Anchor中如何正确使用close_account关闭程序所属ATA
Anchor框架下关闭程序所属ATA的
destination参数说明 参数作用
Solana账户关闭的核心逻辑是回收账户占用的链上存储,被关闭账户创建时质押的租金豁免SOL余额,必须转入一个指定的接收账户,链上不允许账户关闭时残留SOL无归属销毁,这是SPL Token程序强制要求传入destination参数的原因。
该参数仅用于接收被关闭账户残留的SOL,和账户内存储的SPL代币余额无关。只要你已经把ATA内的代币全额转出、余额为0,就可以正常执行关闭,不会产生代币相关的异常。
各参数正确取值
你对另外两个参数的判断是准确的,三个参数的完整取值规则如下:
account:待关闭的、归属程序所有的关联代币账户,调用时必须标记为可写authority:对该ATA拥有操作权限的程序账户/程序派生PDA,调用CPI时需要传入对应签名种子完成PDA签名destination:用于接收ATA租金SOL的账户,没有归属限制,常规实践中直接传入本次交易的发起用户钱包地址即可,调用时必须标记为可写。
调用示例
首先在指令的账户校验段声明所需账户:
#[derive(Accounts)] pub struct CloseOwnedAta<'info> { /// CHECK: 账户校验由SPL Token程序负责 #[account(mut)] pub target_ata: AccountInfo<'info>, #[account(mut)] pub user: Signer<'info>, /// CHECK: 租金接收方校验由SPL Token程序负责 #[account(mut)] pub rent_receiver: AccountInfo<'info>, pub token_program: Program<'info, Token>, #[account(seeds = [b"your-authority-pda-seed"], bump)] pub program_authority: SystemAccount<'info>, }
指令逻辑中构造CPI调用:
// 组装PDA签名种子 let authority_seeds = &[b"your-authority-pda-seed".as_ref(), &[ctx.bumps.program_authority][..]]; let cpi_ctx = CpiContext::new( ctx.accounts.token_program.to_account_info(), CloseAccount { account: ctx.accounts.target_ata.to_account_info(), destination: ctx.accounts.rent_receiver.to_account_info(), authority: ctx.accounts.program_authority.to_account_info(), } ).with_signer(&[authority_seeds]); close_account(cpi_ctx)?;
注意:如果关闭时ATA内SPL代币余额不为0,SPL Token程序会直接抛出NonZeroBalance错误,你已经完成代币转出步骤,只要确认转账金额与ATA余额完全一致即可避免该问题。
内容的提问来源于stack exchange,提问作者leotron
相关产品推荐
相关产品推荐

