Настройка Anchor для разработки (Solana)
Solana разработка без Anchor — это работа напрямую с низкоуровневым Solana Program Library и ручной десериализацией account data через borsh. Anchor добавляет макросы, кодогенерацию IDL (Interface Definition Language) и TypeScript-клиент. Но настройка окружения с нуля занимает больше времени, чем кажется — версии инструментов конфликтуют, Anchor нужно собирать совместимым с конкретной версией solana-cli.
Что идёт не так при первой настройке
Несовместимость версий. Anchor 0.30.x требует Solana CLI 1.18.x. Anchor 0.29.x работал с 1.17.x. Поставить latest Anchor + latest Solana — почти гарантированный конфликт при anchor build. Ошибка error[E0308]: mismatched types в сгенерированном коде — обычно именно это.
Совместимые версии на апрель 2025:
| Anchor | Solana CLI | Rust |
|---|---|---|
| 0.30.1 | 1.18.17 | 1.75+ |
| 0.29.0 | 1.17.34 | 1.72+ |
| 0.28.0 | 1.16.x | 1.70+ |
avm (Anchor Version Manager) решает проблему переключения версий:
cargo install --git https://github.com/coral-xyz/anchor avm --force
avm install 0.30.1
avm use 0.30.1
Solana Tool Suite устанавливается отдельно и тоже требует точного указания версии:
sh -c "$(curl -sSfL https://release.anza.xyz/v1.18.17/install)"
После установки — проверка через solana --version и anchor --version. Если версии не совпадают с ожидаемыми — PATH не обновлён.
Структура Anchor проекта
После anchor init my-program получаем:
my-program/
├── programs/
│ └── my-program/
│ ├── Cargo.toml
│ └── src/
│ └── lib.rs # program entry point
├── tests/
│ └── my-program.ts # Mocha/Chai тесты
├── app/ # опционально, frontend
├── migrations/
│ └── deploy.ts
├── Anchor.toml # конфиг проекта
└── package.json
Anchor.toml — центральный конфиг. Там прописываются:
-
[programs.localnet]/[programs.mainnet]— адреса задеплоенных программ -
[provider]— cluster (localnet/devnet/mainnet) и wallet path -
[scripts]— команды для миграций и тестов
Cluster настройка. Для локальной разработки используем solana-test-validator:
solana-test-validator --reset
# в отдельном терминале:
anchor test --skip-local-validator # если validator уже запущен
# или просто:
anchor test # запустит validator автоматически
IDL и клиентская интеграция
Главная ценность Anchor — автоматическая генерация IDL (JSON-схема программы) при anchor build. IDL описывает accounts, instructions, types, events. На основе IDL генерируется TypeScript-клиент.
import { Program, AnchorProvider } from "@coral-xyz/anchor";
import { MyProgram, IDL } from "./target/types/my_program";
const provider = AnchorProvider.env();
const program = new Program<MyProgram>(IDL, provider);
// Вызов instruction
await program.methods
.initialize(new BN(1000))
.accounts({
myAccount: myAccountKp.publicKey,
user: provider.wallet.publicKey,
systemProgram: SystemProgram.programId,
})
.signers([myAccountKp])
.rpc();
Типы генерируются автоматически из IDL — никакого ручного описания интерфейсов. При изменении программы — пересборка, и TypeScript типы обновляются.
Account constraints. Anchor-макросы #[account] с аннотациями — ключевая фича:
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(
init,
payer = user,
space = 8 + MyAccount::INIT_SPACE,
seeds = [b"my-seed", user.key().as_ref()],
bump
)]
pub my_account: Account<'info, MyAccount>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>,
}
seeds + bump — автоматическая PDA (Program Derived Address) деривация и верификация. Anchor проверяет bump при каждом вызове — это предотвращает атаки через подмену PDA.
Тестирование
Тесты пишем на TypeScript через Mocha (встроен в Anchor). anchor test компилирует программу, запускает localnet, деплоит программу и прогоняет тесты.
it("initializes account", async () => {
const [myPda] = PublicKey.findProgramAddressSync(
[Buffer.from("my-seed"), user.publicKey.toBuffer()],
program.programId
);
await program.methods
.initialize(new BN(1000))
.accounts({ myAccount: myPda, user: user.publicKey })
.rpc();
const account = await program.account.myAccount.fetch(myPda);
assert.equal(account.amount.toNumber(), 1000);
});
Для более сложных сценариев — bankrun (быстрая симуляция без полного валидатора) или solana-program-test на Rust.
Деплой на devnet и mainnet
# devnet
anchor deploy --provider.cluster devnet
# mainnet — через multisig (Squads Protocol) или программный апгрейд
solana program deploy target/deploy/my_program.so \
--program-id target/deploy/my_program-keypair.json \
--url mainnet-beta
Для mainnet — обязательно программный keypair в cold storage. Потеря keypair = невозможность апгрейда программы навсегда. Рекомендуем Squads Protocol для multisig управления апгрейдами.
После деплоя — верификация исходного кода на Solana Explorer через solana-verify CLI от OtterSec:
solana-verify verify-from-repo \
--url https://api.mainnet-beta.solana.com \
--program-id YourProgramId \
https://github.com/yourorg/yourrepo
Срок настройки окружения с нуля — 4-8 часов включая первый рабочий тест. Настройка CI/CD pipeline (GitHub Actions с кэшированием Rust toolchain) + деплой скрипт — ещё 1-2 дня.







