Программы
На 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?