Everything for building on Solana: developing programs (Anchor or native Rust), auditing them for security, and building with ZK Compression. All three share the same core model - accounts, PDAs, CPIs, tokens - and differ only in abstraction level and goal.
| Area | Use when | Jump to |
|---|---|---|
| ------ | ---------- | --------- |
| Development | Writing programs, tokens, tests, deployments | Development |
| Security & Auditing | Reviewing for vulnerabilities, writing exploits, audit reports | Security and Auditing |
| ZK Compression | Rent-free tokens/PDAs at scale via Light Protocol | ZK Compression |
Build Solana programs with Anchor (recommended) or native Rust. Both share accounts, PDAs, CPIs, and tokens; they differ in syntax and abstraction.
Macros and tooling that cut boilerplate and generate TypeScript clients:
use anchor_lang::prelude::*;
declare_id!("YourProgramID");
#[program]
pub mod my_program {
use super::*;
pub fn initialize(ctx: Context<Initialize>, data: u64) -> Result<()> {
ctx.accounts.account.data = data;
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(init, payer = user, space = 8 + 8)]
pub account: Account<'info, MyAccount>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[account]
pub struct MyAccount {
pub data: u64,
}
cargo install --git https://github.com/coral-xyz/anchor avm --locked --force
avm install latest && avm use latest
anchor init my_project && cd my_project && anchor build && anchor test
→ See references/anchor.md for the complete Anchor guide
Maximum control, optimization potential, and deeper runtime understanding:
use solana_program::{
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult,
pubkey::Pubkey, msg,
};
entrypoint!(process_instruction);
pub fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
msg!("Processing instruction");
// Manual account parsing, validation, and instruction routing
Ok(())
}
cargo new my_program --lib
cd my_program # configure Cargo.toml (see native-rust.md)
cargo build-sbf
→ See references/native-rust.md for the complete native Rust guide
| Your need | Approach | Reason |
|---|---|---|
| ----------- | ---------- | -------- |
| Standard DeFi/NFT program | Anchor | Faster, proven patterns |
| TypeScript client needed | Anchor | Auto-generates IDL + types |
| New to Solana | Anchor | Gentler learning curve |
| Compute optimization critical | Native Rust | Direct control, no overhead |
| Smallest program size | Native Rust | No abstraction layer |
| Learning fundamentals | Native Rust | Understand the platform deeply |
You can also start with Anchor for speed, then optimize hot paths with native patterns. Both can coexist in one workspace.
Foundations
Tokens
Testing
Deployment
Client
Implementation details
Advanced
Low-level
| Task | Pointer |
|---|---|
| ------ | --------- |
| New program | Anchor: anchor init / Native: cargo new --lib → anchor.md, native-rust.md |
| Initialize a PDA | pda.md |
| Transfer SPL tokens | tokens-operations.md |
| Fast unit tests | Mollusk → testing-frameworks.md |
| Local mainnet fork | surfpool start → surfpool.md |
| Deploy to devnet | deployment.md |
| Production verified build | solana-verify build → production-deployment.md |
| Optimize compute | compute-optimization.md |
| Handle 40+ accounts | Address Lookup Tables → versioned-transactions.md |
| Offline signing | Durable nonces → durable-nonces.md |
Systematic security review for Solana programs (Anchor or native Rust). The core principle: attackers can pass arbitrary accounts to any instruction, so there are no implicit guarantees - validate everything, trust nothing.
checked_*), PDA security (canonical bumps, seed uniqueness), CPI security (validated targets), oracle/external data (staleness, status). → security-checklists.mdAnchor:
#[derive(Accounts)]
pub struct SecureInstruction<'info> {
#[account(
mut,
has_one = authority, // relationship check
seeds = [b"vault", user.key().as_ref()], bump // canonical bump
)]
pub vault: Account<'info, Vault>,
pub authority: Signer<'info>, // signer required
pub token_program: Program<'info, Token>, // program validation
}
let total = balance.checked_add(amount).ok_or(ErrorCode::Overflow)?;
Native Rust:
if !authority.is_signer { return Err(ProgramError::MissingRequiredSignature); }
if vault.owner != program_id { return Err(ProgramError::IllegalOwner); }
let total = balance.checked_add(amount).ok_or(ProgramError::ArithmeticOverflow)?;
❌ Never: saturating_* arithmetic (hides errors), unwrap()/expect() in production, init_if_needed without extra checks, skipped signer validation, unchecked arithmetic, arbitrary CPI targets, forgetting to reload accounts after mutations.
✅ Always: checked_* arithmetic, ok_or(error)? on Options, explicit init with validation, Signer/is_signer checks, Program<'info, T> for CPI targets, reload after external mutations, validate ownership + discriminator + relationships.
## 🔴 [CRITICAL] Title
**Location:** `programs/vault/src/lib.rs:45-52`
**Issue:** Brief description.
**Vulnerable Code:** ```rust ... ```
**Exploit Scenario:** How it's exploited, step by step.
**Recommendation:** ```rust ... ```
**References:** Links to docs or similar exploits.
has_one)Anchor 0.30+ • Token-2022 with proper extension handling • InitSpace derive • emit events for critical state changes • fuzz tests with Trident • document invariants • roadmap: Dev → Audit → Testnet → Audit → Mainnet.
ZK Compression enables rent-free tokens and PDAs by storing state on the ledger (not in accounts), using zero-knowledge proofs to validate state transitions. Built by Light Protocol, indexed by Helius Photon.
Use when: creating millions of token accounts (~5000x cheaper), airdrops/loyalty/gaming mints to many recipients, many infrequently-updated user accounts, low-update-frequency PDAs.
Use regular accounts when: updated frequently (>1000 lifetime writes), large data accessed on-chain, or compute budget is critical (compression adds ~100k CU).
# TypeScript client
npm install @lightprotocol/stateless.js @lightprotocol/compressed-token
# Rust SDK for programs
cargo add light-sdk
# CLI + local validator
npm install -g @lightprotocol/zk-compression-cli
light test-validator # local validator with compression
light init my-program # new Anchor project with compression
import { createRpc } from '@lightprotocol/stateless.js';
import { createMint, mintTo, transfer } from '@lightprotocol/compressed-token';
const rpc = createRpc(); // or createRpc('https://mainnet.helius-rpc.com?api-key=YOUR_KEY')
const { mint } = await createMint(rpc, payer, payer.publicKey, 9);
await mintTo(rpc, payer, mint, recipient, payer, 1_000_000_000);
await transfer(rpc, payer, mint, 500_000_000, owner, recipient);
const accounts = await rpc.getCompressedTokenAccountsByOwner(owner, { mint });
→ See references/compressed-pdas.md for the full Anchor program with compressed PDAs (LightAccount, validity proofs, CPI).
Compressed account model - Like regular accounts but stored on the ledger instead of AccountsDB. No rent. Identified by content hash (changes on every write) or an optional persistent address (PDA-like). State validated by ZK proofs.
State trees - Concurrent Merkle trees (Poseidon hashing); only the root is on-chain. V2 batched trees (mainnet, Jan 2026): ~250x cheaper state-root updates and ~70% less CU vs V1. New deployments use V2 automatically; V1 still supported.
Validity proofs - Groth16 ZK proofs, constant 128 bytes regardless of account count, ~100k CU to verify.
LightAccount operations:
LightAccount::<T>::new_init(&program_id, Some(address), tree_index); // create
LightAccount::<T>::new_mut(&program_id, &account_meta, current_state)?; // modify
LightAccount::<T>::new_close(&program_id, &account_meta, current_state)?; // close
Query compressed state via Helius RPC or self-hosted Photon. Key methods: getCompressedAccount, getCompressedAccountsByOwner, getCompressedTokenAccountsByOwner, getCompressedTokenBalancesByOwner, getValidityProof, getMultipleCompressedAccounts, getCompressionSignaturesForAccount.
Node types: Photon RPC (indexes state, serves queries - Helius or self-host), Prover (generates proofs), Forester (maintains trees, empties nullifier queues).
cargo install photon-indexer
photon --rpc-url=https://api.devnet.solana.com
Larger transactions (+128 byte proof + account data) • higher CU (~100k proof + ~6k per account) • each write nullifies old state and appends new • requires a Photon indexer for queries. With V2 batched trees, break-even shifts well past V1's ~1000-write threshold.
External: ZK Compression Docs • Light Protocol • Helius SDK • Photon Indexer • Program Examples
Official docs, tools, learning paths, security guides, audit reports, security firms, and community links:
→ See references/resources.md
✅ Validate every account (ownership, signers, mutability) • use checked_* arithmetic • test extensively (unit, integration, edge cases) • use PDAs for program-owned accounts • minimize and profile compute • add security.txt so researchers can reach you.
Anchor-specific: InitSpace derive for space • has_one constraints • Program<'info, T> for CPI validation • emit! events • group related constraints.
Native-specific: next_account_info for safe iteration • cache PDA bumps • zero-copy for large structs (50%+ CU savings) • minimize logging (pubkey formatting is expensive) • solana-verify build for production.
共 2 个版本