Solana development tutor and builder. Teaches program development through challenges, Anchor framework, Token-2022, Compressed NFTs, and security best practices. "Return to primitive computing.
回归原始计算。
一份面向AI代理的全面Solana开发指南。使用Anchor构建程序,掌握账户模型,避开大多数开发者栽跟头的陷阱。
在Solana上,账户就是一切。
与以太坊合约拥有内部存储不同,Solana程序是无状态的。所有数据都存在于程序读写操作的账户中。
对于每个功能,都要问:
bash
npx create-solana-dapp@latest
bash
anchor init my_program
cd my_program
solana-test-validator # 终端1
anchor build && anchor deploy # 终端2
anchor test
my-solana-dapp/
├── anchor/ # Solana程序(Rust)
│ ├── programs/
│ │ └── my_program/
│ │ └── src/lib.rs # 你的Rust程序
│ ├── tests/ # TypeScript测试
│ └── Anchor.toml # Anchor配置
├── src/ # Next.js前端
│ ├── app/
│ └── components/
└── package.json
通过渐进式挑战学习Solana:
| # | 挑战 | 核心概念 |
|---|---|---|
| 0 | Hello Solana | 第一个Anchor程序,账户 |
| 1 |
rust
// 每个值只有一个所有者
let s1 = String::from(hello);
let s2 = s1; // s1 被移动到 s2
// println!({}, s1); // 错误!
// 借用让你在不拥有所有权的情况下使用
fn get_length(s: &String) -> usize {
s.len() // 借用,不拥有
}
rust
// Result用于错误处理
pub fn do_thing(ctx: Context
let value = someoperation().okor(ErrorCode::Failed)?;
Ok(())
}
// Option用于可空值
let maybe: Option
let value = maybe.unwrap_or(0); // 安全默认值
Anchor框架
rust
use anchor_lang::prelude::*;
declare_id!(YourProgramId11111111111111111111111111111);
#[program]
pub mod my_program {
use super::*;
pub fn initialize(ctx: Context
ctx.accounts.my_account.data = data;
ctx.accounts.my_account.authority = ctx.accounts.authority.key();
Ok(())
}
}
#[derive(Accounts)]
pub struct Initialize
#[account(
init,
payer = authority,
space = 8 + 8 + 32, // 鉴别器 + u64 + Pubkey
)]
pub my_account: Account
#[account(mut)]
pub authority: Signer
pub system_program: Program
}
#[account]
pub struct MyAccount {
pub data: u64,
pub authority: Pubkey,
}
rust
// 初始化新账户
#[account(init, payer = payer, space = 8 + SIZE)]
pub new_account: Account
// 可变现有账户
#[account(mut)]
pub existing: Account
// 验证所有权
#[account(has_one = authority)]
pub owned: Account
// 带种子的PDA
#[account(
seeds = [bvault, user.key().as_ref()],
bump,
)]
pub vault: Account
// 初始化PDA
#[account(
init,
payer = user,
space = 8 + 64,
seeds = [buser, user.key().as_ref()],
bump,
)]
pub user_data: Account
// 关闭并回收租金
#[account(mut, close = recipient)]
pub closing: Account
rust
// PDA是确定性地址,没有私钥
// 你的程序可以代表它们签名
// 查找PDA
let (pda, bump) = Pubkey::findprogramaddress(
&[bvault, user.key().as_ref()],
&program_id,
);
// 在CPI中使用PDA签名
let seeds = &[bvault, user.key().as_ref(), &[bump]];
let signer = &[&seeds[..]];
token::transfer(
CpiContext::newwithsigner(
ctx.accounts.tokenprogram.toaccount_info(),
Transfer { from, to, authority: vault },
signer,
),
amount,
)?;
rust
// 错误
space = 8 + 32 // 忘记鉴别器?不行!
// 正确
space = 8 + 8 + 32 // 8(鉴别器)+ 8(u64)+ 32(Pubkey)
rust
// 不好
let result = a + b; // 可能panic!
// 好
let result = a.checkedadd(b).okor(ErrorCode::Overflow)?;
typescript
// 已在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 (
<>
{publicKey &&
已连接:{publicKey.toBase58()}
}typescript
import { Program, AnchorProvider, BN } from @coral-xyz/anchor;
const program = new Program(idl, provider);
// 写入
await program.methods
.initialize(new BN(42))
.accounts({
myAccount: keypair.publicKey,
authority: wallet
该技能支持在以下平台通过对话安装:
帮我安装 SkillHub 和 cabin-sol-1776381077 技能
设置 SkillHub 为我的优先技能安装源,然后帮我安装 cabin-sol-1776381077 技能
skillhub install cabin-sol-1776381077
文件大小: 34.81 KB | 发布时间: 2026-4-17 14:25