8 Anchor
- 1 min问题:Anchor 使用宏和特征为你生成样板 Rust 代码,主要的高级宏和属性有哪些?
答案:
- declare_id - 用于声明程序的链上地址的宏
- #[program] - 用于表示包含程序指令逻辑的模块的属性宏
- Accounts - 应用于表示指令所需账户列表的结构体的特性
- #[account] - 用于为程序定义自定义账户类型的属性宏
问题:
Anchor 中的 declare_id 宏用于指定什么内容?
答案:
declare_id 宏用于指定程序的链上地址(即 programId)。
问题:
在 Anchor 中,#[program] 属性宏定义了什么内容?
答案:
#[program] 属性宏定义了包含程序所有指令的模块,即为程序中每个指令实现业务逻辑的地方。
问题:
在 Anchor 中,Context 类型的泛型类型 T 定义了什么内容?指令可以通过 Context 参数访问哪些内容?
答案:
在 Anchor 中,Context 类型的泛型类型 T 定义了指令需要的账户列表。指令可以通过 Context 参数访问以下内容:
- 执行程序的程序 ID(ctx.program_id)
- 传递给指令的账户(ctx.accounts)
- 剩余账户(ctx.remaining_accounts)
- Accounts 结构中任何 PDA 账户的 bump(ctx.bumps)
问题:
在 Anchor 中,Accounts 特征的作用是什么?如何使用 derive 宏来应用 Accounts 特征?
答案:
Accounts 特征定义了一个经过验证的账户数据结构,用于定义给定指令所需的账户列表。通过 derive 宏(例如 #[derive(Accounts)]),可以应用 Accounts 特征,在给定的结构体上实现一个 Accounts 反序列化器,消除了手动反序列化每个账户的需要。
问题:
在 Anchor 中,Account 类型的作用是什么?它是如何验证账户的所有权的?
答案:
在 Anchor 中,Account 类型是围绕着 AccountInfo 的一个包装器(wrapper),用于验证账户的所有权。它验证账户是否为程序自定义的合约,并将底层数据反序列化为 Rust 类型。
问题:
在 Anchor 中,Signer 类型的作用是什么?在何种情况下应该使用 Signer 类型?
答案:
在 Anchor 中,Signer 类型用于验证给定的账户是否对交易进行了签名,不执行其他所有权或类型检查。应该只在指令中不需要底层账户数据时使用 Signer。
对于前面示例中的 user 账户,Signer 类型指定了 user 账户必须是指令的签名者。
问题:
在 Anchor 中,Program 类型的作用是什么?在何种情况下应该使用 Program 类型?
答案:
在 Anchor 中,Program 类型用于验证账户是否是某个特定程序。应该使用 Program 类型来指定特定程序的身份。
对于前面示例中的 system_program 账户,Program 类型用于指定该程序应该是系统程序。Anchor 提供了一个 System 类型,其中包括要检查的系统程序的 programId。
问题:
在 Anchor 中的 #[account(..)] 属性宏用于做什么?请说明在示例中的每个约束值的作用。
答案:
在 Anchor 中,#[account(..)] 属性宏用于对账户应用约束。在示例中,每个约束值的作用如下:
- init - 通过对系统程序执行 CPI 来创建账户并初始化它,设置账户辨别器。
- payer - 指定账户初始化的付款人为结构体中定义的 user 账户。
- space - 指定为账户分配的空间应为 8 + 8 字节,其中前 8 字节用于辨别器,接下来的 8 字节为账户存储的数据分配空间。
对于 user 账户,使用 #[account(mut)] 属性来指定该账户是可变的。这是因为将从该账户中扣除 lamports 以支付 account_name 的初始化。
#[account]
问题:
在 Anchor 中的 #[account] 属性具有什么作用?它实现了哪些特征?辨别器的作用是什么?
答案:
- 实现了序列化
- 实现了辨别器
- 实现了所有者
在 Anchor 中,#[account] 属性用于表示 Solana 账户数据结构的结构体,实现了以下特征:
- AccountSerialize
- AccountDeserialize
- AnchorSerialize
- AnchorDeserialize
- Clone
- Discriminator
- Owner
辨别器
辨别器是一个 8 字节的唯一标识符,用于表示账户类型
没有这个就无法序列化
所有者
使用 #[account] 属性定义的账户类型初始化的所有账户也都归程序所有。
#[account] 属性还为使用 declareId 声明的 programId 实现了 Owner 特性。