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

Anchor与传统代币转账签名权限报错原因咨询

问题原因及修复方案

核心错误点

  1. PDA种子不匹配
    传统方法里生成PDA用的是sender_account.key.to_bytes()作为种子,但Anchor代码里错误换成了vault.key.to_bytes()。这会导致你签名用的PDA和实际需要授权的PDA不是同一个,SPL Token程序自然不认这个签名,直接抛出权限错误。

  2. CPI调用的目标程序错了
    token_transfer是SPL Token程序的指令,但你在Anchor的CpiContext里传的是system_program,不是token_program。跨程序调用找错了目标程序,权限校验肯定过不了。

  3. 签名逻辑和授权方不匹配
    传统方法明确指定了授权方是vault.key,同时用对应正确的PDA种子签名;但Anchor这边种子写错、程序传错,导致整个签名逻辑完全偏离,SPL Token程序无法识别合法的签名者。

修正后的Anchor代码

let (_account_address, bump) = Pubkey::find_program_address(
    &[&ctx.accounts.sender_account.key.to_bytes()], 
    ctx.program_id
);

// 修正PDA种子,和find_program_address的参数保持一致
let pda_signer_seeds: &[&[&[_]]] = &[&[&ctx.accounts.sender_account.key.to_bytes(), &[bump]]];

let transfer_ix = Token_Transfer{
    from: ctx.accounts.vault_associated_info.to_account_info(),
    to: ctx.accounts.receiver_associated_info.to_account_info(),
    authority: ctx.accounts.vault.to_account_info()
};

// 修正CPI上下文,传入token_program而非system_program
let cpi_ctx = CpiContext::new_with_signer(
    ctx.accounts.token_program.to_account_info(),
    transfer_ix,
    pda_signer_seeds,
);

token_transfer(cpi_ctx, amount)?;

补充说明

你用receiver_account当签名者时出错,是因为实际需要的签名者是程序派生的PDA,receiver_account根本不是这个PDA的合法签名主体;改用vault_account能解决可能是巧合,但本质上正确的做法是确保PDA种子、签名逻辑、CPI调用的程序三者完全匹配。

内容的提问来源于stack exchange,提问作者Roshan Shrestha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 01:36:25