Solana Anchor框架PDA正确初始化及CPI报错问题排查
错误根因
你触发该错误的核心原因是客户端生成PDA时使用了错误的派生程序ID:
- 链上程序中
#[account(init)]约束派生PDA时,默认使用你的程序ID(也就是declare_id!中声明的地址)作为派生基准 - 客户端代码中调用
PublicKey.findProgramAddress时,第二个参数传的是SystemProgram.programId,生成的PDA归属于系统程序而非你的程序 - Anchor的
init约束会自动调用系统程序的创建账户CPI逻辑,该逻辑要求账户所有者程序(也就是你的程序)拥有该PDA的签名权限,不属于你的程序的PDA无法被你的程序签名,因此触发权限错误。
修复方案
只需要修改客户端生成PDA的代码,将派生程序ID替换为你自己的程序ID即可:
// 原错误代码:第二个参数为SystemProgram.programId // const [sandboxPda, sandboxBump] = await PublicKey.findProgramAddress([Buffer.from('seed')], SystemProgram.programId); // 修复后代码:使用你的程序ID作为PDA派生基准 const [sandboxPda, sandboxBump] = await PublicKey.findProgramAddress( [Buffer.from('seed')], program.programId // 也可直接硬写你declare_id中的地址:new PublicKey("51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p") );
可选优化
你当前使用的Anchor 0.18.0已支持自动推导PDA的bump值,无需手动从客户端传递bump,可简化代码:
- 移除
initialize方法的bump入参 - 移除
Initialize账户结构上方的#[instruction(bump: u8)]注解 - 客户端调用时无需再传递
sandboxBump参数
内容的提问来源于stack exchange,提问作者Kale
相关产品推荐
相关产品推荐

