<aside> 💡
anchor中的account哪些在ctx中要被声明mut?比如是ata_a给ata_b转账,那么ata_b要声明为mut么? 如果是account A给account B转SOL,account A和account B需要时mut么?
</aside>
在 Anchor 中,#[account(mut)] 的使用决定了哪些账户在指令执行期间需要被标记为可写(is_writable = true)。是否需要声明 mut 取决于账户在交易中是否会被修改,而这通常由具体的程序逻辑和底层 Solana 运行时规则决定。以下我会针对你提到的两种情况(ATA 转账和 SOL 转账)逐一分析,并总结 Anchor 中 mut 的使用规则。
情况 1:ATA_A 给 ATA_B 转账
假设你的程序通过 SPL Token 程序从 ata_a(源代币账户)向 ata_b(目标代币账户)转移代币,典型场景如下:
rust
use anchor_lang::prelude::*;
use anchor_spl::token::{self, Token, TokenAccount, Transfer};
#[program]
pub mod my_program {
use super::*;
pub fn transfer_tokens(ctx: Context<TransferTokens>, amount: u64) -> Result<()> {
let cpi_accounts = Transfer {
from: ctx.accounts.ata_a.to_account_info(),
to: ctx.accounts.ata_b.to_account_info(),
authority: ctx.accounts.authority.to_account_info(),
};
let cpi_ctx = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
cpi_accounts,
);
token::transfer(cpi_ctx, amount)?;
Ok(())
}
}
#[derive(Accounts)]
pub struct TransferTokens<'info> {
#[account(mut)]
pub ata_a: Account<'info, TokenAccount>, // 源代币账户
#[account(mut)]
pub ata_b: Account<'info, TokenAccount>, // 目标代币账户
pub authority: Signer<'info>, // ata_a 的授权者(可能是用户或 PDA)
pub token_program: Program<'info, Token>,
}
哪些账户需要声明为 mut?
小结
在 ATA_A 给 ATA_B 转账的场景中:
情况 2:Account A 给 Account B 转 SOL
假设你的程序通过 system_instruction::transfer 从 account_a(源账户)向 account_b(目标账户)转移 SOL,典型场景如下:
rust