Программы
На 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, называемую "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 обрабатывает инструкцию, которая принимает в качестве первого байта количество следующих структур, сериализованных в данных инструкции:
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. Принимает подпись, публичный ключ и сообщение. Возвращает ошибку при неудаче. | Instructions |
Программа 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 программы | Описание | Инструкции |
---|---|---|---|
Системная программа | 11111111111111111111111111111111 | Создание новых аккаунтов, выделение данных аккаунта, назначение аккаунтов владеющим программам, перевод lamport с аккаунтов, принадлежащих системной программе, и оплата комиссий за транзакции. | SystemInstruction |
Программа голосования | Vote111111111111111111111111111111111111111 | Создание и управление аккаунтами, которые отслеживают состояние голосования validator и вознаграждения. | VoteInstruction |
Программа стейкинга | Stake11111111111111111111111111111111111111 | Создание и управление аккаунтами, представляющими стейк и вознаграждения за делегирование validator. | StakeInstruction |
Программа конфигурации | Config1111111111111111111111111111111111111 | Добавление данных конфигурации в цепочку, за которыми следует список публичных ключей, которым разрешено их изменять. В отличие от других программ, программа конфигурации не определяет отдельных инструкций. У нее есть только одна неявная инструкция: "store". Ее instruction data - это набор ключей, которые контролируют доступ к аккаунту и данным в нем. | ConfigInstruction |
Программа бюджета вычислений | ComputeBudget111111111111111111111111111111 | Установка лимитов вычислительных единиц и цен для транзакций, позволяющая пользователям контролировать вычислительные ресурсы и приоритетные комиссии. | ComputeBudgetInstruction |
Программа таблиц поиска адресов | AddressLookupTab1e1111111111111111111111111 | Управление таблицами поиска адресов, которые позволяют транзакциям ссылаться на большее количество аккаунтов, чем могло бы поместиться в список аккаунтов транзакции. | ProgramInstruction |
Программа ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | Обеспечивает верификацию доказательств с нулевым разглашением для данных, зашифрованных по методу ElGamal. | — |
Is this page helpful?