Програми
У Solana смарт-контракт називається програмою. Програма — це безстановий обліковий запис, який містить виконуваний код. Цей код організований у функції, які називаються інструкціями. Користувачі взаємодіють з програмою, надсилаючи транзакцію, що містить одну або кілька інструкцій. Транзакція може включати інструкції з кількох програм.
Коли програма розгортається, Solana використовує LLVM для її компіляції у виконуваний та компонований формат (ELF). ELF-файл містить бінарний код програми у форматі байткоду Solana (sBPF) і зберігається в мережі у виконуваному обліковому записі.
sBPF — це власна версія Solana байткоду eBPF.
Написання програм
Більшість програм написані мовою Rust, з двома поширеними підходами до розробки:
- Anchor: Anchor — це фреймворк, розроблений для швидкої та легкої розробки на Solana. Він використовує макроси Rust для зменшення шаблонного коду — що робить його чудовим для початківців.
- Нативний Rust: Написання програм на Rust без використання будь-яких фреймворків. Цей підхід пропонує більшу гнучкість, але має підвищену складність.
Оновлення програм
Щоб модифікувати наявну програму, обліковий запис повинен бути призначений як орган оновлення. (Зазвичай це той самий обліковий запис, який спочатку розгорнув програму.) Якщо орган оновлення відкликано і встановлено як null, програму більше не можна оновлювати.
Перевірка програм
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) з облікових записів системи на інші облікові записи. |
Адреса System Program — 11111111111111111111111111111111.
Програми завантажувачі
Кожна програма належить іншій — своєму завантажувачу. Завантажувачі використовуються для розгортання, повторного розгортання, оновлення або закриття програм. Вони також використовуються для завершення програми та передачі повноважень програми.
Наразі існує п'ять програм завантажувачів, як показано в таблиці нижче.
| Завантажувач | ID програми | Примітки | Посилання на інструкції |
|---|---|---|---|
| native | NativeLoader1111111111111111111111111111111 | Володіє іншими чотирма завантажувачами | — |
| v1 | BPFLoader1111111111111111111111111111111111 | Інструкції керування вимкнено, але програми все ще виконуються | — |
| v2 | BPFLoader2111111111111111111111111111111111 | Інструкції керування вимкнено, але програми все ще виконуються | Інструкції |
| v3 | BPFLoaderUpgradeab1e11111111111111111111111 | Програми можна оновлювати після розгортання. Виконуваний файл програми зберігається в окремому обліковому записі даних програми | Інструкції |
| v4 | LoaderV411111111111111111111111111111111111 | У розробці (не випущено) | Інструкції |
Програми, розгорнуті за допомогою loader-v3 або loader-v4, можуть бути змінені після розгортання, що визначається їхнім органом оновлення.
Коли розгортається нова програма, за замовчуванням буде використовуватися найновіша версія завантажувача.
Попередньо скомпільовані програми
Окрім програм-завантажувачів, Solana надає такі попередньо скомпільовані програми.
Перевірка підпису ed25519
Програма ed25519 використовується для перевірки одного або кількох підписів 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
Програма secp256k1 використовується для перевірки операцій відновлення відкритого ключа 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 використовується для перевірки до 8 підписів 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}
Низькі значення S застосовуються для всіх підписів, щоб уникнути випадкової пластичності підпису.
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}
Основні програми
Програми у списку нижче забезпечують основну функціональність мережі.
| Програма | ID програми | Опис | Інструкції |
|---|---|---|---|
| System | 11111111111111111111111111111111 | Створення нових облікових записів, розподіл даних облікового запису, призначення облікових записів програмам-власникам, переказ лампортів з облікових записів, що належать системній програмі, та оплата комісій за транзакції | SystemInstruction |
| Vote | Vote111111111111111111111111111111111111111 | Створення та управління обліковими записами, які відстежують стан голосування validator та винагороди | VoteInstruction |
| Stake | Stake11111111111111111111111111111111111111 | Створення та управління обліковими записами, що представляють ставку та винагороди за делегування validator | StakeInstruction |
| Config | Config1111111111111111111111111111111111111 | Додавання конфігураційних даних до ланцюга, за якими слідує список відкритих ключів, яким дозволено їх змінювати. На відміну від інших програм, програма Config не визначає окремих інструкцій. Вона має лише одну неявну інструкцію: "store". Її дані інструкції — це набір ключів, які контролюють доступ до облікового запису та даних, що зберігаються в ньому | ConfigInstruction |
| Compute Budget | ComputeBudget111111111111111111111111111111 | Встановлення лімітів обчислювальних одиниць та цін для транзакцій, що дозволяє користувачам контролювати обчислювальні ресурси та комісії за пріоритет | ComputeBudgetInstruction |
| Address Lookup Table | AddressLookupTab1e1111111111111111111111111 | Управління таблицями пошуку адрес, які дозволяють транзакціям посилатися на більше облікових записів, ніж могло б вміститися у списку облікових записів транзакції | ProgramInstruction |
| ZK ElGamal Proof | ZkE1Gama1Proof11111111111111111111111111111 | Забезпечує перевірку доказів з нульовим розголошенням для даних, зашифрованих за допомогою ElGamal | — |
Is this page helpful?