Blockchain Best Practices
Safety-first habits for Rust blockchain engineering - on-chain programs, wallets, and node tooling.
How to Use This List
- Apply A-B when starting a new program or pallet.
- Complete C-D before mainnet deploy and treasury exposure.
- Review E quarterly for dependency and key hygiene.
A - On-Chain Code Quality
- Use
checked_*arithmetic for all token amounts. Never rely on release-mode wrapping. - Prefer Anchor or FRAME patterns over raw byte slicing. Fewer deserialization mistakes.
- Keep instructions small and compute-aware. Split heavy work across transactions or off-chain provers.
- Return typed errors, not panics. Panics abort programs and confuse clients.
- Document account layout and invariants in code comments. Auditors and future you need the spec.
B - Keys and Environments
- Never share keys between devnet and mainnet. Burner wallets for local testing only.
- Store treasury keys in multisig or HSM. Hot deployer keys hold minimal balance.
- Pin RPC URLs per environment in config. Wrong endpoint signs against unintended cluster.
- Verify program ID matches audited artifact hash. Supply-chain deploy mistakes happen.
- Rotate CI secrets and revoke old deploy keys after launch.
C - Testing and Verification
- Integration test every instruction and error path. Match IDL client expectations.
- Run local validator in CI for program repos. Catch deploy regressions early.
- Simulation before user-facing send flows. Surface program logs to UI for failures.
- Property tests on merkle and math helpers. Off-by-one bugs are common.
- External audit before significant TVL. No substitute for skilled human review.
D - Operations
- Monitor program error rates and compute usage post-deploy. Spikes indicate attack or bug.
- Timelock or multisig on upgrades. Users need notice before logic changes.
- Incident playbook: pause, communicate, patch, verify. Minutes matter in exploits.
-
cargo auditandcargo denyin pipeline. Crypto repos are high-value targets. - Log pubkeys and signatures, never seeds or private keys.
E - Design Discipline
- Minimize on-chain state - store hashes, not bulk data. Rent and merkle proofs scale better.
- Prefer composability via known programs (SPL, etc.). Reinventing token standards adds risk.
- Version client SDKs with on-chain program releases. Mismatched IDL causes user errors.
- Document decimal and rounding policy in user-facing docs. Support tickets follow confusion here.
- Assume adversarial inputs on every public instruction. Validators and bots will send weird bytes.
FAQs
What is the most common preventable loss?
Missing signer or authority check on an account that moves funds - caught by checklist in Security & Auditing.
Rust vs Solidity safety?
Rust removes memory bugs; logic bugs remain. Discipline on math and auth still required.
How small should programs be?
Small enough to audit; split into multiple programs via CPI when domains differ (token vs market).
Devnet testing enough?
Devnet plus local validator tests; mainnet-beta has different congestion and CU costs - stage on testnet when available.
Open source?
Transparency helps audits; keep deployment keys and admin endpoints private.
Dependency policy?
Minimize crate count on-chain; vet no_std compatibility and BPF build targets.
User error handling?
Map on-chain error codes to actionable UI strings with simulation log excerpts.
Formal verification?
Valuable for critical invariants; still pair with audits and fuzzing.
Cross-chain bridges?
Highest risk surface - extend audit scope beyond single program checklist.
Where to start learning?
Blockchain Basics in Rust then chain-specific pages.
Related
- Security & Auditing - pre-audit checklist
- Solana Programs - Anchor patterns
- Wallets & Key Management - key tiers
- Applied Cryptography - primitives
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+.