Програми

У Solana смарт-контракт називається програмою. Програма — це stateless акаунт, що містить виконуваний код. Цей код організовано у функції, які називаються інструкціями. Користувачі взаємодіють з програмою, надсилаючи транзакцію, що містить одну або кілька інструкцій. Транзакція може включати інструкції з кількох програм.

Коли програму розгортають, Solana використовує LLVM для компіляції її у виконуваний формат з можливістю компонування (ELF). ELF-файл містить бінарний код програми у форматі Solana Bytecode Format (sBPF) і зберігається он-чейн у виконуваному акаунті.

sBPF — це кастомна версія байткоду eBPF від Solana.

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

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

  • Anchor: Anchor — це фреймворк, призначений для швидкої та легкої розробки на Solana. Він використовує макроси Rust для зменшення шаблонного коду — що робить його чудовим для початківців.
  • Нативний Rust: Написання програм на Rust без використання будь-яких фреймворків. Цей підхід пропонує більше гнучкості, але супроводжується підвищеною складністю.

Оновлення програм

Щоб модифікувати існуючу програму, акаунт має бути призначений як upgrade authority. (Зазвичай той самий акаунт, який спочатку розгорнув програму.) Якщо upgrade authority відкликано і встановлено в None, програму більше не можна оновити.

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

Solana підтримує верифіковані білди, які дозволяють користувачам перевірити, чи відповідає он-чейн код програми її публічному вихідному коду. Фреймворк Anchor надає вбудовану підтримку для створення верифікованого білду.

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

Вбудовані програми

System Program

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

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

Адреса системної програми — 11111111111111111111111111111111.

Програми-завантажувачі

Кожна програма належить іншій — її завантажувачу. Завантажувачі використовуються для розгортання, повторного розгортання, оновлення або закриття програм. Вони також використовуються для фіналізації програми та передачі повноважень програми.

Програми-завантажувачі іноді називають «BPF Loaders».

Наразі існує п'ять програм-завантажувачів, як показано в таблиці нижче.

ЗавантажувачІдентифікатор програмиПриміткиПосилання на інструкції
nativeNativeLoader1111111111111111111111111111111Володіє іншими чотирма завантажувачами
v1BPFLoader1111111111111111111111111111111111Інструкції керування вимкнено, але програми все ще виконуються
v2BPFLoader2111111111111111111111111111111111Інструкції керування вимкнено, але програми все ще виконуютьсяІнструкції
v3BPFLoaderUpgradeab1e11111111111111111111111Програми можна оновлювати після розгортання. Виконуваний код програми зберігається в окремому program data accountІнструкції
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 обробляє інструкцію. Перший байт інструкції містить кількість відкритих ключів, які потрібно перевірити. Після цього, наступна структура створюється один раз для кожного відкритого ключа, потім серіалізується та додається до даних інструкції.

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
}

Це дозволяє користувачеві вказати будь-які дані інструкції в транзакції для даних підпису та повідомлення. Вказавши спеціальний sysvar інструкцій, можна також отримувати дані з самої транзакції.

Вартість транзакції буде враховувати кількість підписів для перевірки, помножену на множник вартості перевірки підпису.

Програма secp256r1 використовується для перевірки до 8 підписів 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
}

Низькі значення 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Створення та управління обліковими записами, які відстежують стан голосування validator та винагородиVoteInstruction
StakeStake11111111111111111111111111111111111111Створення та управління обліковими записами, що представляють ставку та винагороди за делегування validatorStakeInstruction
ConfigConfig1111111111111111111111111111111111111Додавання конфігураційних даних до ланцюга, за якими слідує список відкритих ключів, яким дозволено їх змінювати. На відміну від інших програм, програма Config не визначає окремих інструкцій. Вона має лише одну неявну інструкцію: "store". Її дані інструкції — це набір ключів, які контролюють доступ до облікового запису та даних, що зберігаються в ньомуConfigInstruction
Compute BudgetComputeBudget111111111111111111111111111111Встановлення лімітів обчислювальних одиниць та цін для транзакцій, що дозволяє користувачам контролювати обчислювальні ресурси та комісії за пріоритетComputeBudgetInstruction
Address Lookup TableAddressLookupTab1e1111111111111111111111111Управління таблицями пошуку адрес, які дозволяють транзакціям посилатися на більше облікових записів, ніж могло б вміститися у списку облікових записів транзакціїProgramInstruction
ZK ElGamal ProofZkE1Gama1Proof11111111111111111111111111111Забезпечує перевірку доказів з нульовим розголошенням для даних, зашифрованих за допомогою ElGamal

Is this page helpful?

Керується

© 2026 Фонд Solana.
Всі права захищені.
Залишайтеся на зв'язку