在 Solana Anchor 框架内初始化 PDA 的正确方法
Proper way to initialize PDAs within the Solana Anchor framework
我正在尝试使用 Rust/Anchor 编写一个简单的 Solana 程序,该程序使用 PDA,但是当我尝试调用它时出现 CPI 错误,即使没有发生 CPI(可能是 PDA 帐户)初始化?)。
程序代码如下:
use anchor_lang::prelude::*;
declare_id!("51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p");
#[program]
pub mod solana_sandbox {
use super::*;
pub fn initialize(ctx: Context<Initialize>, bump: u8) -> ProgramResult {
ctx.accounts.sandbox_account.bump = bump;
Ok(())
}
}
#[derive(Accounts)]
#[instruction(bump: u8)]
pub struct Initialize<'info> {
#[account(mut)]
pub signer: Signer<'info>,
#[account(
init,
seeds = [b"seed".as_ref()],
bump,
payer = signer,
)]
pub sandbox_account: Account<'info, SandboxAccount>,
pub system_program: Program<'info, System>,
}
#[account]
#[derive(Default)]
pub struct SandboxAccount {
pub bump: u8,
}
客户端代码如下:
const [sandboxPda, sandboxBump] = await PublicKey.findProgramAddress([Buffer.from('seed')], SystemProgram.programId);
await program.rpc.initialize(
sandboxBump,
{
accounts: {
signer: keypair.publicKey,
sandboxAccount: sandboxPda,
systemProgram: anchor.web3.SystemProgram.programId,
},
signers: [keypair],
instructions: []
});
当我 运行 以上时,我得到以下信息:
Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account
Program 51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p invoke [1]
8ZiyjNgnFFPyw39NyMQE5FGETTjyUhSHUVQG3oKAFZiU's signer privilege escalated
Program 51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p consumed 200000 of 200000 compute units
Program 51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p failed: Cross-program invocation with unauthorized signer or writable account
8ZiyjNgnFFPyw39NyMQE5FGETTjyUhSHUVQG3oKAFZiU
是我传入的PDA地址,我用的是anchor-cli 0.18.0
.
原来我是使用系统程序 ID 在我的客户端代码中派生 PDA,而不是使用我的实际程序 ID。
应该是:
const [sandboxPda, sandboxBump] = await PublicKey.findProgramAddress([Buffer.from('seed')], <PROGRAM_ID>);
我正在尝试使用 Rust/Anchor 编写一个简单的 Solana 程序,该程序使用 PDA,但是当我尝试调用它时出现 CPI 错误,即使没有发生 CPI(可能是 PDA 帐户)初始化?)。
程序代码如下:
use anchor_lang::prelude::*;
declare_id!("51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p");
#[program]
pub mod solana_sandbox {
use super::*;
pub fn initialize(ctx: Context<Initialize>, bump: u8) -> ProgramResult {
ctx.accounts.sandbox_account.bump = bump;
Ok(())
}
}
#[derive(Accounts)]
#[instruction(bump: u8)]
pub struct Initialize<'info> {
#[account(mut)]
pub signer: Signer<'info>,
#[account(
init,
seeds = [b"seed".as_ref()],
bump,
payer = signer,
)]
pub sandbox_account: Account<'info, SandboxAccount>,
pub system_program: Program<'info, System>,
}
#[account]
#[derive(Default)]
pub struct SandboxAccount {
pub bump: u8,
}
客户端代码如下:
const [sandboxPda, sandboxBump] = await PublicKey.findProgramAddress([Buffer.from('seed')], SystemProgram.programId);
await program.rpc.initialize(
sandboxBump,
{
accounts: {
signer: keypair.publicKey,
sandboxAccount: sandboxPda,
systemProgram: anchor.web3.SystemProgram.programId,
},
signers: [keypair],
instructions: []
});
当我 运行 以上时,我得到以下信息:
Transaction simulation failed: Error processing Instruction 0: Cross-program invocation with unauthorized signer or writable account
Program 51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p invoke [1]
8ZiyjNgnFFPyw39NyMQE5FGETTjyUhSHUVQG3oKAFZiU's signer privilege escalated
Program 51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p consumed 200000 of 200000 compute units
Program 51v31qHaEQniLoYuvvtXByZcfiyvog3R2EKC39EPD52p failed: Cross-program invocation with unauthorized signer or writable account
8ZiyjNgnFFPyw39NyMQE5FGETTjyUhSHUVQG3oKAFZiU
是我传入的PDA地址,我用的是anchor-cli 0.18.0
.
原来我是使用系统程序 ID 在我的客户端代码中派生 PDA,而不是使用我的实际程序 ID。
应该是:
const [sandboxPda, sandboxBump] = await PublicKey.findProgramAddress([Buffer.from('seed')], <PROGRAM_ID>);