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

Solana Anchor初始化数据账户时遇越权跨程序调用错误求助

解决Solana Anchor初始化PDA时的“未授权签名者/可写账户”错误

错误核心原因

你遇到的问题根源在于客户端派生PDA时使用了错误的程序ID:调用PublicKey.findProgramAddress时,你传入了SystemProgram.programId,但PDA是由你的Anchor程序派生的,必须使用你自己的程序ID。这会导致实际创建的账户地址与程序预期的PDA不匹配,触发跨程序调用的权限校验失败。

你后续修改的InitData结构体添加了多余的handler字段,完全没必要,反而增加了复杂度。

修复步骤

1. 修正客户端PDA派生逻辑

将findProgramAddress的第二个参数替换为你的程序ID:

const [dataAccount,] = await PublicKey.findProgramAddress(
  [Buffer.from("data-account"), wallet.publicKey.toBuffer()],
  programId // 替换原SystemProgram.programId为你的程序ID
);

2. 还原Anchor程序的账户结构体(去掉多余字段)

你的原始InitData结构体是正确的,不需要额外添加handler:

#[derive(Accounts)]
pub struct InitData<'info> {
    #[account(
        init,
        payer = manager,
        space = 8 + 1,
        seeds = [b"data-account", manager.key().as_ref()],
        bump
    )]
    pub data_account: Account<'info, DummyData>,
    #[account(mut)]
    pub manager: Signer<'info>,
    pub system_program: Program<'info, System>,
}

3. 可选优化:将硬编码钱包地址改为常量

为避免代码中直接写入字符串形式的Pubkey,可提前定义常量:

// 替换为你的目标钱包地址对应的字节数组,或直接用Pubkey::from_str解析
const AUTHORIZED_MANAGER: Pubkey = Pubkey::new_from_array([
    0x2j, 0xef, 0x71, 0x6c, 0xfe, 0x17, 0x63, 0x4b, 0xed, 0x82, 0xb4, 0x53, 0x8b, 0xd9, 0x37, 0x49,
    0x61, 0x96, 0xe7, 0xab, 0x6e, 0x37, 0x2e, 0x9f, 0x1a, 0x4c, 0x7d, 0x8f, 0x5a, 0x3b, 0x7c, 0x2f
]);

impl<'info> Validate<'info> for InitData<'info> {
  fn validate(&self) -> Result<()> {
      assert_keys_eq!(self.manager, AUTHORIZED_MANAGER);
      Ok(())
  }
}

验证修复

  1. 重新执行anchor build和anchor deploy
  2. 运行客户端脚本,此时应能成功初始化数据账户

错误日志中的"7g32AFUNrTqyyuj1zbve6ui1aUzqzEvzpBc2tdNmqBjo's signer privilege escalated"提示,本质是因为用系统程序ID派生PDA后,系统程序被错误当作PDA的权威,而你的Anchor程序没有权限操作该账户,最终触发权限校验失败。

内容的提问来源于stack exchange,提问作者Andrii Kapinos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 18:45:41