Solana Programs
Build on-chain Solana programs with Anchor - account constraints, instructions, and cross-program invocation in Rust.
Recipe
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod hello_anchor {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
ctx.accounts.counter.count = 0;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(init, payer = user, space = 8 + 8)]
pub counter: Account<'info, Counter>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[account]
pub struct Counter {
pub count: u64,
}When to reach for this:
- High-throughput DeFi, NFT, or gaming logic on Solana
- Teams wanting IDL-generated TypeScript/Rust clients
- Composable protocols via CPI to SPL Token and other programs
Working Example
Increment instruction with signer and account constraints:
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod counter {
use super::*;
pub fn increment(ctx: Context<Increment>) -> Result<()> {
ctx.accounts.counter.count = ctx.accounts.counter.count
.checked_add(1)
.ok_or(ProgramError::InvalidArgument)?;
Ok(())
}
}
#[derive(Accounts)]
pub struct Increment<'info> {
#[account(mut, has_one = authority)]
pub counter: Account<'info, Counter>,
pub authority: Signer<'info>,
}
#[account]
pub struct Counter {
pub authority: Pubkey,
pub count: u64,
}What this demonstrates:
has_oneties signer to stored authority pubkey- Checked add maps overflow to program error
- Account mutability declared explicitly in derive
Deep Dive
How It Works
- Transactions invoke programs with account metas (writable, signer).
- Anchor
#[account(...)]macros validate owners, seeds, and rent. - IDL describes instructions for client SDKs.
- CPI lets your program call SPL Token
transferwith invoked signer seeds.
Account Types
| Type | Use |
|---|---|
Account<T> | Anchor-owned deserialized data |
Signer | Must sign transaction |
UncheckedAccount | Manual validation only |
Gotchas
- Account space too small - upgrade fails silently or rejects init. Fix:
space = 8 + sizeof(T)plus discriminator. - Missing signer on mut account - transaction simulation fails. Fix: mark
Signerandmutcorrectly inAccountsstruct. - Compute budget exceeded - loop-heavy logic fails on mainnet. Fix: profile CU in local validator, optimize or split instructions.
- PDA seed collisions - bricked accounts. Fix: namespace seeds with program id and domain tags.
- Unchecked external accounts - arbitrary CPI targets drain funds. Fix: whitelist program IDs in constraints.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Native Solana Rust (no Anchor) | Minimal binary size | Team wants IDL and safety macros |
| Ethereum Solidity | EVM liquidity and tooling | Need Solana throughput |
| Substrate pallet | Custom L1 chain | App on existing Solana cluster |
| Off-chain Rust + oracle | Heavy compute | State must be trustlessly on-chain |
FAQs
How do I test locally?
solana-test-validator plus anchor test runs migrations and integration tests against local cluster.
What is the 8-byte prefix?
Anchor account discriminator - do not forget it in space calculation.
Upgradeable programs?
Deploy with upgrade authority, then transfer authority to multisig or burn for immutability when audited.
SPL Token integration?
CPI to token program with PDA signer seeds for vault authority pattern.
Client generation?
anchor build emits IDL; use @coral-xyz/anchor or anchor-client in Rust integration tests.
Rent exemption?
Accounts need minimum lamports for size; fund on init or reclaim on close.
Error codes?
Define #[error_code] enum for user-visible errors instead of generic failures.
Mainnet vs devnet?
Devnet airdrops are unreliable; use local validator for CI, devnet for manual QA.
Security review?
Walk Security & Auditing before mainnet deploy.
Key management?
Deployer keys off hot laptops - see Wallets & Key Management.
Related
- Blockchain Basics in Rust - primitives
- Wallets & Key Management - signers
- Security & Auditing - vulnerabilities
- Applied Cryptography - hashes and curves
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.