You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用户向Solana Anchor程序发送SPL Tokens时能否直接销毁?

SPL代币销毁流程:直接销毁 vs 先转PDA?

核心结论:不需要先把代币转到程序PDA,只要满足权限和账户要求,就能直接销毁用户发送过来的代币。

关键逻辑澄清

很多指南提到“程序先拥有代币才能销毁”,其实指的是程序需要拥有代币mint账户的销毁授权权限(即作为mint的authorized_burn),而非必须持有代币本身。代币可以直接在用户的ATA账户内销毁,只要用户授权本次操作,且程序具备销毁权限。

实现步骤与要求

要完成“用户发SPL代币→程序销毁→返回SOL”的流程,你的Anchor函数需要满足以下条件:

  1. 传入必要账户:

    • 用户钱包账户(签名者)
    • 用户的SPL代币ATA账户(要销毁的代币所在账户,需用户授权)
    • 代币mint账户(需已将authorized_burn设为程序PDA)
    • 程序的销毁授权PDA(作为mint的授权方,需签名)
    • 程序的SOL金库账户(用来给用户转SOL,需有足够余额)
    • Token程序、System程序账户
  2. 核心操作流程:

    • 调用Token程序的burn指令,传入上述账户并指定销毁数量(注意PDA签名需用invoke_signed)
    • 按预设比例从SOL金库转对应数量的SOL到用户钱包

示例代码片段

#[derive(Accounts)]
pub struct BurnAndRefundSol<'info> {
    #[account(mut)]
    pub user: Signer<'info>,
    #[account(mut, has_one = user)]
    pub user_token_account: Account<'info, TokenAccount>,
    pub mint: Account<'info, Mint>,
    /// CHECK: 程序销毁授权PDA,需为mint的authorized_burn
    #[account(
        seeds = [b"burn_authority"],
        bump,
    )]
    pub burn_authority: AccountInfo<'info>,
    #[account(mut)]
    pub program_sol_vault: AccountInfo<'info>, // 程序SOL金库账户
    pub token_program: Program<'info, Token>,
    pub system_program: Program<'info, System>,
}

pub fn handler(ctx: Context<BurnAndRefundSol>, token_amount: u64) -> Result<()> {
    // 销毁用户ATA内的代币
    let burn_cpi = CpiContext::new(
        ctx.accounts.token_program.to_account_info(),
        Burn {
            mint: ctx.accounts.mint.to_account_info(),
            from: ctx.accounts.user_token_account.to_account_info(),
            authority: ctx.accounts.burn_authority.to_account_info(),
        },
    );
    token::burn(
        burn_cpi.with_signer(&[&[b"burn_authority", &[ctx.bumps.burn_authority]]]),
        token_amount
    )?;

    // 计算兑换的SOL数量(替换为你的兑换逻辑)
    let sol_amount = token_amount / 100; 
    // 向用户转账SOL
    system_program::transfer(
        CpiContext::new(
            ctx.accounts.system_program.to_account_info(),
            system_program::Transfer {
                from: ctx.accounts.program_sol_vault.to_account_info(),
                to: ctx.accounts.user.to_account_info(),
            },
        ),
        sol_amount
    )?;

    Ok(())
}

注意事项

  • 确保代币mint账户的authorized_burn字段已设置为你的程序PDA,否则销毁指令会报错
  • 用户的ATA账户需通过签名授权销毁操作(示例中通过has_one = user关联用户签名)
  • SOL金库建议使用专门的PDA管理,避免程序主账户余额不足影响转账

内容的提问来源于stack exchange,提问作者Robert Grospitch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 04:42:09