Означення та роль програми
On-chain код, виконуваний валідаторами
Solana program — це скомпільований байт-код, розміщений у блокчейні та виконуваний валідаторами під час обробки транзакцій. Програма отримує набір акаунтів та інструкцію (instruction), виконує логіку й може змінювати дані в переданих акаунтах. Якщо виконання завершується успішно, зміни фіксуються; якщо ні — всі зміни відкочуються.
Програми пишуться переважно мовою Rust, компілюються у формат BPF (Berkeley Packet Filter) за допомогою інструменту solang або стандартного ланцюжка cargo build-sbf, і розгортаються на кластері через Solana CLI.
Концептуальний приклад мінімальної програми на Rust:
Цей приклад ілюструє структуру — не розгортайте його в production без обробки помилок та перевірок.
Програма реєструє точку входу (entrypoint), отримує десеріалізовані дані інструкції та масив акаунтів, виконує логіку й повертає результат. Усі дані, з якими працює програма, зберігаються не всередині неї, а в окремих акаунтах.
Відмінність від смарт-контрактів інших блокчейнів
У EVM-блокчейнах смарт-контракт містить і код, і власний стан (storage). У Solana програма безстанова — вона не зберігає жодних даних усередині себе. Усі дані живуть у акаунтах, а програма лише читає їх і записує зміни за вказівкою транзакції. Ця архітектура описана детальніше у розділі про модель акаунтів, тут важливо розуміти наслідок: одна програма може обслуговувати тисячі незалежних акаунтів, а міграція стану між програмами зводиться до переміщення даних між акаунтами.
Друга ключова відмінність — виконання. Solana використовує runtime на основі BPF, а не віртуальну машину типу EVM. Це дає швидкість компіляції та виконання, близьку до нативної, але накладає обмеження: програма не може виділяти динамічну пам'ять довільного розміру, викликати зовнішні мережеві запити або використовувати стандартну бібліотеку Rust у повному обсязі.
Життєвий цикл програми
Розгортання (deploy), оновлення, закриття
Розгортання. Програма компілюється у файл формату .so (shared object). Через Solana CLI цей файл завантажується на кластер:
- Генерація ключової пари для програми (якщо ще немає):
solana-keygen new -o program-keypair.json - Розгортання на Devnet:
solana program deploy ./target/deploy/program.so --program-id program-keypair.json --url devnet
Середовище: Solana CLI, Rust 1.75+, кластер Devnet. Передумова: на акаунті розгортання має бути достатньо SOL для оренди простору (rent-exempt мінімум).
Під час розгортання байт-код записується в спеціальний акаунт типу Program Account. Цей акаунт має фіксований розмір, залежний від обсягу скомпільованого коду, і має бути rent-exempt — тобто містити достатньо lamport-ів, щоб не бути видаленим збірником сміття.
Оновлення. Якщо при розгортанні не було передано прапорець --final, акаунт програми зберігає Upgrade Authority — ключ, який має право замінити байт-код. Це дозволяє виправляти помилки та додавати функціональність. Команда оновлення аналогічна розгортанню: той самий solana program deploy з тим самим keypair.
Закриття. Програму можна закрити командою solana program close, якщо ви маєте Upgrade Authority. Лампорт-и, заблоковані в акаунті програми, повертаються на вказаний адресат. Після закриття Program ID стає недійсним — жодна транзакція не зможе викликати цю програму.
Program ID та його значення
Program ID — це публічний ключ ключової пари, з якою було розгорнуто програму. Він обчислюється детерміновано: SHA256("global:program" + приватний ключ). Program ID є незмінним ідентифікатором, на який посилаються транзакції, інші програми (через CPI — Cross-Program Invocation) та клієнтські застосунки.
Практичний наслідок: якщо ви втратите ключову пару програми без збереження .json-файлу, ви не зможете оновити чи закрити програму. Зберігайте keypair програми надійно і окремо від ключів гаманців.
Типи програм у Solana
Системні програми (System Program, Token Program)
Системні програми — це вбудовані програми, які є частиною валідаторного ПО Solana. Вони мають фіксовані Program ID, відомі всій мережі, і не можуть бути оновлені чи закриті.
| Програма | Роль |
|---|---|
| System Program | Створення нових акаунтів, переказ lamport-ів між акаунтами, призначення адресата для закриття акаунтів |
| Token Program | Створення та управління SPL-токенами: монетами (fungible tokens) та NFT (non-fungible tokens) |
| Associated Token Program | Детерміноване створення токен-акаунтів за формулою, що залежить від адреси власника та Token Program |
| Compute Budget Program | Встановлення лімітів compute units та пріоритетних комісій у транзакції |
Кожна транзакція в Solana неявно включає System Program, якщо хоча б один інструкція потребує її функцій. Вам не потрібно явно передавати її Program ID у більшості випадків — runtime додає її автоматично.
Користувацькі програми (custom programs)
Користувацькі програми — це код, написаний розробниками для реалізації конкретної бізнес-логіки: DeFi-протоколи, маркетплейси, ігри, DAO-інструменти. Вони розгортаються на кластері і отримують власний Program ID.
Для написання користувацьких програм у екосистемі Solana сформувалися два основні підходи:
- Ручне написання на Rust з використанням
solana-programSDK — дає максимальний контроль, але вимагає ручної обробки серіалізації, перевірки прав доступу та управління акаунтами. - Фреймворк Anchor — абстракція поверх Rust SDK, яка автоматизує перевірки акаунтів, серіалізацію та генерацію клієнтського коду. Для початківців це рекомендований шлях.
Вибір між підходами залежить від досвіду та складності завдання. Для навчальних цілей та перших прототипів Anchor значно знижує поріг входу.
Як програма взаємодіє з акаунтами
Читання та запис даних через instructions
Програма не звертається до акаунтів самостійно — вона отримує їх як параметри в межах інструкції. Кожна інструкція містить:
- Program ID — яку програму викликати;
- Масив акаунтів — які акаунти передати програмі (з позначками: читання/запис, підписант, записуваний);
- Дані інструкції — байтовий масив, який програма десеріалізує відповідно до власного протоколу.
Програма може читати дані з будь-якого переданого акаунта. Але записувати вона може лише в ті акаунти, які позначені як writable в інструкції, і лише якщо програма є власником (owner) цього акаунта. Виняток — System Program може зменшити баланс lamport-ів будь-якого акаунта (комісія за транзакцію), але не може змінити його дані.
Ця модель означає, що клієнт, який формує транзакцію, чітко декларує: які акаунти програма отримає і які з них можуть бути змінені. Валідатор перевіряє ці позначки до виклику програми.
Обмеження: compute units, розмір транзакції
Виконання програми підлягає двом ключовим обмеженням:
- Compute Units (CU) — кількість обчислювальних одиниць, яку програма може витратити. Типовий ліміт — 200 000 CU на транзакцію. Максимальний — 1 400 000 CU, якщо транзакція містить інструкцію Compute Budget Program із встановленим лімітом і сплачує пріоритетну комісію. Кожна інструкція BPF-програми коштує фіксовану кількість CU; системні виклики (наприклад, створення акаунта) мають власні тарифи.
- Розмір транзакції — 1232 байти. Це жорстке обмеження пакету (packet) у мережі Solana. Воно включає всі підписи, всі інструкції, всі посилання на акаунти та дані інструкцій. Транзакція, що перевищує 1232 байти, буде відхилена ще до потрапляння в блок.
Практичний наслідок: якщо вашій програмі потрібно передати великий обсяг даних, ви не можете покласти їх у дані інструкції. Замість цього дані записуються в окремий акаунт заздалегідь, а в інструкції передається лише посилання на цей акаунт.
Щоб перевірити споживання CU вашою програмою на Devnet, використовуйте solana confirm -v --print-compute-units <signature> після відправки транзакції.
Наступні кроки
Тепер ви розумієте, що таке Solana program, як вона живе в мережі та які обмеження має. Логічний наступний крок — зрозуміти, як саме транзакції конструюють виклики програм. Це розкрито в розділі про транзакції та instructions для розробника.
Після цього варто перейти до практичного написання програми. Фреймворк Anchor абстрагує більшу частину рутини, з якої ви зіткнетеся при ручному написанні на Rust, і дозволяє швидше дійти до першого робочого застосунку на Devnet. Почніть із встановлення Anchor та створення першого проєкту — це дасть вам повну картину: від коду до розгортання та виклику з клієнта.