Skip to content

Commit d7043f4

Browse files
author
Lewis
committed
project7: add more comprehensive comments and bump anchor version to 0.31.1
solana-developers#51
1 parent 032f4e6 commit d7043f4

File tree

7 files changed

+353
-6
lines changed

7 files changed

+353
-6
lines changed

project-7-swap/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check"
66
},
77
"dependencies": {
8-
"@coral-xyz/anchor": "^0.30.1",
8+
"@coral-xyz/anchor": "0.31.1",
99
"@solana-developers/helpers": "^2.4.0",
1010
"@solana/spl-token": "^0.4.8"
1111
},

project-7-swap/programs/swap/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@ no-log-ix-name = []
1717
idl-build = ["anchor-lang/idl-build", "anchor-spl/idl-build"]
1818

1919
[dependencies]
20-
anchor-lang = { version = "0.30.1", features=["init-if-needed"]}
21-
anchor-spl = "0.30.1"
22-
solana-program= "=2.0.3"
20+
anchor-lang = { version = "0.31.1", features=["init-if-needed"]}
21+
anchor-spl = "0.31.1"
22+
solana-program= "=2.1.0"
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
# Anchor 宏和约束速查表
2+
3+
## 问题分析
4+
5+
你提到的问题确实存在:
6+
1. **宏和约束太多**:Anchor有大量的宏和约束需要记忆
7+
2. **官方文档不友好**:缺乏清晰的速查表和示例
8+
3. **开发者体验差**:需要频繁查阅文档或复制粘贴
9+
10+
## 常用宏和约束速查表
11+
12+
### 1. 基础账户约束
13+
14+
| 约束 | 作用 | 示例 |
15+
|------|------|------|
16+
| `mut` | 账户会被修改 | `#[account(mut)]` |
17+
| `init` | 创建新账户 | `#[account(init, payer = user)]` |
18+
| `init_if_needed` | 如果不存在则创建 | `#[account(init_if_needed, payer = user)]` |
19+
| `close` | 关闭账户并返还租金 | `#[account(close = authority)]` |
20+
21+
### 2. PDA (Program Derived Address) 约束
22+
23+
| 约束 | 作用 | 示例 |
24+
|------|------|------|
25+
| `seeds` | 定义PDA种子 | `seeds = [b"offer", user.key().as_ref()]` |
26+
| `bump` | 自动生成bump seed | `bump` |
27+
| `has_one` | 验证账户关系 | `has_one = user` |
28+
29+
### 3. 代币账户约束
30+
31+
| 约束 | 作用 | 示例 |
32+
|------|------|------|
33+
| `mint::token_program` | 指定代币程序 | `mint::token_program = token_program` |
34+
| `associated_token::mint` | 关联代币类型 | `associated_token::mint = token_mint` |
35+
| `associated_token::authority` | 关联代币权限 | `associated_token::authority = user` |
36+
| `associated_token::token_program` | 关联代币程序 | `associated_token::token_program = token_program` |
37+
38+
### 4. 账户类型
39+
40+
| 类型 | 作用 | 示例 |
41+
|------|------|------|
42+
| `Signer<'info>` | 需要签名的账户 | `pub user: Signer<'info>` |
43+
| `Account<'info, T>` | 自定义账户类型 | `pub offer: Account<'info, Offer>` |
44+
| `InterfaceAccount<'info, T>` | SPL代币账户 | `pub token_account: InterfaceAccount<'info, TokenAccount>` |
45+
| `SystemAccount<'info>` | 系统账户 | `pub user: SystemAccount<'info>` |
46+
| `Program<'info, T>` | 程序账户 | `pub system_program: Program<'info, System>` |
47+
| `Interface<'info, T>` | 程序接口 | `pub token_program: Interface<'info, TokenInterface>` |
48+
49+
## 常见模式模板
50+
51+
### 1. 创建新账户模式
52+
53+
```rust
54+
#[account(
55+
init,
56+
payer = user,
57+
space = ANCHOR_DISCRIMINATOR + MyStruct::INIT_SPACE,
58+
seeds = [b"my_seed", user.key().as_ref()],
59+
bump
60+
)]
61+
pub my_account: Account<'info, MyStruct>,
62+
```
63+
64+
### 2. 代币账户模式
65+
66+
```rust
67+
#[account(
68+
mut,
69+
associated_token::mint = token_mint,
70+
associated_token::authority = user,
71+
associated_token::token_program = token_program
72+
)]
73+
pub user_token_account: InterfaceAccount<'info, TokenAccount>,
74+
```
75+
76+
### 3. 创建代币账户模式
77+
78+
```rust
79+
#[account(
80+
init,
81+
payer = user,
82+
associated_token::mint = token_mint,
83+
associated_token::authority = user,
84+
associated_token::token_program = token_program
85+
)]
86+
pub new_token_account: InterfaceAccount<'info, TokenAccount>,
87+
```
88+
89+
### 4. 关闭账户模式
90+
91+
```rust
92+
#[account(
93+
mut,
94+
close = user,
95+
has_one = user,
96+
seeds = [b"my_seed", user.key().as_ref()],
97+
bump = my_account.bump
98+
)]
99+
pub my_account: Account<'info, MyStruct>,
100+
```
101+
102+
## 常见错误和解决方案
103+
104+
### 1. 忘记添加 `mut`
105+
```rust
106+
// ❌ 错误:账户会被修改但没有mut
107+
#[account]
108+
pub token_account: InterfaceAccount<'info, TokenAccount>,
109+
110+
// ✅ 正确
111+
#[account(mut)]
112+
pub token_account: InterfaceAccount<'info, TokenAccount>,
113+
```
114+
115+
### 2. 忘记指定 `payer`
116+
```rust
117+
// ❌ 错误:创建账户但没有指定谁支付
118+
#[account(init)]
119+
pub new_account: Account<'info, MyStruct>,
120+
121+
// ✅ 正确
122+
#[account(init, payer = user)]
123+
pub new_account: Account<'info, MyStruct>,
124+
```
125+
126+
### 3. 忘记添加必要的程序账户
127+
```rust
128+
// ❌ 错误:创建账户但没有system_program
129+
#[account(init, payer = user)]
130+
pub new_account: Account<'info, MyStruct>,
131+
132+
// ✅ 正确
133+
#[account(init, payer = user)]
134+
pub new_account: Account<'info, MyStruct>,
135+
pub system_program: Program<'info, System>,
136+
```
137+
138+
## 开发建议
139+
140+
### 1. 使用代码片段
141+
创建IDE代码片段来快速生成常用模式:
142+
143+
```rust
144+
// 创建新账户的代码片段
145+
#[account(
146+
init,
147+
payer = $1,
148+
space = ANCHOR_DISCRIMINATOR + $2::INIT_SPACE,
149+
seeds = [b"$3", $1.key().as_ref()],
150+
bump
151+
)]
152+
pub $4: Account<'info, $2>,
153+
```
154+
155+
### 2. 使用模板项目
156+
维护一个包含常用模式的模板项目,需要时复制粘贴。
157+
158+
### 3. 使用AI辅助
159+
如你所说,让AI生成这些样板代码,然后根据需要修改。
160+
161+
### 4. 创建自己的速查表
162+
根据项目需求,创建个性化的速查表。
163+
164+
## 为什么这么复杂?
165+
166+
1. **Solana的账户模型**:每个操作都需要明确指定所有账户
167+
2. **安全性要求**:需要验证账户关系和权限
168+
3. **类型安全**:在编译时确保正确性
169+
4. **自动化**:减少运行时错误
170+
171+
## 改进建议
172+
173+
1. **更好的文档**:Anchor团队应该提供更清晰的速查表
174+
2. **IDE支持**:更好的代码补全和错误提示
175+
3. **代码生成工具**:自动生成常用模式
176+
4. **简化API**:减少样板代码的需求
177+
178+
## 结论
179+
180+
你的观察很准确:Anchor的宏和约束确实太多,难以记忆。这确实是框架的一个问题,需要:
181+
- 更好的文档和速查表
182+
- 更多的代码生成工具
183+
- 更好的IDE支持
184+
- 简化的API设计
185+
186+
对于开发者来说,最好的策略是:
187+
1. 创建自己的速查表
188+
2. 使用代码片段
189+
3. 维护模板项目
190+
4. 利用AI辅助生成

project-7-swap/programs/swap/src/instructions/make_offer.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,35 @@ use super::transfer_tokens;
1111
#[derive(Accounts)]
1212
#[instruction(id: u64)]
1313
pub struct MakeOffer<'info> {
14+
// 创建交易的用户(出价者)
1415
#[account(mut)]
1516
pub maker: Signer<'info>,
1617

18+
/*
19+
作用: 用户要提供的代币A的铸币账户
20+
类型: Mint 表示这是一个代币的铸币账户
21+
用途: 定义代币A的类型(比如USDC、SOL等)
22+
*/
1723
#[account(mint::token_program = token_program)]
1824
pub token_mint_a: InterfaceAccount<'info, Mint>,
1925

26+
/*
27+
作用: 用户想要的代币B的铸币账户
28+
类型: Mint 表示这是一个代币的铸币账户
29+
用途: 定义代币B的类型(用户想要换取的代币)
30+
*/
2031
#[account(mint::token_program = token_program)]
2132
pub token_mint_b: InterfaceAccount<'info, Mint>,
2233

34+
/*
35+
作用: 用户拥有的代币A的账户
36+
类型: TokenAccount 表示这是一个代币账户
37+
约束:
38+
mut 表示会被修改(转出代币)
39+
associated_token::mint = token_mint_a 确保是代币A的账户
40+
associated_token::authority = maker 确保是用户的账户
41+
用途: 用户从这里转出代币A到vault
42+
*/
2343
#[account(
2444
mut,
2545
associated_token::mint = token_mint_a,
@@ -28,6 +48,16 @@ pub struct MakeOffer<'info> {
2848
)]
2949
pub maker_token_account_a: InterfaceAccount<'info, TokenAccount>,
3050

51+
/*
52+
作用: 存储交易信息的账户
53+
类型: Offer 自定义结构体
54+
约束:
55+
init 表示这是一个新创建的账户
56+
payer = maker 表示用户支付创建费用
57+
seeds 定义PDA(Program Derived Address)的种子
58+
bump 自动生成bump seed
59+
用途: 记录交易的所有信息(ID、用户、代币类型、数量等)
60+
*/
3161
#[account(
3262
init,
3363
payer = maker,
@@ -37,6 +67,16 @@ pub struct MakeOffer<'info> {
3767
)]
3868
pub offer: Account<'info, Offer>,
3969

70+
/*
71+
作用: 托管代币A的保险库账户
72+
类型: TokenAccount 表示这是一个代币账户
73+
约束:
74+
init 表示这是一个新创建的账户
75+
payer = maker 表示用户支付创建费用
76+
associated_token::mint = token_mint_a 确保是代币A的账户
77+
associated_token::authority = offer 以offer账户为权限
78+
用途: 临时存储用户提供的代币A,等待其他用户接受交易
79+
*/
4080
#[account(
4181
init,
4282
payer = maker,
@@ -46,8 +86,17 @@ pub struct MakeOffer<'info> {
4686
)]
4787
pub vault: InterfaceAccount<'info, TokenAccount>,
4888

89+
// 用途: 用于创建新账户(offer和vault账户)
4990
pub system_program: Program<'info, System>,
91+
/*
92+
作用: SPL Token程序接口
93+
用途: 用于代币转账操作
94+
*/
5095
pub token_program: Interface<'info, TokenInterface>,
96+
/*
97+
作用: 关联代币账户程序
98+
用途: 用于创建关联代币账户(vault账户)
99+
*/
51100
pub associated_token_program: Program<'info, AssociatedToken>,
52101
}
53102

0 commit comments

Comments
 (0)