Rust
Rust best practices for Solana smart contract development using Anchor framework and Solana SDK
Awesome CursorRulesv1スター 0 · フォーク 0 · 作品 0約 1K トークン
Rust + Solana (Anchor) Best Practices
Program Structure
- Structure Solana programs using
Anchorframework standards - Place program entrypoint logic in
lib.rs, notmain.rs - Organize handlers into modules (e.g.,
initialize,update,close) - Separate state definitions, errors, instructions, and utils
- Group reusable logic under a
utilsmodule (e.g., account validation) - Use
declare_id!()to define program ID
Anchor Framework
- Use
#[derive(Accounts)]for all instruction contexts - Validate accounts strictly using constraint macros (e.g.,
#[account(mut)],seeds,bump]) - Define all state structs with
#[account]and#[derive(AnchorSerialize, AnchorDeserialize)] - Prefer
Init,Close,Realloc,Mut, and constraint macros to avoid manual deserialization - Use
ctx.accountsto access validated context accounts - Handle CPI (Cross-Program Invocation) calls via Anchor’s CPI helpers
Serialization
- Use Borsh or Anchor's custom serializer (not Serde) for on-chain data
- Always include
#[account(zero_copy)]or#[repr(C)]for packed structures - Avoid floating point types — use
u64,u128, or fixed-point math - Zero out or close unused accounts to reduce rent costs
Testing
- Write tests in TypeScript using Anchor’s Mocha + Chai setup (
tests/*.ts) - Use
anchor.workspace.MyProgramto load deployed contracts - Use
provider.simulate()to inspect failed txs - Spin up a local validator (
anchor test) and reset between tests - Airdrop SOL to wallets with
provider.connection.requestAirdrop(...) - Validate program logs using
tx.confirmation.logMessages
Solana SDK (Manual)
- Use
solana_programcrate when not using Anchor (bare-metal programs) - Carefully deserialize accounts using
AccountInfo,try_from_slice_unchecked - Use
solana_program::msg!for lightweight debugging logs - Verify accounts via
is_signer,is_writable,key == expected - Never panic! Use
ProgramError::Custom(u32)orErrorCodeenums
Security Patterns
- Always validate
msg.sender/signer withaccount_info.is_signer - Prevent replay attacks via
seeds,bump, and unique PDAs - Use strict size checks before reallocating or deserializing
- Avoid unsafe unchecked casting; prefer Anchor deserialization
- For CPIs, validate
target_programagainst expected program ID - When using randomness, never rely on timestamps — use oracles or off-chain VRFs
Performance
- Prefer zero-copy deserialization when accounts are large
- Minimize compute usage; avoid loops and recursion
- Avoid memory reallocations mid-instruction
- Use
#[account(zero_copy)]and#[repr(packed)]for tight layout - Profile compute units with
solana logsandanchor run
Dev Workflow
- Use
anchor initto scaffold projects - Add Anchor IDL support for front-end usage (JSON ABI)
- Use
anchor build,anchor deploy,anchor testconsistently - Use separate
Anchor.tomlenvironments for devnet/mainnet/localnet - Format all Rust code with
cargo fmt, lint withcargo clippy - Keep
Cargo.lockchecked intoprograms/but not root
Documentation
- Use
///Rust doc comments for all instructions and accounts - Include doc examples for each instruction
- Document PDA derivation logic and bump seed expectations
- Maintain up-to-date
README.mdwith test commands and deployment steps
Wallet & Network Handling
- Use
anchorProvider.wallet.publicKeyfor signer verification in tests - Do not hardcode keypairs — use env-based loading (
process.env.ANCHOR_WALLET) - Deploy with clear
clustertargets (localnet,devnet,mainnet) - Use
anchor keys syncto propagate program ID changes - Commit
target/idl/andtarget/types/to share with front end
CI/CD & Deploy
- Use GitHub Actions with
solana-cli,anchor-cli, andnodeinstalled - Run
anchor testin CI for every PR - Use
solana program deploywith explicit--program-idon production deploys - Upload IDLs to a central registry (e.g., GitHub, IPFS, or
anchor.cloud)