[program][derive(Accounts)][account]这三者之间是怎么样的关系这三个宏是Anchor框架的核心,理清它们的关系是入门的关键。我们可以通过一个生动的比喻来理解:开发一个Anchor程序就像拍摄一部电影。下面我们详细拆解这个“电影剧组”的运
<!--StartFragment-->
这三个宏是 Anchor 框架的核心,理清它们的关系是入门的关键。我们可以通过一个生动的比喻来理解:开发一个 Anchor 程序就像拍摄一部电影。

下面我们详细拆解这个“电影剧组”的运作方式。
#[program]:剧本和导演它定义了程序的所有可执行指令,包含了“做什么”的业务逻辑。
mod)。initialize, increment)就是一个可以被外部调用的链上指令。它负责处理具体的计算、状态变更等核心逻辑。#[derive(Accounts)]:演员名单和进场规则它定义了执行某个特定指令时所需的所有账户的集合、验证规则和安全约束,规定了“用谁来做”以及“他们需要满足什么条件”。
struct)。每个指令都有自己专属的账户结构体,这是因为不同的指令需要操作不同的账户,有着不同的安全要求。#[account]:角色设定它用于定义自定义账户的数据结构,即这个账户在链上“存储什么”数据。
作用对象:一个结构体(struct)。
核心职责:
discriminator,用于在反序列化时唯一识别账户类型。让我们用经典的计数器程序片段,具体看它们如何协作:
定义数据结构(角色设定)
首先,我们用 #[account]定义计数器账户里要存什么数据。
#[account]
pub struct Counter {
pub count: u64, // 只有一个计数字段
}
定义指令的账户上下文(演员名单)
然后,为“初始化计数器”这个指令定义它需要的账户和规则。
#[derive(Accounts)]
pub struct Initialize<'info> {
#[account(init, payer = user, space = 8 + 8)] // 规则:创建新账户,用户付租金,分配空间
pub counter: Account<'info, Counter>, // 账户:一个Counter类型的账户
#[account(mut)]
pub user: Signer<'info>, // 账户:必须是交易的签名者
pub system_program: Program<'info, System>, // 账户:必须传入系统程序
}
实现指令逻辑(导演说“开机!”)
最后,在 #[program]下实现指令函数。Anchor会自动将账户验证和业务逻辑绑定。
#[program]
pub mod counter_program {
use super::*;
pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
// 开拍!这里可以安全地使用已经通过验证的账户
let counter = &mut ctx.accounts.counter; // 拿到counter账户
counter.count = 0; // 执行逻辑:设置初始值为0
Ok(())
}
}
#[program]中的指令函数通过 Context<T>依赖 特定的 #[derive(Accounts)]结构体(T)。而 #[derive(Accounts)]结构体中的 Account类型,又依赖于 #[account]定义的数据结构。#[account]管数据长什么样,#[derive(Accounts)]管需要哪些人(账户)并检查他们的资格,#[program]管具体做什么事。如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!