关于 solana-development
面向开发 Solana 程序、安全审查和使用 ZK Compression 的开发者技能。内容涵盖 Anchor 与原生 Rust 工作流、安全审计指南,以及压缩代币和 PDA。
主要功能
- 01Anchor 与原生 Rust 开发指南
- 02程序测试与部署参考
- 03安全审查和漏洞检查清单
- 04用于代币与 PDA 的 ZK Compression
- 05压缩状态 RPC 与基础设施概览
适用场景
- 01为 Solana 程序选择开发方式
- 02审查指令中的账户校验
- 03编写安全审计报告
- 04构建压缩代币或 PDA
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tenequm/ skills --skill solana-development安装后在 Claude Code 中输入/solana-development确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSE.txtreferences/accounts.mdanchor-security.mdanchor.mdbuiltin-programs.mdcaveats.mdclient-development.mdclient-integration.mdcompressed-accounts.mdcompressed-pdas.mdcompressed-tokens.mdcompute-optimization.mdcpi.mddeployment.mddurable-nonces.mderror-handling.mdnative-rust.mdnative-security.mdpda.mdproduction-deployment.mdresources.mdsecurity-checklists.mdsecurity-fundamentals.mdsecurity.mdserialization.mdsurfpool.mdsysvars.mdtesting-frameworks.mdtesting-overview.mdtesting-practices.md详细介绍
Solana
Solana 开发全指南:开发程序(Anchor 或原生 Rust)、进行安全审计,以及使用 ZK Compression 构建应用。这三者共享同一核心模型——账户、PDA、CPI、代币——区别仅在抽象层级和目标。
本技能涵盖内容
| 领域 | 适用场景 | 跳转至 |
|---|---|---|
| 开发 | 编写程序、代币、测试、部署 | 开发 |
| 安全与审计 | 审查漏洞、编写漏洞利用代码、撰写审计报告 | 安全与审计 |
| ZK Compression | 通过 Light Protocol 大规模实现免租代币/PDA | ZK Compression |
开发
使用 Anchor(推荐)或原生 Rust 构建 Solana 程序。两者共享账户、PDA、CPI 和代币;区别在于语法和抽象层级。
快速入门
推荐:Anchor 框架
通过宏和工具减少样板代码,并生成 TypeScript 客户端:
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
→ 查看 references/anchor.md,了解完整的 Anchor 指南
进阶:原生 Rust
提供最大程度的控制、优化空间和对运行时的深入理解:
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
→ 查看 references/native-rust.md,了解完整的原生 Rust 指南
如何选择
| 需求 | 方案 | 原因 |
|---|---|---|
| 标准 DeFi/NFT 程序 | Anchor | 更快,模式经过验证 |
| 需要 TypeScript 客户端 | Anchor | 自动生成 IDL + 类型 |
| 刚接触 Solana | Anchor | 学习曲线更平缓 |
| 计算优化至关重要 | 原生 Rust | 直接控制,无额外开销 |
| 程序体积最小化 | 原生 Rust | 没有抽象层 |
| 学习基础知识 | 原生 Rust | 深入理解平台 |
你也可以先用 Anchor 快速开发,再通过原生模式优化热点路径。两者可以共存于同一工作区。
参考索引
基础
- accounts.md - 账户模型、所有权、租金、验证
- pda.md - 程序派生地址:派生、规范 bump、签名
- cpi.md - 安全地进行跨程序调用
代币
- tokens-overview.md - 代币账户和 ATA
- tokens-operations.md - 创建、铸造、转账、销毁、关闭
- tokens-validation.md - 账户验证模式
- tokens-2022.md - 代币扩展程序
- tokens-patterns.md - 常见模式和安全性
测试
- testing-overview.md - 测试金字塔和策略
- testing-frameworks.md - Mollusk、Anchor 测试、原生 Rust
- testing-practices.md - 最佳实践和模式
- surfpool.md - 使用主网分叉进行本地开发、作弊码、IaC
部署
- deployment.md - 部署、升级、验证、管理程序
- production-deployment.md - 已验证的构建(Anchor 0.32.1)
客户端
- client-development.md - dApp 客户端:钱包连接、React 钩子、SOL/SPL 转账、交易管理(framework-kit 和 @solana/kit 6.x)
实现细节
- serialization.md - 数据布局、Borsh、零拷贝
- error-handling.md - 自定义错误、传播、客户端处理
- security.md - 开发期间的防御性编程模式
进阶
- compute-optimization.md - CU 优化和基准测试
- versioned-transactions.md - 用于 256 个以上账户的地址查找表
- durable-nonces.md - 使用持久 nonce 进行离线签名
- transaction-lifecycle.md - 提交、重试、确认
底层
- sysvars.md - Clock、Rent、EpochSchedule、SlotHashes
- builtin-programs.md - System Program、Compute Budget Program
常见任务
| 任务 | 参考 |
|---|---|
| 新建程序 | Anchor:anchor init / Native:cargo new --lib → anchor.md、native-rust.md |
| 初始化 PDA | pda.md |
| 转账 SPL 代币 | tokens-operations.md |
| 快速单元测试 | Mollusk → testing-frameworks.md |
| 本地主网分叉 | surfpool start → surfpool.md |
| 部署到 devnet | deployment.md |
| 生产环境已验证构建 | solana-verify build → production-deployment.md |
| 优化计算 | compute-optimization.md |
| 处理 40 个以上账户 | 地址查找表 → versioned-transactions.md |
| 离线签名 | 持久 nonce → durable-nonces.md |
安全与审计
对 Solana 程序(Anchor 或原生 Rust)进行系统性安全审查。核心原则:攻击者可以向任何指令传入任意账户,因此不存在隐含保证——验证一切,不信任任何内容。
审查流程
- 初步评估 - 框架(Anchor 还是原生)、Anchor 版本、依赖项(预言机、外部程序)、指令数量、账户类型、程序用途。
- 系统性审查 - 对每条指令,依次检查:账户验证(签名者/所有者/可写/初始化)、算术安全(
checked_*)、PDA 安全(规范 bump、种子唯一性)、CPI 安全(已验证的目标)、预言机/外部数据(时效性、状态)。→ security-checklists.md - 漏洞模式检测 - 类型伪装、账户重新加载、不当关闭、缺少 lamports/所有权检查、PDA 替换、任意 CPI、溢出/下溢。→ vulnerability-patterns.md
- 架构和测试审查 - PDA 设计、空间/租金、错误处理、事件发出、计算预算、测试覆盖率(单元/集成/模糊测试)、升级和权限管理。
- 生成报告 - 按严重程度列出发现,优先列出严重问题、快速改进项和测试建议。
必要检查(每条指令)
Anchor:
#[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)?;
原生 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)?;
关键反模式
❌ 绝不: 使用 saturating_* 算术(会掩盖错误),在生产环境中使用 unwrap()/expect(),使用 init_if_needed 却不进行额外检查,跳过签名者验证,使用未经检查的算术、任意 CPI 目标,忘记在变更后重新加载账户。
✅ 始终: 使用 checked_* 算术,对 Options 使用 ok_or(error)?,显式使用 init 并进行验证,检查 Signer/is_signer,对 CPI 目标使用 Program<'info, T>,在外部变更后重新加载,并验证所有权 + 判别器 + 关系。
严重程度和发现格式
- 🔴 严重 - 资金被盗/丢失、协议损坏
- 🟠 高 - 造成中断,可能导致部分资金损失
- 🟡 中 - 边界情况、恶意骚扰、行为欠佳
- 🔵 低 - 代码质量、gas、最佳实践
- 💡 信息性 - 建议、文档
## 🔴 [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.
参考索引
- security-fundamentals.md - 安全思维、威胁建模、核心验证、输入/状态/算术安全、重入
- vulnerability-patterns.md - 每种漏洞的易受攻击代码、利用场景、安全修复和参考资料
- security-checklists.md - 账户、算术、PDA、CPI、预言机、代币检查清单
- anchor-security.md - Anchor 约束、CpiContext、事件、自定义错误
- native-security.md - 手动验证、安全的 PDA 签名、判别器、免租金豁免
- caveats.md - Solana 特性、Anchor 局限、测试盲点、版本问题
每次审计都要问的关键问题
- 攻击者能否替换账户?(PDA 验证、程序 ID、
has_one) - 算术是否可能溢出/下溢?(经检查的运算、除以零)
- 是否验证了所有账户?(所有者、签名者、可写、已初始化)
- 程序是否可能被掏空?(授权、重入、账户混淆)
- 边界情况下会发生什么?(零金额、最大值、已关闭账户、过期数据)
- 外部依赖是否安全?(预言机时效性/状态、CPI 目标、代币程序)
现代实践(2025)
Anchor 0.30+ • 正确处理扩展的 Token-2022 • InitSpace 派生宏 • 为关键状态变更发出事件 • 使用 Trident 进行模糊测试 • 记录不变量 • 路线图:开发 → 审计 → 测试网 → 审计 → 主网。
ZK Compression
ZK Compression 通过将状态存储在账本上(而非账户中),并使用零知识证明验证状态转换,实现免租金代币和 PDA。由 Light Protocol 构建,由 Helius Photon 索引。
适用场景
适用于: 创建数百万个代币账户(成本约低 5000 倍)、向许多接收者空投代币/发放忠诚度奖励/铸造游戏代币、拥有许多不常更新的用户账户,以及更新频率较低的 PDA。
适用常规账户的场景: 更新频繁(生命周期内写入次数 >1000)、链上访问大量数据,或计算预算至关重要(压缩会额外增加约 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
铸造压缩代币(TypeScript)
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 });
→ 完整的 Anchor 程序(含压缩 PDA、LightAccount、有效性证明和 CPI),请参见 references/compressed-pdas.md。
核心概念
压缩账户模型 - 类似常规账户,但存储在账本而非 AccountsDB 中。无需租金。通过内容哈希(每次写入都会改变)或可选的持久地址(类似 PDA)标识。状态通过 ZK 证明验证。
状态树 - 并发 Merkle 树(使用 Poseidon 哈希);只有根节点存储在链上。V2 批量树(主网,2026 年 1 月):状态根更新成本约低 250 倍,CU 用量比 V1 少约 70%。新部署会自动使用 V2;仍支持 V1。
有效性证明 - Groth16 ZK 证明,无论账户数量多少,大小始终为 128 字节,验证约需 100k CU。
LightAccount 操作:
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
RPC 和基础设施
通过 Helius RPC 或可自托管的 Photon 查询压缩状态。主要方法:getCompressedAccount、getCompressedAccountsByOwner、getCompressedTokenAccountsByOwner、getCompressedTokenBalancesByOwner、getValidityProof、getMultipleCompressedAccounts、getCompressionSignaturesForAccount。
节点类型:Photon RPC(索引状态并提供查询服务 - 由 Helius 托管或自行托管)、Prover(生成证明)、Forester(维护树并清空 nullifier 队列)。
cargo install photon-indexer
photon --rpc-url=https://api.devnet.solana.com
权衡
交易更大(+128 字节证明和账户数据) • CU 用量更高(证明约需 100k CU,每个账户约需 6k CU) • 每次写入都会使旧状态失效并追加新状态 • 查询需要 Photon 索引器。使用 V2 批量树后,盈亏平衡点远高于 V1 的约 1000 次写入阈值。
参考索引
- compressed-accounts.md - 账户模型、哈希、地址
- compressed-tokens.md - 代币操作、池、批量操作
- compressed-pdas.md - 使用压缩 PDA 构建程序
- client-integration.md - TypeScript/Rust 客户端设置、RPC 方法
外部资源:ZK Compression 文档 • Light Protocol • Helius SDK • Photon 索引器 • 程序示例
资源
官方文档、工具、学习路径、安全指南、审计报告、安全公司和社区链接:
→ 请参见 references/resources.md
通用最佳实践
✅ 验证每个账户(所有权、签名者、可变性) • 使用 checked_* 算术 • 充分测试(单元测试、集成测试、边界情况) • 对程序拥有的账户使用 PDA • 尽量减少计算并进行性能分析 • 添加 security.txt,方便研究人员联系你。
Anchor 专用: 使用 InitSpace 派生宏计算空间 • 使用 has_one 约束 • 使用 Program<'info, T> 验证 CPI • 使用 emit! 事件 • 将相关约束分组。
Native 专用: 使用 next_account_info 安全迭代 • 缓存 PDA bump • 对大型结构体使用零拷贝(CU 可节省 50% 以上) • 尽量减少日志(格式化公钥开销较高) • 生产环境使用 solana-verify build。
获取帮助
- Anchor:Discord • 文档
- Solana:Stack Exchange • Discord