Програми

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

Ключові моменти

  • Програми — це облікові записи, що містять виконуваний код, організований у функції, які називаються інструкціями.
  • Хоча програми є безстановими, вони можуть включати інструкції, які створюють та оновлюють інші облікові записи для зберігання даних.
  • Орган оновлення може оновлювати програми. Після видалення цього органу програма стає незмінною.
  • Користувачі можуть перевірити, чи дані облікового запису програми в мережі відповідають її публічному вихідному коду через верифіковані збірки.

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

Програми Solana переважно пишуться мовою програмування Rust, з двома поширеними підходами до розробки:

  • Anchor: Фреймворк, розроблений для розробки програм Solana. Він забезпечує швидший і простіший спосіб написання програм, використовуючи макроси Rust для зменшення шаблонного коду. Для початківців рекомендується починати з фреймворку Anchor.

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

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

Щоб дізнатися більше про розгортання та оновлення програм, перегляньте сторінку розгортання програм.

Програми можуть бути безпосередньо модифіковані обліковим записом, призначеним як "орган оновлення", яким зазвичай є обліковий запис, що спочатку розгорнув програму. Якщо орган оновлення відкликано і встановлено як null, програма стає незмінною і більше не може бути оновлена.

Програми, що підлягають верифікації

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

Спільнота розробників 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 програмиПриміткиПосилання на інструкції
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 обробляє інструкцію, яка приймає як перший байт кількість наступних структур, серіалізованих у даних інструкції:

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 включає список спеціальних програм, які забезпечують основні функціональні можливості мережі. Історично їх називали "нативними" програмами, і вони розповсюджувалися разом із кодом validator.

ПрограмаID програмиОписІнструкції
Системна програма11111111111111111111111111111111Створення нових облікових записів, виділення даних облікового запису, призначення облікових записів програмам-власникам, переказ lamport з облікових записів, що належать Системній програмі, та оплата комісій за транзакції.SystemInstruction
Програма голосуванняVote111111111111111111111111111111111111111Створення та управління обліковими записами, які відстежують стан голосування validator та винагороди.VoteInstruction
Програма стейкінгуStake11111111111111111111111111111111111111Створення та управління обліковими записами, що представляють стейк та винагороди за делегування validator.StakeInstruction
Програма конфігураціїConfig1111111111111111111111111111111111111Додавання даних конфігурації до ланцюга, за якими слідує список публічних ключів, яким дозволено їх змінювати. На відміну від інших програм, програма Config не визначає окремих інструкцій. Вона має лише одну неявну інструкцію: "store". Її дані інструкції — це набір ключів, які контролюють доступ до облікового запису, та дані для зберігання в ньому.ConfigInstruction
Програма обчислювального бюджетуComputeBudget111111111111111111111111111111Встановлення лімітів обчислювальних одиниць та цін для транзакцій, що дозволяє користувачам контролювати обчислювальні ресурси та комісії за пріоритет.ComputeBudgetInstruction
Програма таблиць пошуку адресAddressLookupTab1e1111111111111111111111111Управління таблицями пошуку адрес, які дозволяють транзакціям посилатися на більше облікових записів, ніж могло б поміститися у списку облікових записів транзакції.ProgramInstruction
Програма ZK ElGamal ProofZkE1Gama1Proof11111111111111111111111111111Забезпечує перевірку доказів з нульовим розголошенням для даних, зашифрованих за допомогою ElGamal.

Is this page helpful?