Ця сторінка — системний посібник для розробника, який починає працювати з Solana. Тут зібрана ментальна модель блокчейну, практичні кроки від першої транзакції до повноцінного застосунку та посилання на глибші матеріали. Усі приклади орієнтовані на Devnet — тестовий кластер, де помилки не коштують реальних коштів.
Модель даних і виконання
Як стати Solana-розробником
Solana-розробник відрізняється від Ethereum-розробника насамперед моделлю даних. Замість стану, що зберігається в контрактах, Solana використовує незалежні акаунти з власним балансом і даними. Щоб почати, потрібні: базове розуміння блокчейну, знайомство з Rust на рівні синтаксису та досвід роботи з TypeScript або JavaScript для клієнтської частини. Навчання найкраще будувати за циклом: зрозуміти модель акаунтів, написати першу програму на Anchor, підключити frontend, додати роботу з токенами.
Як працює модель акаунтів у Solana
У Solana немає єдиного «стану контракту». Замість цього кожен акаунт — це окремий запис у базі даних кластера. Акаунт має власник (програму, яка має право змінювати його дані), баланс у lamports (1 SOL = 1 000 000 000 lamports), розмір даних та самі дані. Програма не «володіє» станом — вона лише читає та записує дані в акаунти, якими керує. Це ключова відмінність, яку треба засвоїти перед написанням першої програми.
Що таке Solana program
Solana program (програма) — це скомпільований байт-код, розміщений у кластері. Програма є stateless: вона не зберігає власні дані, а лише обробляє instructions (інструкції), які надходять у транзакціях. Програма отримує на вхід список акаунтів, дані інструкції та контекст виконання, після чого зчитує та модифікує акаунти відповідно до своєї логіки. Програми пишуться переважно на Rust, рідше на C або C++.
Транзакції та instructions для розробника
Транзакція в Solana містить одну або кілька інструкцій, які виконуються атомарно: або всі успішні, або жодна. Кожна інструкція вказує: програму-виконавця, список акаунтів (які читаються або записуються) та серіалізовані дані інструкції. Порядок інструкцій у транзакції визначає порядок виконання. Одна транзакція може викликати кілька різних програм — це основа для композиції логіки на ланцюжку.
Що таке signers у Solana
Signer — це акаунт, чий приватний ключ підписав транзакцію. У кожній інструкції перший акаунт традиційно є signers, але програма сама визначає, які акаунти мають бути підписані, через перевірку `signer` у контексті. Signer потрібен для авторизації: наприклад, лише власник акаунта може перевести з нього кошти. Важливо розрізняти signers від writable акаунтів — акаунт може бути записуваним, але не підписаним, і навпаки.
Комісії транзакцій у Solana для початківця
Кожна транзакція сплачує дві складові: базову комісію (base fee) за підпис транзакції та комісію за обчислення (compute unit price). Базова комісія фіксована на рівні кластера. Комісія за обчислення залежить від кількості запитаних compute units та поточного пріоритетного рівня (priority fee), який розробник встановлює вручну. На Devnet комісії сплачуються тестовими SOL, які можна отримати безкоштовно.
Compute units у Solana: як працюють обчислювальні ліміти
Compute units (CU) — це міра обчислювальних ресурсів, яку програма може використати під час виконання інструкції. Базовий ліміт на інструкцію становить 200 000 CU. Якщо програма перевищує ліміт, транзакція завершується помилкою `ComputationalBudgetExceeded`. Розробник може явно вказати менший ліміт через `ComputeBudgetInstruction.setComputeUnitLimit`, щоб зекономити на комісіях. Важливо: ліміт встановлюється на інструкцію, а не на всю транзакцію.
Як створити та відправити першу транзакцію на Devnet
Передумови: встановлено Solana CLI, налаштовано Devnet (`solana config set --url devnet`), є ключова пара. Отримайте тестові SOL через кран. Створіть та відправте транзакцію:
solana transfer <адресата> 0.01 --url devnet
Очікуваний результат: у терміналі з'явиться підпис транзакції (signature). Перевірте статус:
solana confirm -v <signature> --url devnet
Якщо статус `confirmed` — транзакція успішно оброблена кластером.
Як зберігаються дані в акаунтах Solana
Дані акаунта — це масив байтів фіксованого розміру (від 0 до 10 МБ). Програма сама визначає, як інтерпретувати ці байти: як структури, map-и чи інші формати. При створенні акаунта треба вказати `space` — кількість байтів, яку буде займати серіалізовані дані. Якщо пізніше знадобиться більше місця, акаунт треба перестворити з більшим `space` (збільшити розмір існуючого акаунта неможливо). Саме тому Anchor автоматично розраховує `space` на основі визначених структур.
Типові помилки транзакцій у Solana та їх вирішення
- `InstructionFallbackNotFound` — програма не знайшла обробник для переданих даних інструкції. Перевірте, чи правильний ідентифікатор інструкції (зазвичай перші 8 байтів — це sha256 хеш від назви методу).
- `AccountNotSigner` — акаунт, який програма очікує як підписаний, не підписав транзакцію. Перевірте порядок акаунтів та наявність `signers: true` у клієнті.
- `InsufficientFundsForRent` — на акаунті недостатньо lamports для оплати rent-exempt мінімуму. Поповніть акаунт.
- `ComputationalBudgetExceeded` — перевищено ліміт compute units. Оптимізуйте логіку або збільште ліміт.
Як читати логи транзакцій на Devnet
Логи — основний інструмент діагностики. Отримайте логи транзакції:
solana logs <signature> --url devnet
Або через `solana confirm -v`, що виводить повні логи разом із метаданими. Кожен рядок логу містить програму, що його згенерувала, та текст повідомлення. Anchor додає зручні префікси з назвами інструкцій та полів. Якщо логи обрізаються, використовуйте RPC-провайдера з повною підтримкою логів (не всі публічні ноди повертають повні логи).
Rust і Anchor для початківця
Базовий Rust для Solana-розробника
Для написання програм на Solana не потрібен експертний рівень Rust. Достатньо розуміти: власність та позичання (ownership & borrowing), структури та enum-и, трейти (особливо `Serialize` та `Deserialize` з crate `borsh`), макроси (атрибутні макроси `#[derive]`, `#[account]`) та обробку помилок через `Result`. Solana-програми не використовують стандартну бібліотеку `std` — доступний лише `core` та `alloc`, тому деякі звичні типи відсутні.
Що таке Anchor та чому він потрібен
Anchor — це фреймворк для Solana, який автоматизує рутину: серіалізацію/desеріалізацію акаунтів, перевірку прав доступу, розрахунок `space` для акаунтів, генерацію TypeScript-клієнта з IDL та безпеку seed-ів для PDA. Без Anchor розробник вручну пише парсинг байтів, перевірки signers та owner-ів, що призводить до помилок і вразливостей. Anchor не обмежує можливості — будь-яку логіку можна реалізувати вручну всередині Anchor-програми.
Перший проєкт на Anchor
Передумови: встановлено Rust (перевірте актуальну версію на офіційному сайті), Node.js, Anchor CLI. Створіть проєкт:
anchor init my_first_project
cd my_first_project
anchor build
Очікуваний результат: у каталозі `target/types/` з'явиться IDL-файл, у `target/deploy/` — скомпільований `.so` файл. Якщо збірка пройшла без помилок — середовище налаштовано коректно.
Структура Anchor-проєкту: каталоги та файли
- `programs/` — вихідний код програми на Rust. Кожна підпапка — окрема програма з `Cargo.toml` та `src/lib.rs`.
- `tests/` — інтеграційні тести на TypeScript. Тут пишуться тести, що взаємодіють з програмою через RPC.
- `target/` — результати збірки: байт-код, IDL, TypeScript-типи.
- `Anchor.toml` — конфігурація проєкту: кластер, гаманець, шляхи до програм, скрипти.
- `migrations/` — скрипти розгортання (deploy), що виконуються командою `anchor deploy`.
Anchor constraints: обмеження та перевірки в програмах
Constraints — це атрибути, які Anchor застосовує до акаунтів у структурі контексту. Вони виконуються автоматично перед передачею контролю до логіки інструкції. Основні:
- `#[account(mut)]` — акаунт може бути змінений програмою.
- `#[account(signer)]` — акаунт має бути підписаним.
- `#[account(seeds = [...], bump)]` — акаунт є PDA з вказаними seed-ами.
- `#[account(has_one = authority)]` — поле `authority` акаунта має збігатися з вказаним акаунтом.
- `#[account(constraint = ...)]` — довільна умова, що повертає `bool`.
Якщо хоча б один constraint не виконується, транзакція відхиляється до виконання логіки програми.
Що таке IDL у Anchor
IDL (Interface Definition Language) — це JSON-файл, що описує публічний інтерфейс програми: назви інструкцій, їхні аргументи, структури акаунтів та типи даних. Anchor генерує IDL автоматично під час `anchor build`. На основі IDL генерується TypeScript-клієнт, який забезпечує типобезпечне викликання інструкцій. IDL — це аналог ABI в Ethereum, але для Solana.
Як написати першу instruction на Anchor
Концептуальний приклад — програма, що зберігає повідомлення в акаунті:
#[derive(Accounts)]
pub struct SaveMessage<'info> {
#[account(mut)]
pub data_account: Account<'info, DataAccount>,
#[account(signer)]
pub authority: Signer<'info>,
}
pub fn save_message(ctx: Context<SaveMessage>, message: String) -> Result<()> {
ctx.accounts.data_account.message = message;
Ok(())
}
Цей приклад ілюструє механіку. Для production-рішення додайте перевірку довжини рядка, обмеження на автора та обробку помилок.
Anchor accounts: визначення та зв'язування даних
Акаунт-структура визначається з атрибутом `#[account]`:
#[account]
pub struct DataAccount {
pub authority: Pubkey,
pub message: String,
}
Anchor автоматично додає поле `discriminator` (8 байтів) на початку серіалізованих даних для ідентифікації типу акаунта. Це означає, що `space` має враховувати 8 байтів плюс розмір усіх полів. Anchor розраховує це автоматично через `DataAccount::INIT_SPACE`, якщо використовується відповідний атрибут.
Як тестувати просту програму локально
Передумови: встановлено Anchor, проєкт зібрано (`anchor build`). Запустіть локальний validator:
anchor test --provider.local
Ця команда автоматично піднімає локальний кластер, деплоїть програму та запускає тести з `tests/`. Очікуваний результат: усі тести зелені, у логах видно підписи транзакцій. Локальний validator не потребує реальних SOL і працює значно швидше за Devnet.
Як деплоїти Anchor-програму на Devnet
Передумови: на гаманці достатньо тестових SOL для розгортання (зазвичай достатньо 1–2 SOL на Devnet). У `Anchor.toml` встановіть:
[provider]
cluster = "devnet"
wallet = "~/.config/solana/id.json"
Виконайте:
anchor deploy
Очікуваний результат: у терміналі з'явиться Program ID щойно розгорнутої програми. Перевірте:
solana program show <Program ID> --url devnet
Зверніть увагу: Program ID на Devnet відрізняється від локального. Оновіть `lib.rs` та `Anchor.toml` з новим ID перед наступним деплоєм, інакше Anchor створить нову програму замість оновлення існуючої.
Типові помилки Anchor та їх вирішення
- `AccountDiscriminatorMismatch` — акаунт не має правильного discriminator. Найчастіше виникає, коли акаунт створено вручну без Anchor, або коли змінили структуру і не перестворили акаунт.
- `ConstraintSeeds` / `ConstraintOwner` — PDA не відповідає очікуваним seed-ам або owner-у. Перевірте порядок seed-ів та bump.
- `AccountNotInitialized` — акаунт не ініціалізовано, але код намагається його прочитати як `Account<T>`. Переконайтеся, що інструкція ініціалізації виконана раніше.
- Помилка `space` — акаунт створено з недостатнім розміром. Перевірте розрахунок `INIT_SPACE` та додайте запас для рядків (`String` потребує 4 байти на довжину плюс вміст).
TypeScript, SDK та frontend
Як встановити та налаштувати Solana CLI
Офіційний спосіб — через інсталятор:
sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)"
Після встановлення перевірте:
solana --version
Перевірте актуальну версію в офіційному репозиторії Solana перед встановленням. Налаштуйте кластер за замовчуванням:
solana config set --url devnet
Генеруйте ключову пару, якщо її немає:
solana-keygen new
Solana web3.js: перші кроки
@solana/web3.js — основний клієнт для взаємодії з кластером. Концептуальний приклад підключення:
import { Connection } from "@solana/web3.js";
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const slot = await connection.getSlot();
console.log("Current slot:", slot);
Очікуваний результат: число — поточний слот кластера. Якщо отримали число без помилок — підключення працює. Для production використовуйте власний RPC-провайдер замість публічних ендпоінтів.
Solana Kit для початківника
Solana Kit — це набір високорівневих утиліт поверх `@solana/web3.js`, що спрощує типові операції: створення транзакцій, роботу з токенами, підключення гаманців. Перевірте актуальну назву та статус пакету в офіційному репозиторії Solana перед використанням, оскільки інструменти екосистеми оновлюються часто.
Як підключити гаманець до застосунку
Гаманці (Phantom, Solflare, Backpack) інжектують об'єкт `window.solana` у браузер. Перевірка наявності та підключення:
const provider = window.solana;
if (!provider) {
alert("Встановіть гаманець");
return;
}
const response = await provider.connect();
console.log("Підключено:", response.publicKey.toString());
Очікуваний результат: у консолі з'явиться публічний ключ підключеного гаманця. Важливо: завжди перевіряйте наявність провайдера перед викликом `connect()`, інакше отримаєте runtime error.
Як надіслати транзакцію через TypeScript
Концептуальний приклад відправки SOL на Devnet:
import { Connection, Transaction, SystemProgram, LAMPORTS_PER_SOL } from "@solana/web3.js";
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
const transaction = new Transaction().add(
SystemProgram.transfer({
fromPubkey: senderPublicKey,
toPubkey: recipientPublicKey,
lamps: 0.01 * LAMPORTS_PER_SOL,
})
);
const signature = await provider.signAndSendTransaction(transaction);
await connection.confirmTransaction(signature, "confirmed");
Для production додайте обробку помилок, retry-логіку та перевірку балансу перед відправкою.
Як читати стан акаунта через клієнт
Для десеріалізації даних акаунта використовуйте типи, згенеровані Anchor з IDL:
import { Program, AnchorProvider } from "@coral-xyz/anchor";
import idl from "../target/idl/my_program.json";
const program = new Program(idl, programId, provider);
const account = await program.account.dataAccount.fetch(accountPublicKey);
console.log("Message:", account.message);
Очікуваний результат: десеріалізований об'єкт з полями, визначеними в Rust-структурі. Якщо акаунт не існує, метод викине помилку — обробляйте її через `try/catch`.
Як підключитися до Devnet з TypeScript
Вкажіть Devnet URL при створенні `Connection`:
const connection = new Connection(
"https://api.devnet.solana.com",
"confirmed"
);
Публічний Devnet RPC має rate limits. Якщо отримуєте помилки 429 — використовуйте альтернативний провайдер або зменште частоту запитів. Перевірте актуальні публічні ендпоінти в офіційній документації Solana.
Як створити простий UI для Solana-застосунку
Мінімальний UI для Solana-застосунку потребує три елементи: кнопка підключення гаманця, відображення балансу та кнопка виконання дії (наприклад, відправка транзакції). Використовуйте React або Vue для керування станом. Ключове правило: ніколи не зберігайте приватні ключі в frontend-коді — всі підписи виконуються через інжектований провайдер гаманця.
Як обробляти помилки гаманця у frontend
- Користувач відхилив підключення — `provider.connect()` викидає помилку. Показуйте повідомлення «Підключення скасовано» замість технічного тексту.
- Користувач відхилив транзакцію — `signAndSendTransaction` викидає помилку з повідомленням «User rejected the request». Обробляйте окремо від мережевих помилок.
- Гаманець не підключено — перевіряйте `provider.isConnected` або `provider.publicKey` перед кожною операцією.
- Непідтримуваний гаманець — перевірте наявність `window.solana` та `window.solana.isPhantom` (або аналогічне поле для інших гаманців).
Як перевірити баланс SOL через SDK
const balance = await connection.getBalance(publicKey);
console.log("Баланс:", balance / LAMPORTS_PER_SOL, "SOL");
Метод повертає баланс у lamports. Ділення на `LAMPORTS_PER_SOL` дає значення у SOL. Для періодичного оновлення балансу використовуйте `connection.onAccountChange` з підпискою на зміни акаунта.
Як запустити локальний validator для розробки
Локальний validator — це повноцінний вузол Solana, що працює на вашій машині без підключення до зовнішнього кластера. Запуск через Anchor:
anchor test --provider.local
Або вручну:
solana-test-validator
Очікуваний результат: validator стартує, у логах видно генерацію блоків. За замовчуванням він слухає `http://127.0.0.1:8899`. Локальний validator дає необмежені тестові SOL, миттєве підтвердження транзакцій та повний контроль над станом. Зупинка — `Ctrl+C` (стан не зберігається між перезапусками).
Токени, PDA та CPI
Що таке SPL Token та як він працює
SPL Token — це стандартна програма Solana для створення та управління токенами. На відміну від Ethereum, де токен — це смарт-контракт, у Solana токен — це комбінація з двох акаунтів: Mint Account (визначає тип токена: назву, кількість десяткових знаків, загальну пропозицію) та Token Account (прив'язаний до конкретного власника, зберігає баланс конкретного токена). Програма SPL Token обробляє інструкції: mint, burn, transfer, freeze та інші.
Token Extensions: огляд для початківника
Token Extensions (раніше Token-2022) — це розширена версія SPL Token програми з додатковими можливостями: конфіденційні транзакції (confidential transfers), transfer hooks, transfer fees, метадані токена без окремого метадата-акаунта, постійні делегати та інші. Перевірте актуальний перелік підтримуваних extensions в офіційній документації, оскільки список розширюється. Для використання Token Extensions треба вказувати правильний Program ID замість стандартного SPL Token.
Як створити токен на Devnet
Найпростіший спосіб — через SPL Token CLI:
spl-token create-token --url devnet
Очікуваний результат: у терміналі з'явиться адреса щойно створеного Mint Account. Створіть Token Account для отримання токенів:
spl-token create-account <MINT_ADDRESS> --url devnet
Змint-йте токени:
spl-token mint <MINT_ADDRESS> 1000 --url devnet
Перевірте баланс:
spl-token balance --url devnet
PDA простими словами для розробника
PDA (Program Derived Address) — це детерміновано згенерована адреса акаунта, яка контролюється програмою, але не має відповідного приватного ключа. PDA обчислюється як SHA-256 від програми та вказаних seed-ів (рядків або байтів), після чого перевіряється, чи результат лежить на кривій ed25519. Якщо ні — це валідний PDA. Програма може підписувати інструкції від імені PDA через `invoke_signed`, що дозволяє програмі управляти своїми акаунтами без участі зовнішнього користувача.
Як створити PDA у програмі
В Anchor PDA створюється через constraint `init`:
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(
init,
payer = authority,
space = 8 + DataAccount::INIT_SPACE,
seeds = [b"data", authority.key().as_ref()],
bump
)]
pub data_account: Account<'info, DataAccount>,
#[account(mut, signer)]
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
}
Anchor автоматично обчислює bump, створює акаунт та сплачує rent з акаунта `authority`. Seed-и мають бути детермінованими — зміна хоча б одного байту дасть іншу адресу.
Що таке CPI у Solana
CPI (Cross-Program Invocation) — це механізм виклику однією програмою іншої програми в межах тієї ж транзакції. Програма A може викликати інструкцію програми B, передаючи їй частину акаунтів зі своєї інструкції. CPI зберігає контекст підписів: якщо програма A підписує від імені PDA, програма B також бачить цей підпис. Це дозволяє будувати композицію: ваша програма може викликати SPL Token для mint-у, transfer-у або інших операцій з токенами.
Як викликати іншу програму через CPI
В Anchor CPI виконується через методи, згенеровані для цільової програми. Наприклад, виклик System Program для переказу SOL:
pub fn transfer_sol(ctx: Context<TransferSol>, amount: u64) -> Result<()> {
let cpi_context = CpiContext::new(
ctx.accounts.system_program.to_account_info(),
system_program::Transfer {
from: ctx.accounts.from.to_account_info(),
to: ctx.accounts.to.to_account_info(),
}
);
system_program::transfer(cpi_context, amount)?;
Ok(())
}
Для виклику з PDA-signer використовуйте `CpiContext::new_with_signer` з передачею seed-ів та bump.
Як передати токен через програму
Для передачі токенів через CPI програма має бути делегатом Token Account-а відправника. В Anchor це реалізується через `token::Transfer` з правильними акаунтами:
token::transfer(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
token::Transfer {
authority: ctx.accounts.authority.to_account_info(),
from: ctx.accounts.from_ata.to_account_info(),
to: ctx.accounts.to_ata.to_account_info(),
}
),
amount
?)
ATA (Associated Token Account) — це стандартний тип Token Account, адреса якого детерміновано обчислюється з публічного ключа власника та Mint Address.
Як mint-нути токен через Anchor
Програма може mint-нути токени, якщо є authority (або делегат) Mint Account-а. У тестовому середовищі зручно створити Mint з authority, що є PDA вашої програми:
token::mint_to(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
token::MintTo {
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.token_account.to_account_info(),
authority: ctx.accounts.mint_authority.to_account_info(),
}
),
signer_seeds
),
amount
?)
Для production обов'язково перевіряйте, що mint-authority належить вашій програмі, інакше будь-хто зможе mint-нути токени.
Як перевірити баланс токена на Devnet
Через CLI:
spl-token balance <MINT_ADDRESS> --url devnet
Через TypeScript:
import { getAssociatedTokenAddressSync, getAccount } from "@solana/spl-token";
const ata = getAssociatedTokenAddressSync(mint, owner);
const account = await getAccount(connection, ata);
console.log("Token balance:", account.amount);
Очікуваний результат: число у найменших одиницях токена. Поділіть на `10^decimals` для отримання значення у людському форматі.
Типові помилки PDA та CPI у Solana
- `Seeds must not contain mutable references` — seed-и для PDA мають бути незмінними. Не передавайте `&mut` посилання як seed.
- `InvalidSeeds` — обчислений PDA лежить на кривій ed25519, що неможливо. Змініть seed-и.
- `SignatureVerificationFailure` при CPI — програма не передала правильні signers через `invoke_signed`. Перевірте, що seed-и та bump у `invoke_signed` збігаються з тими, що використовувалися для обчислення PDA.
- `AccountNotSigner` при CPI з PDA — цільова програма очікує звичайного signer, а не PDA. Переконайтеся, що цільова програма підтримує PDA-signer через перевірку підпису PDA, а не звичайного `is_signer`.
- `IncorrectProgramOwner` для ATA — Token Account не належить очікуваній Token Program. Перевірте, чи використовуєте ви правильний Program ID (особливо при роботі з Token Extensions).
Навчальні проєкти
Як отримати тестові SOL на Devnet
Тестові SOL потрібні для сплати комісій на Devnet. Отримайте через кран:
solana airdrop 2 --url devnet
Або через веб-кран (перевірте актуальну URL-адресу в офіційній документації Solana). Ліміт airdrop-у обмежений — якщо не вистачає, виконайте команду кілька разів. Перевірте баланс:
solana balance --url devnet
Як структурувати повний Solana-проєкт
Повний проєкт зазвичай містить три частини: `programs/` (on-chain логіка на Rust/Anchor), `app/` або `frontend/` (клієнт на React/Next.js) та `tests/` (інтеграційні тести). У корені проєкту розміщуйте `Anchor.toml`, `package.json` для frontend-залежностей та `.env` для конфігурації. Розділяйте логіку: on-chain програма не повинна залежати від frontend, а frontend спілкується з програмою виключно через IDL та RPC.
Як створити простий токен-контракт на Anchor
Простий токен-контракт на Solana — це програма, що керує Mint Account через PDA як mint-authority. Програма надає інструкції `mint_to` (з обмеженням на загальну пропозицію) та `burn`. Замість того, щоб давати mint-authority зовнішньому акаунту, PDA програми контролює випуск. Це навчальний приклад — для production розгляньте Token Extensions з вбудованими обмеженнями.
Як побудувати escrow-програму на Anchor
Escrow — це класичний навчальний проєкт, що демонструє PDA, CPI та роботу з токенами. Логіка: відправник депонує токен A в escrow-акаунт (PDA), вказує бажаний токен B та суму. Отримувач викликає інструкцію `exchange`, передаючи токен B відправнику та отримуючи токен A з escrow. Програма використовує CPI для transfer-у обох токенів та закриває escrow-акаунт після виконання, повертаючи rent.
Як створити систему голосування на Solana
Навчальна система голосування містить: акаунт пропозиції (питання, варіанти, стан) та акаунти голосів (PDA, прив'язаний до пропозиції та голосуючого). Інструкції: `create_proposal`, `vote`, `close_proposal`. Ключовий нюанс — кожен голосуючий може проголосувати лише раз, що перевіряється через спробу ініціалізації PDA з фіксованими seed-ами (якщо PDA вже існує — голос відхилено). Це ефективніше, ніж зберігати масив голосуючих у пропозиції.
Як реалізувати прості платежі через програму
Простий платіж через програму — це переказ SOL від користувача до продавця з додатковою логікою (наприклад, запис платежу в акаунт). Програма отримує інструкцію з акаунтами відправника, отримувача та акаунтом запису платежу. Через CPI викликається `system_program::transfer`. Навчальний приклад — не використовуйте його для production без додавання перевірок на суму, отримувача та обробки edge cases.
Як створити Telegram-бот для Solana
Telegram-бот взаємодіє з Solana через TypeScript SDK на сервері. Архітектура: бот отримує команди від користувача, формує транзакцію, відправляє її на Devnet (або Mainnet) через RPC та повертає результат у чат. Для підписання транзакцій є два підходи: сервер зберігає ключову пару (навчальний, не для production) або користувач підписує через deep link у гаманці. Перший підхід підходить для навчання — другий вимагає інтеграції з wallet adapter.
Як поєднати frontend з on-chain програмою
Зв'язок frontend з програмою відбувається через три кроки: 1) ініціалізація `Program` з IDL та провайдером (гаманець + Connection), 2) виклик інструкції через `program.methods.methodName(args).accounts({...}).rpc()`, 3) читання стану через `program.account.accountType.fetch(address)`. Anchor генерує TypeScript-типи з IDL, що забезпечує типобезпечність на етапі компіляції. Усі акаунти, які інструкція очікує, треба явно передати в `.accounts()`.
Як тестувати навчальний проєкт на Devnet
Тестування на Devnet відрізняється від локального: транзакції підтверджуються повільніше, комісії реальні (тестові SOL), стан зберігається між сесіями. Підхід: напишіть тести на TypeScript з використанням Devnet RPC, використовуйте фіксовані ключові пари для передбачуваності, після кожного тесту перевіряйте стан акаунтів. Не забувайте поповнювати баланс тестових акаунтів через airdrop перед тестами.
Як деплоїти навчальний проєкт на Devnet
Послідовність: 1) оновіть `Anchor.toml` — встановіть `cluster = "devnet"` та правильний `wallet`, 2) виконайте `anchor build`, 3) виконайте `anchor deploy`, 4) скопіюйте Program ID з термінала, 5) оновіть `lib.rs` (константа `ID`) та `Anchor.toml` (поле `program_id`), 6) перезберіть та перездеплойте для фіксації ID. Після фіксації ID оновіть IDL у frontend-частині проєкту.
Перший full-stack застосунок Solana
Full-stack застосунок об'єднує всі попередні знання: Anchor-програма на ланцюжку, TypeScript-клієнт з `@coral-xyz/anchor` та React-frontend з підключенням гаманця. Рекомендований порядок розробки: спочатку напишіть та протестуйте програму локально, потім деплойте на Devnet, потім реалізуйте frontend з підключенням до Devnet, і нарешті об'єднайте та протестуйте повний цикл. Почніть з найпростішої логіки (зберігання та читання даних) і додавайте складність поступово.