Программы
На Solana "смарт-контракты" называются программами. Программы развёртываются в сети на аккаунтах, которые содержат скомпилированный исполняемый бинарный файл программы. Пользователи взаимодействуют с программами, отправляя транзакции, содержащие инструкции, которые указывают программе, что нужно сделать.
Основные моменты
- Программы — это аккаунты, содержащие исполняемый код, организованный в функции, называемые инструкциями.
- Хотя программы являются бессостоячными, они могут включать инструкции, которые создают и обновляют другие аккаунты для хранения данных.
- Авторитет обновления может обновлять программы. После удаления этого авторитета программа становится неизменяемой.
- Пользователи могут проверить, что данные аккаунта программы в сети соответствуют её публичному исходному коду, с помощью проверяемых сборок.
Написание программ для Solana
Программы для Solana в основном пишутся на языке программирования Rust, с использованием двух распространённых подходов к разработке:
-
Anchor: Фреймворк, разработанный для создания программ на Solana. Он предоставляет более быстрый и простой способ написания программ, используя макросы Rust для сокращения шаблонного кода. Для начинающих рекомендуется начинать с фреймворка Anchor.
-
Чистый Rust: Этот подход предполагает написание программ на Solana на Rust без использования фреймворков. Он предоставляет больше гибкости, но сопровождается увеличением сложности.
Обновление программ на Solana
Чтобы узнать больше о развертывании и обновлении программ, посетите страницу развертывание программ.
Программы могут быть
непосредственно изменены
аккаунтом, назначенным как "авторитет обновления", который обычно является
аккаунтом, изначально развернувшим программу. Если
авторитет обновления
отзывается и устанавливается в None
, программа становится неизменяемой и
больше не может быть обновлена.
Проверяемые программы
Проверяемые сборки позволяют любому пользователю убедиться, что код программы в блокчейне соответствует её публичному исходному коду, что делает возможным выявление расхождений между исходным кодом и развернутой версией.
Сообщество разработчиков Solana представило инструменты для поддержки проверяемых сборок, позволяя как разработчикам, так и пользователям убедиться, что программы в блокчейне точно отражают их публично доступный исходный код.
-
Поиск проверенных программ: Чтобы быстро проверить наличие проверенных программ, пользователи могут искать адрес программы на Solana Explorer. Пример проверенной программы можно посмотреть здесь.
-
Инструменты для проверки: Solana Verifiable Build CLI от Ellipsis Labs позволяет пользователям самостоятельно проверять программы в блокчейне на соответствие опубликованному исходному коду.
-
Поддержка проверяемых сборок в Anchor: Anchor предоставляет встроенную поддержку проверяемых сборок. Подробности можно найти в документации Anchor.
Фильтр Berkeley Packet Filter (BPF)
Solana использует LLVM (Low Level Virtual Machine) для компиляции программ в файлы формата ELF (Executable and Linkable Format). Эти файлы содержат пользовательскую версию байт-кода eBPF, называемую "Solana Bytecode Format" (sBPF). ELF-файл содержит бинарный код программы и хранится в блокчейне в исполняемом аккаунте при развертывании программы.
Встроенные программы
Программы-загрузчики
Каждая программа принадлежит другой программе, которая является её загрузчиком. В настоящее время существует пять программ-загрузчиков:
Загрузчик | ID программы | Примечания | Ссылка на инструкции |
---|---|---|---|
native | NativeLoader1111111111111111111111111111111 | Управляет остальными четырьмя загрузчиками | — |
v1 | BPFLoader1111111111111111111111111111111111 | Инструкции управления отключены, но программы всё ещё выполняются | — |
v2 | BPFLoader2111111111111111111111111111111111 | Инструкции управления отключены, но программы всё ещё выполняются | Инструкции |
v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Находится в процессе вывода из эксплуатации | Инструкции |
v4 | LoaderV411111111111111111111111111111111111 | Ожидается, что v4 станет стандартным загрузчиком | Инструкции |
Эти загрузчики необходимы для создания и управления пользовательскими программами:
- Развертывание новой программы или буфера
- Закрытие программы или буфера
- Повторное развертывание / обновление существующей программы
- Передача полномочий над программой
- Завершение программы
Loader-v3 и loader-v4 поддерживают модификации программ после их первоначального развертывания. Разрешение на это регулируется полномочиями программы, так как владение аккаунтом каждой программы находится у загрузчика.
Предварительно скомпилированные программы
Программа Ed25519
Программа | ID программы | Описание | Инструкции |
---|---|---|---|
Программа Ed25519 | Ed25519SigVerify111111111111111111111111111 | Проверяет подписи ed25519. Если любая подпись не проходит проверку, возвращается ошибка. | Инструкции |
Программа ed25519 обрабатывает инструкцию. Первый u8
- это количество подписей
для проверки, за которым следует однобайтовое выравнивание. После этого
сериализуется следующая структура, по одной для каждой проверяемой подписи.
struct Ed25519SignatureOffsets {signature_offset: u16, // offset to ed25519 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to public key of 32 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
Псевдокод проверки подписи:
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionsinstruction_index = ed25519_signature_instruction_index != u16::MAX ? ed25519_signature_instruction_index : current_instruction;signature = instructions[instruction_index].data[ed25519_signature_offset..ed25519_signature_offset + 64]instruction_index = ed25519_pubkey_instruction_index != u16::MAX ? ed25519_pubkey_instruction_index : current_instruction;pubkey = instructions[instruction_index].data[ed25519_pubkey_offset..ed25519_pubkey_offset + 32]instruction_index = ed25519_message_instruction_index != u16::MAX ? ed25519_message_instruction_index : current_instruction;message = instructions[instruction_index].data[ed25519_message_data_offset..ed25519_message_data_offset + ed25519_message_data_size]if pubkey.verify(signature, message) != Success {return Error}}return Success}
Программа Secp256k1
Программа | ID программы | Описание | Инструкции |
---|---|---|---|
Программа Secp256k1 | KeccakSecp256k11111111111111111111111111111 | Проверяет операции восстановления открытого ключа secp256k1 (ecrecover). | Инструкции |
Программа secp256k1 обрабатывает инструкцию, которая принимает в качестве первого байта количество следующих структур, сериализованных в instruction data:
struct Secp256k1SignatureOffsets {secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytessecp_signature_instruction_index: u8, // instruction index to find signaturesecp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytessecp_pubkey_instruction_index: u8, // instruction index to find pubkeysecp_message_data_offset: u16, // offset to start of message datasecp_message_data_size: u16, // size of message datasecp_message_instruction_index: u8, // instruction index to find message data}
Псевдокод проверки восстановления:
process_instruction() {for i in 0..count {// i'th index values referenced:instructions = &transaction.message().instructionssignature = instructions[secp_signature_instruction_index].data[secp_signature_offset..secp_signature_offset + 64]recovery_id = instructions[secp_signature_instruction_index].data[secp_signature_offset + 64]ref_eth_pubkey = instructions[secp_pubkey_instruction_index].data[secp_pubkey_offset..secp_pubkey_offset + 20]message_hash = keccak256(instructions[secp_message_instruction_index].data[secp_message_data_offset..secp_message_data_offset + secp_message_data_size])pubkey = ecrecover(signature, recovery_id, message_hash)eth_pubkey = keccak256(pubkey[1..])[12..]if eth_pubkey != ref_eth_pubkey {return Error}}return Success}
Это позволяет пользователю указывать любые данные инструкции в транзакции для подписи и данных сообщения. Указав специальный sysvar инструкций, можно также получить данные из самой транзакции.
Стоимость транзакции будет рассчитываться как количество подписей для проверки, умноженное на множитель стоимости проверки подписи.
Программа Secp256r1
Программа | ID программы | Описание | Инструкции |
---|---|---|---|
Программа Secp256r1 | Secp256r1SigVerify1111111111111111111111111 | Проверяет до 8 подписей secp256r1. Принимает подпись, открытый ключ и сообщение. Возвращает ошибку, если проверка любой из них не удалась. | Инструкции |
Программа secp256r1 обрабатывает инструкцию. Первый u8
- это количество
подписей для проверки, за которым следует один байт заполнения. После этого
сериализуется следующая структура, по одной для каждой подписи для проверки:
struct Secp256r1SignatureOffsets {signature_offset: u16, // offset to compact secp256r1 signature of 64 bytessignature_instruction_index: u16, // instruction index to find signaturepublic_key_offset: u16, // offset to compressed public key of 33 bytespublic_key_instruction_index: u16, // instruction index to find public keymessage_data_offset: u16, // offset to start of message datamessage_data_size: u16, // size of message datamessage_instruction_index: u16, // index of instruction data to get message data}
Псевдокод проверки подписи:
process_instruction() {if data.len() < SIGNATURE_OFFSETS_START {return Error}num_signatures = data[0] as usizeif num_signatures == 0 || num_signatures > 8 {return Error}expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_STARTif data.len() < expected_data_size {return Error}for i in 0..num_signatures {offsets = parse_signature_offsets(data, i)signature = get_data_slice(data, instruction_datas, offsets.signature_instruction_index, offsets.signature_offset, SIGNATURE_SERIALIZED_SIZE)if s > half_curve_order {return Error}pubkey = get_data_slice(data, instruction_datas, offsets.public_key_instruction_index, offsets.public_key_offset, COMPRESSED_PUBKEY_SERIALIZED_SIZE)message = get_data_slice(data, instruction_datas, offsets.message_instruction_index, offsets.message_data_offset, offsets.message_data_size)if !verify_signature(signature, pubkey, message) {return Error}}return Success}
Примечание: Низкие значения S применяются ко всем подписям, чтобы избежать случайной изменяемости подписи.
Основные программы
Генезис кластера Solana включает список специальных программ, которые предоставляют основные функции для сети. Исторически они назывались "родными" программами и распространялись вместе с кодом валидатора.
Программа | ID программы | Описание | Инструкции |
---|---|---|---|
System Program | 11111111111111111111111111111111 | Создает новые аккаунты, выделяет данные аккаунта, назначает аккаунты программам-владельцам, переводит lamports с аккаунтов, принадлежащих System Program, и оплачивает комиссии за транзакции. | SystemInstruction |
Vote Program | Vote111111111111111111111111111111111111111 | Создает и управляет аккаунтами, которые отслеживают состояние голосования валидаторов и вознаграждения. | VoteInstruction |
Stake Program | Stake11111111111111111111111111111111111111 | Создает и управляет аккаунтами, представляющими стейкинг и вознаграждения за делегирование валидаторам. | StakeInstruction |
Config Program | Config1111111111111111111111111111111111111 | Добавляет данные конфигурации в цепочку, за которыми следует список открытых ключей, которым разрешено их изменять. В отличие от других программ, программа Config не определяет никаких отдельных инструкций. У нее есть только одна неявная инструкция: "store". Данные инструкции - это набор ключей, которые ограничивают доступ к аккаунту, и данные для хранения в нем. | ConfigInstruction |
Compute Budget Program | ComputeBudget111111111111111111111111111111 | Устанавливает лимиты вычислительных единиц и цены для транзакций, позволяя пользователям контролировать вычислительные ресурсы и комиссии за приоритет. | ComputeBudgetInstruction |
Address Lookup Table Program | AddressLookupTab1e1111111111111111111111111 | Управляет таблицами поиска адресов, которые позволяют транзакциям ссылаться на большее количество аккаунтов, чем может поместиться в списке аккаунтов транзакции. | ProgramInstruction |
ZK ElGamal Proof Program | ZkE1Gama1Proof11111111111111111111111111111 | Обеспечивает проверку доказательств с нулевым разглашением для данных, зашифрованных с использованием ElGamal. | — |
Is this page helpful?