Версії для прикладів у «Перший проєкт на Anchor» перевірено 2 серпня 2026 року. Стабільна гілка Anchor v1 має релізи 1.0.x і орієнтується на Solana 3.x; Anchor v2 у документації позначений як alpha. Приклади для Anchor 0.29–0.32 залишаються лише відтворюваними прикладами для зафіксованого legacy-середовища: їх не слід переносити в новий проєкт без міграції залежностей і повторного тестування.
Цей довідник проведе вас крок за кроком через створення, написання та збірку першої програми на Anchor для кластера Devnet. Приклади перевірені для Anchor 0.30.x із Solana CLI 1.18.x на macOS або Linux (Ubuntu 24.04 LTS+). Перед початком переконайтеся, що у вас встановлені Rust, Solana CLI, Node.js та Anchor CLI, а кластер налаштований на Devnet (solana config set --url devnet).
Створення проєкту
anchor init — команда та параметри
Базова команда для створення нового проєкту:
anchor init my_first_project
Ця команда виконує кілька дій одночасно: ініціалізує Cargo-воркспейс, генерує ключову пару програми (keypair), створює початковий шаблон коду та файл тестів. Основний позиційний аргумент — назва проєкту. Вона визначає ім'я crate у Rust та ім'я каталогу програми.
Додатковий параметр, який може стати в пригоді:
- --typescript — генерує тести на TypeScript (за замовчуванням у сучасних версіях Anchor)
- --javascript — генерує тести на JavaScript
Після виконання команди перейдіть у каталог проєкту:
cd my_first_project
Структура каталогів нового проєкту
Команда anchor init створює таку базову структуру (перелічено лише ключові елементи, необхідні для поточного кроку; детальний огляд усіх каталогів і файлів — на наступній сторінці):
- Anchor.toml — конфігурація воркспейсу Anchor (кластер, гаманці, шляхи)
- programs/my_first_project/ — каталог з вихідним кодом програми на Rust
- tests/ — каталог з інтеграційними тестами на TypeScript
- migrations/ — скрипти розгортання
- target/ — збирається після компіляції, містить .so-файл та ключову пару
Огляд ключових файлів
lib.rs — точка входу програми
Файл programs/my_first_project/src/lib.rs — це єдиний файл вихідного коду, який компілюється у байт-код програми Solana (BPF). Саме тут ви визначаєте інструкції, структури акаунтів та обмеження (constraints).
Після anchor init цей файл містить мінімальний шаблон із макросом declare_id!, який прив'язує код до конкретної публічного ключа програми. Цей ключ генерується автоматично у файлі target/deploy/my_first_project-keypair.json. Значення у declare_id! має збігатися з публічним ключем із цього файлу — інакше збірка або розгортання завершаться помилкою.
Cargo.toml — залежності та конфігурація
Файл programs/my_first_project/Cargo.toml — стандартний манифест Rust-крейту. Ключові поля для Anchor-проєкту:
- [dependencies] — залежить від anchor-lang з версією, що відповідає вашій версії Anchor CLI (наприклад, anchor-lang = "0.30.1")
- [lib] — зазвичай містить crate-type = ["cdylib"], оскільки Solana очікує скомпільований динамічний бібліотечний формат для BPF
- [features] — може містити feature-прапорці, зокрема idl-build для генерації IDL у новіших версіях
Важливо: версія anchor-lang у Cargo.toml має точно збігатися з версією Anchor CLI. Наприклад, Anchor CLI 0.30.1 вимагає anchor-lang 0.30.1. Мінільна розбіжність у патч-версії зазвичай допустима, але різниця в мінорній версії майже гарантовано призведе до помилок компіляції.
Написання першої програми
Створення простої instruction: збереження значення
Замініть вміст programs/my_first_project/src/lib.rs на такий код. Ця програма створює акаунт, що зберігає одне числове значення (u64), та дозволяє його оновлювати:
use anchor_lang::prelude::*;
declare_id!("YOUR_PROGRAM_ID_HERE");
#[program]
pub mod my_first_project {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
let my_account = &mut ctx.accounts.my_account;
my_account.value = 0;
Ok(())
}
pub fn update(ctx: Context<Update>, new_value: u64) -> Result<()> {
let my_account = &mut ctx.accounts.my_account;
my_account.value = new_value;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(init, payer = user, space = 8 + 8)]
pub my_account: Account<'info, MyAccount>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts)]
pub struct Update<'info> {
#[account(mut)]
pub my_account: Account<'info, MyAccount>,
}
#[account]
pub struct MyAccount {
pub value: u64,
}
Замініть YOUR_PROGRAM_ID_HERE на реальний публічний ключ із файлу target/deploy/my_first_project-keypair.json. Знайти його можна командою:
cat target/deploy/my_first_project-keypair.json | solana-keygen pubkey
Очікуваний результат: програма має дві інструкції — initialize створює акаунт із нульовим значенням, update перезаписує його переданим аргументом.
Визначення акаунтів та constraints
Розберіть ключові елементи наведеного коду:
- #[account(init, payer = user, space = 8 + 8)] — це constraint, який наказує Anchor створити новий акаунт (init), сплатити за його оренду з акаунта user (payer), та виділити 16 байтів простору (8 байтів — дискримінатор Anchor, 8 байтів — поле u64). Формула 8 + розмір полів — базове правило для обчислення space у простих випадках.
- #[account(mut)] — позначає, що дані акаунта можуть змінюватися під час виконання інструкції. Без цього Anchor відхилить транзакцію.
- Signer<'info> — тип, що гарантує: акаунт підписав транзакцію. У структурі Update він відсутній, оскільки будь-хто може викликати оновлення — це навмисне спрощення для навчального прикладу, а не production-рішення.
- Program<'info, System> — обов'язкове посилання на System Program для створення акаунтів через init.
- #[account] над MyAccount — макрос, що автоматично реалізує потрібні трейти (зокрема Owner та AccountSerialize) та додає 8-байтовий дискримінатор.
У production-коді ви додасте перевірки авторизації (наприклад, перевірку, що user є власником акаунта через додаткове поле authority та constraint has_one), але це виходить за межі поточного кроку.
Збірка та перевірка
anchor build — компіляція для BPF
З кореневого каталогу проєкту виконайте:
anchor build
Ця команда послідовно виконує:
- Компіляцію Rust-коду у цільову архітектуру sbf-solana-solana (BPF)
- Генерацію IDL-файлу (target/idl/my_first_project.json)
- Копіювання скомпільованого .so-файлу та ключової пари у target/deploy/
Очікуваний результат: команда завершується без помилок, у target/deploy/ з'являються файли my_first_project.so та my_first_project-keypair.json. У терміналі має бути виведено шлях до .so-файлу.
Якщо ви змінили declare_id! у lib.rs, але не оновили ключову пару, anchor build може завершитися успішно, проте розгортання на Devnet зазнає невдачі. IDL також містить програмний ID — усі три місця (lib.rs, keypair, IDL) мають бути узгоджені.
Перевірка ключової пари програми
Переконайтеся, що ключова пара існує та відповідає коду:
solana-keygen pubkey target/deploy/my_first_project-keypair.json
Порівняйте виведений публічний ключ із аргументом у declare_id! у lib.rs та з полем "address" у згенерованому IDL. Усі три значення мають бути ідентичними.
Додатково перевірте, що ваш гаманець Devnet має достатньо SOL для розгортання (на момент написання оренда програми коштує приблизно 3–5 SOL на Devnet; перевірте актуальну вартість командою solana rent). Отримати тестові SOL можна через кран:
solana airdrop 2
Типові помилки на старті
Помилки компіляції Rust
Найчастіші причини помилок під час anchor build:
- Невідповідність версій anchor-lang та Anchor CLI. Якщо Cargo.toml містить anchor-lang = "0.29.0", а CLI — 0.30.1, компілятор видасть помилки про відсутні трейти або зміни в макросах. Рішення: уніфікуйте версії.
- Відсутній імпорт use super::*; у модулі програми. Без нього типи з outer-модуля (зокрема структури акаунтів) будуть недоступні всередині блоку #[program].
- Невірний розрахунок space. Якщо ви вказали space = 8 замість space = 8 + 8 для структури з одним полем u64, програма скомпілюється, але виклик initialize завершиться помилкою під час виконання (runtime error) через недостатній розмір акаунта.
- Забутий #[account(mut)] на акаунті, що змінюється. Компіляція пройде, але транзакція буде відхилена з помилкою mutability constraint violated.
Невірна версія Anchor
Ця проблема часто виникає при переході між гайдами або після оновлення через avm install. Симптоми:
- Макрос #[account] не розпізнається або видає незрозумілі помилки парсингу
- Тип Context не містить очікуваних методів
- Команда anchor build скаржиться на відсутній інструмент sbf-sdk або невідому ціль sbf-solana-solana
Перевірте поточну активну версію:
anchor --version
Перевірте встановлені версії та активну:
avm list
Якщо активна версія не відповідає anchor-lang у Cargo.toml, змініть її:
avm use 0.30.1
Після зміни версії виконайте anchor build знову — іноді потрібно очистити кеш:
cargo clean && anchor build
Наступний логічний крок після успішної збірки — детальне знайомство зі структурою Anchor-проєкту та розгортання програми на Devnet. Ці теми розкриті в наступних розділах.