Программы

В Solana смарт-контракт называется программой. Программа — это статeless аккаунт, который содержит исполняемый код. Этот код организован в функции, называемые инструкциями. Пользователи взаимодействуют с программой, отправляя транзакцию, содержащую одну или несколько инструкций. Одна транзакция может включать инструкции из нескольких программ.

Когда программа развёртывается, Solana использует LLVM для компиляции её в исполняемый и компонуемый формат (ELF). ELF-файл содержит бинарный код программы в формате байткода Solana (sBPF) и сохраняется в сети на исполняемом аккаунте.

sBPF — это собственная версия байткода eBPF для Solana.

Написание программ

Большинство программ пишутся на Rust с использованием двух основных подходов к разработке:

  • Anchor: Anchor — это фреймворк, созданный для быстрой и простой разработки на Solana. Он использует макросы Rust для сокращения шаблонного кода, что делает его отличным выбором для новичков.
  • Чистый Rust: Написание программ на Rust без использования фреймворков. Такой подход даёт больше гибкости, но требует большего опыта и усложняет разработку.

Обновление программ

Чтобы изменить существующую программу, аккаунт должен быть назначен управляющим обновлением. (Обычно это тот же аккаунт, который изначально развёртывал программу.) Если права управляющего обновлением отозваны и установлены в None, программа больше не может быть обновлена.

Верификация программ

Solana поддерживает проверяемые сборки, которые позволяют пользователям убедиться, что код программы в сети соответствует её открытому исходному коду. Фреймворк Anchor предоставляет встроенную поддержку для создания проверяемых сборок.

Чтобы проверить, верифицирована ли существующая программа, найдите её идентификатор программы на Solana Explorer. Также вы можете воспользоваться CLI-инструментом Ellipsis Labs Solana Verifiable Build CLI, чтобы самостоятельно верифицировать программы в блокчейне.

Встроенные программы

System Program

System Program — единственный аккаунт, который может создавать новые аккаунты. По умолчанию все новые аккаунты принадлежат System Program, хотя при создании многим из них назначается новый владелец. System Program выполняет следующие ключевые функции:

ФункцияОписание
Создание нового аккаунтаТолько System Program может создавать новые аккаунты.
Выделение пространстваУстанавливает объём байтов для поля данных каждого аккаунта.
Назначение владельца программыПосле создания аккаунта System Program может переназначить владельца программы на другой program account. Так кастомные программы получают владение новыми аккаунтами, созданными System Program.
Перевод SOLПереводит лампорты (SOL) с аккаунтов System Program на другие аккаунты.

Адрес System Program: 11111111111111111111111111111111.

Загрузочные программы

Каждая программа принадлежит другой — своему загрузчику (loader). Загрузчики используются для деплоя, повторного деплоя, обновления или закрытия программ. Также они применяются для финализации программы и передачи полномочий.

Загрузочные программы иногда называют «BPF Loaders».

В настоящее время существует пять загрузочных программ, приведённых в таблице ниже.

ЗагрузчикProgram IDПримечанияСсылка на инструкции
nativeNativeLoader1111111111111111111111111111111Является владельцем остальных четырёх загрузчиков
v1BPFLoader1111111111111111111111111111111111Инструкции управления отключены, но программы продолжают выполняться
v2BPFLoader2111111111111111111111111111111111Инструкции управления отключены, но программы продолжают выполнятьсяИнструкции
v3BPFLoaderUpgradeab1e11111111111111111111111Программы можно обновлять после деплоя. Исполняемый файл программы хранится в отдельном аккаунте program dataИнструкции
v4LoaderV411111111111111111111111111111111111В разработке (не выпущен)Инструкции

Программы, развернутые с помощью loader-v3 или loader-v4, могут быть изменяемыми после развертывания, если это разрешено их полномочиями на обновление.

При развертывании новой программы по умолчанию будет использоваться последняя версия загрузчика.

Предкомпилированные программы

В дополнение к программам-загрузчикам Solana предоставляет следующие предкомпилированные программы.

Проверка подписи ed25519

Программа ed25519 используется для проверки одной или нескольких подписей ed25519.

ПрограммаID программыОписаниеИнструкции
Программа Ed25519Ed25519SigVerify111111111111111111111111111Проверяет подписи ed25519. Если какая-либо подпись не проходит проверку, возвращается ошибка.Инструкции

Программа ed25519 обрабатывает инструкцию. Первый u8 инструкции содержит количество подписей, которые необходимо проверить, за которым следует один байт для выравнивания. После этого для каждой подписи сериализуется следующая структура.

Ed25519SignatureOffsets
struct Ed25519SignatureOffsets {
signature_offset: u16, // offset to ed25519 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to public key of 32 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}
Signature verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
instruction_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

Программа secp256k1 используется для проверки операций восстановления открытого ключа secp256k1.

ПрограммаID программыОписаниеИнструкции
Программа Secp256k1KeccakSecp256k11111111111111111111111111111Проверяет операции восстановления открытого ключа secp256k1 (ecrecover).Инструкции

Программа secp256k1 обрабатывает инструкцию. Первый байт инструкции содержит количество открытых ключей, которые необходимо проверить. После этого для каждого открытого ключа создаётся следующая структура, затем сериализуется и добавляется в instruction data.

Secp256k1SignatureOffsets
struct Secp256k1SignatureOffsets {
secp_signature_offset: u16, // offset to [signature,recovery_id] of 64+1 bytes
secp_signature_instruction_index: u8, // instruction index to find signature
secp_pubkey_offset: u16, // offset to ethereum_address pubkey of 20 bytes
secp_pubkey_instruction_index: u8, // instruction index to find pubkey
secp_message_data_offset: u16, // offset to start of message data
secp_message_data_size: u16, // size of message data
secp_message_instruction_index: u8, // instruction index to find message data
}
Recovery verification pseudocode
process_instruction() {
for i in 0..count {
// i'th index values referenced:
instructions = &transaction.message().instructions
signature = 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
}

Это позволяет пользователю указывать любые instruction data в транзакции для подписи и данных сообщения. Указав специальную системную переменную инструкций, можно также получать данные непосредственно из самой транзакции.

Стоимость транзакции рассчитывается как количество подписей для проверки, умноженное на коэффициент стоимости проверки подписи.

Программа secp256r1 используется для проверки до 8 подписей secp256r1.

ПрограммаID программыОписаниеИнструкции
Программа Secp256r1Secp256r1SigVerify1111111111111111111111111Проверяет до 8 подписей secp256r1. Принимает подпись, открытый ключ и сообщение. Возвращает ошибку при любой ошибке.Инструкции

Программа secp256r1 обрабатывает инструкцию. Первый u8 инструкции — это количество подписей, которые необходимо проверить, за которым следует один байт для выравнивания. Затем для каждой подписи создаётся следующая структура, сериализуется и добавляется в instruction data.

Secp256r1SignatureOffsets
struct Secp256r1SignatureOffsets {
signature_offset: u16, // offset to compact secp256r1 signature of 64 bytes
signature_instruction_index: u16, // instruction index to find signature
public_key_offset: u16, // offset to compressed public key of 33 bytes
public_key_instruction_index: u16, // instruction index to find public key
message_data_offset: u16, // offset to start of message data
message_data_size: u16, // size of message data
message_instruction_index: u16, // index of instruction data to get message data
}

Для всех подписей применяется требование низких значений S, чтобы избежать случайной изменяемости подписи.

Signature verification psuedocode
process_instruction() {
if data.len() < SIGNATURE_OFFSETS_START {
return Error
}
num_signatures = data[0] as usize
if num_signatures == 0 || num_signatures > 8 {
return Error
}
expected_data_size = num_signatures * SIGNATURE_OFFSETS_SERIALIZED_SIZE + SIGNATURE_OFFSETS_START
if 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
}

Основные программы

Программы в списке ниже обеспечивают основную функциональность сети.

ПрограммаID программыОписаниеИнструкции
System11111111111111111111111111111111Создание новых аккаунтов, выделение данных аккаунта, назначение аккаунтов программам-владельцам, перевод лампортов с аккаунтов, принадлежащих системной программе, и оплата комиссий за транзакцииSystemInstruction
VoteVote111111111111111111111111111111111111111Создание и управление аккаунтами, отслеживающими состояние голосования валидаторов и вознагражденияVoteInstruction
StakeStake11111111111111111111111111111111111111Создание и управление аккаунтами, представляющими стейк и вознаграждения за делегирование валидаторамStakeInstruction
ConfigConfig1111111111111111111111111111111111111Добавление конфигурационных данных в цепочку, а также списка открытых ключей, которым разрешено их изменять. В отличие от других программ, программа Config не определяет отдельных инструкций. В ней есть только одна неявная инструкция: "store". Её instruction data — это набор ключей, ограничивающих доступ к аккаунту и данным внутри негоConfigInstruction
Compute BudgetComputeBudget111111111111111111111111111111Установка лимитов и цен на вычислительные ресурсы для транзакций, позволяя пользователям управлять вычислительными ресурсами и приоритетными комиссиямиComputeBudgetInstruction
Address Lookup TableAddressLookupTab1e1111111111111111111111111Управление таблицами поиска адресов, которые позволяют транзакциям ссылаться на большее количество аккаунтов, чем обычно помещается в списке аккаунтов транзакцииProgramInstruction
ZK ElGamal ProofZkE1Gama1Proof11111111111111111111111111111Предоставляет проверку доказательств с нулевым разглашением для данных, зашифрованных с помощью ElGamal

Is this page helpful?

Управляется

© 2026 Фонд Solana.
Все права защищены.
Подключиться