Программы

На 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 программыПримечанияСсылка на инструкции
nativeNativeLoader1111111111111111111111111111111Управляет остальными четырьмя загрузчиками
v1BPFLoader1111111111111111111111111111111111Инструкции управления отключены, но программы всё ещё выполняются
v2BPFLoader2111111111111111111111111111111111Инструкции управления отключены, но программы всё ещё выполняютсяИнструкции
v3BPFLoaderUpgradeab1e11111111111111111111111Находится в процессе вывода из эксплуатацииИнструкции
v4LoaderV411111111111111111111111111111111111Ожидается, что v4 станет стандартным загрузчикомИнструкции

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

  • Развертывание новой программы или буфера
  • Закрытие программы или буфера
  • Повторное развертывание / обновление существующей программы
  • Передача полномочий над программой
  • Завершение программы

Loader-v3 и loader-v4 поддерживают модификации программ после их первоначального развертывания. Разрешение на это регулируется полномочиями программы, так как владение аккаунтом каждой программы находится у загрузчика.

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

Программа 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
}

Псевдокод проверки подписи:

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

Программа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
}

Псевдокод проверки восстановления:

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
}

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

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

Программа Secp256r1

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

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

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
}

Псевдокод проверки подписи:

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
}

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

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

Генезис кластера Solana включает список специальных программ, которые предоставляют основные функции для сети. Исторически они назывались "родными" программами и распространялись вместе с кодом валидатора.

ПрограммаID программыОписаниеИнструкции
System Program11111111111111111111111111111111Создает новые аккаунты, выделяет данные аккаунта, назначает аккаунты программам-владельцам, переводит lamports с аккаунтов, принадлежащих System Program, и оплачивает комиссии за транзакции.SystemInstruction
Vote ProgramVote111111111111111111111111111111111111111Создает и управляет аккаунтами, которые отслеживают состояние голосования валидаторов и вознаграждения.VoteInstruction
Stake ProgramStake11111111111111111111111111111111111111Создает и управляет аккаунтами, представляющими стейкинг и вознаграждения за делегирование валидаторам.StakeInstruction
Config ProgramConfig1111111111111111111111111111111111111Добавляет данные конфигурации в цепочку, за которыми следует список открытых ключей, которым разрешено их изменять. В отличие от других программ, программа Config не определяет никаких отдельных инструкций. У нее есть только одна неявная инструкция: "store". Данные инструкции - это набор ключей, которые ограничивают доступ к аккаунту, и данные для хранения в нем.ConfigInstruction
Compute Budget ProgramComputeBudget111111111111111111111111111111Устанавливает лимиты вычислительных единиц и цены для транзакций, позволяя пользователям контролировать вычислительные ресурсы и комиссии за приоритет.ComputeBudgetInstruction
Address Lookup Table ProgramAddressLookupTab1e1111111111111111111111111Управляет таблицами поиска адресов, которые позволяют транзакциям ссылаться на большее количество аккаунтов, чем может поместиться в списке аккаунтов транзакции.ProgramInstruction
ZK ElGamal Proof ProgramZkE1Gama1Proof11111111111111111111111111111Обеспечивает проверку доказательств с нулевым разглашением для данных, зашифрованных с использованием ElGamal.

Is this page helpful?