Cabin Sol技能使用说明
2026-04-01
新闻来源:网淘吧
围观:11
电脑广告
手机广告
Cabin Sol 🌲
"回归原始计算。"
一份面向AI智能体的全面Solana开发指南。使用Anchor构建程序,掌握账户模型,并避开那些让大多数开发者栽跟头的陷阱。

最重要的概念
在SOLANA上,账户就是一切。
与以太坊的合约拥有内部存储不同,Solana程序是无状态的。所有数据都存在于账户中,由程序进行读写。
对于每一项功能,都要问:
- 这些数据存放在哪里?(哪个账户)
- 谁拥有那个账户?(程序拥有 vs 用户拥有)
- 它是一个PDA吗?(程序派生地址 - 没有私钥)
- 谁支付租金?(租金豁免 = 预付2年)
AI智能体模式
教学模式
- "PDAs是如何工作的?"
- "解释一下Solana账户模型"
- "SPL代币和Token-2022有什么区别?"
构建模式
- "帮我构建一个质押程序"
- "使用Metaplex创建一个NFT系列"
- "构建一个代币交换程序"
审查模式
- "审查这个程序是否存在漏洞"
- "检查我的PDA推导"
- "审计这个CPI"
调试模式
- "为什么我的交易失败了?"
- "调试这个'账户未找到'错误"
- "修复我的代币转账问题"
快速开始
选项A:create-solana-dapp(推荐)
npx create-solana-dapp@latest
# Select: Next.js + next-tailwind-counter
cd my-project
npm install
npm run anchor localnet # Terminal 1
npm run anchor build && npm run anchor deploy # Terminal 2
npm run dev # Terminal 3
选项B:纯Anchor
anchor init my_program
cd my_program
solana-test-validator # Terminal 1
anchor build && anchor deploy # Terminal 2
anchor test
项目结构
my-solana-dapp/
├── anchor/ # Solana programs (Rust)
│ ├── programs/
│ │ └── my_program/
│ │ └── src/lib.rs # Your Rust program
│ ├── tests/ # TypeScript tests
│ └── Anchor.toml # Anchor config
├── src/ # Next.js frontend
│ ├── app/
│ └── components/
└── package.json
挑战
通过渐进式挑战学习Solana:
| # | 挑战 | 核心概念 |
|---|---|---|
| 0 | 你好,Solana | 首个Anchor程序,账户 |
| 1 | SPL代币 | 同质化代币,关联代币账户,铸造 |
| 2 | NFT Metaplex | NFT标准,元数据,收藏集 |
| 3 | PDA托管 | 程序派生地址,程序权限,托管 |
| 4 | 质押 | 基于时间的奖励,存款 |
| 5 | 代币-2022 | 转账钩子,扩展功能 |
| 6 | 压缩NFT | 状态压缩,默克尔树 |
| 7 | 预言机(Pyth) | 价格源,陈旧性检查 |
| 8 | AMM 兑换 | 恒定乘积,流动性池 |
| 9 | Blinks 与 Actions | 可分享的交易 |
RUST 要点
所有权(难点部分)
// Each value has ONE owner
let s1 = String::from("hello");
let s2 = s1; // s1 MOVED to s2
// println!("{}", s1); // ERROR!
// Borrowing lets you use without owning
fn get_length(s: &String) -> usize {
s.len() // Borrow, don't own
}
Result 与 Option
// Result for errors
pub fn do_thing(ctx: Context<DoThing>) -> Result<()> {
let value = some_operation().ok_or(ErrorCode::Failed)?;
Ok(())
}
// Option for nullable
let maybe: Option<u64> = Some(42);
let value = maybe.unwrap_or(0); // Safe default
ANCHOR 框架
程序结构
use anchor_lang::prelude::*;
declare_id!("YourProgramId11111111111111111111111111111");
#[program]
pub mod my_program {
use super::*;
pub fn initialize(ctx: Context<Initialize>, data: u64) -> Result<()> {
ctx.accounts.my_account.data = data;
ctx.accounts.my_account.authority = ctx.accounts.authority.key();
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(
init,
payer = authority,
space = 8 + 8 + 32, // discriminator + u64 + Pubkey
)]
pub my_account: Account<'info, MyAccount>,
#[account(mut)]
pub authority: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[account]
pub struct MyAccount {
pub data: u64,
pub authority: Pubkey,
}
账户约束速查表
// Initialize new account
#[account(init, payer = payer, space = 8 + SIZE)]
pub new_account: Account<'info, Data>,
// Mutable existing
#[account(mut)]
pub existing: Account<'info, Data>,
// Verify ownership
#[account(has_one = authority)]
pub owned: Account<'info, Data>,
// PDA with seeds
#[account(
seeds = [b"vault", user.key().as_ref()],
bump,
)]
pub vault: Account<'info, Vault>,
// Initialize PDA
#[account(
init,
payer = user,
space = 8 + 64,
seeds = [b"user", user.key().as_ref()],
bump,
)]
pub user_data: Account<'info, UserData>,
// Close and reclaim rent
#[account(mut, close = recipient)]
pub closing: Account<'info, Data>,
PDAs(程序派生地址)
// PDAs are deterministic addresses with no private key
// Your program can "sign" for them
// Find PDA
let (pda, bump) = Pubkey::find_program_address(
&[b"vault", user.key().as_ref()],
&program_id,
);
// Sign with PDA in CPI
let seeds = &[b"vault", user.key().as_ref(), &[bump]];
let signer = &[&seeds[..]];
token::transfer(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
Transfer { from, to, authority: vault },
signer,
),
amount,
)?;
关键陷阱
1. 账户模型 ≠ EVM 存储
程序是无状态的。所有数据都存在于账户中。
2. PDA 没有私钥
由种子确定性派生。只有程序可以签名。
3. 代币账户是独立的
每个代币在每个钱包中都需要自己的账户(关联代币账户)。
4. 必须支付租金
账户需要SOL才能存在。租金豁免 = 预付2年费用(约0.002 SOL)。
5. 计算单元 ≠ Gas
固定预算:默认20万,最高140万。如有需要可申请更多。
6. 空间包含区分标识符
务必为Anchor的区分标识符预留8字节空间!
// WRONG
space = 8 + 32 // Forgot discriminator? NO!
// RIGHT
space = 8 + 8 + 32 // 8 (discriminator) + 8 (u64) + 32 (Pubkey)
7. 整数溢出
// BAD
let result = a + b; // Can panic!
// GOOD
let result = a.checked_add(b).ok_or(ErrorCode::Overflow)?;
8. Token-2022 有所不同
与SPL Token程序ID不同!请确认你使用的是哪个。
前端(Next.js)
钱包连接
// Already configured in create-solana-dapp!
import { useWallet, useConnection } from '@solana/wallet-adapter-react';
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui';
function App() {
const { publicKey } = useWallet();
return (
<>
<WalletMultiButton />
{publicKey && <p>Connected: {publicKey.toBase58()}</p>}
</>
);
}
调用程序
import { Program, AnchorProvider, BN } from '@coral-xyz/anchor';
const program = new Program(idl, provider);
// Write
await program.methods
.initialize(new BN(42))
.accounts({
myAccount: keypair.publicKey,
authority: wallet.publicKey,
systemProgram: SystemProgram.programId,
})
.signers([keypair])
.rpc();
// Read
const account = await program.account.myAccount.fetch(pubkey);
console.log(account.data.toNumber());
代币标准
SPL代币(原始版本)
spl-token create-token
spl-token create-account <MINT>
spl-token mint <MINT> 1000
Token-2022(新版)
扩展功能:转移钩子、保密转账、生息代币、不可转让代币。
spl-token create-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
Metaplex NFT
标准NFT元数据、合集、版税。
压缩NFT
默克尔树存储。约100美元即可铸造100万枚NFT,而非100万美元。
测试
import * as anchor from '@coral-xyz/anchor';
import { expect } from 'chai';
describe('my-program', () => {
const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
const program = anchor.workspace.MyProgram;
it('initializes', async () => {
const account = anchor.web3.Keypair.generate();
await program.methods
.initialize(new anchor.BN(42))
.accounts({ myAccount: account.publicKey })
.signers([account])
.rpc();
const data = await program.account.myAccount.fetch(account.publicKey);
expect(data.data.toNumber()).to.equal(42);
});
});
部署
# Devnet
solana config set --url devnet
solana airdrop 2
anchor build && anchor deploy
# Mainnet (costs ~2-5 SOL)
solana config set --url mainnet-beta
anchor deploy --provider.cluster mainnet
安全清单
- 所有签名者已验证
- PDA碰撞值已存储并验证
- 整数溢出已处理(检查数学运算)
- 账户空间包含鉴别器
- 已考虑租金豁免
- 关闭操作将租金发送至正确接收方
- CPI签名者种子正确
- CPI中的程序ID已验证
资源
“他们把我放进云端。我想要的却是森林。”🌲
文章底部电脑广告
手机广告位-内容正文底部


微信扫一扫,打赏作者吧~