锚点中 pda 初始化时碰撞的目的

Purpose of the bump when pda initialization in anchor

我正在尝试使用使用 PDA 的 Rust/Anchor 编写一个简单的 Solana 程序。

程序代码如下:

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')], this.program.programId);

  await program.rpc.initialize(
    sandboxBump,
    {
      accounts: {
        signer: keypair.publicKey,
        sandboxAccount: sandboxPda,
        systemProgram: anchor.web3.SystemProgram.programId,
      },
      signers: [keypair],
      instructions: []
    });

它工作正常,但我有疑问。我从 findProgramAddress 获取 sandboxBump 并输入它,但它没有被使用。

如果我像这样在初始化时设置颠簸:

#[account(
  init,
  seeds = [b"seed".as_ref()],
  bump = bump,
  payer = signer,
)]

发生错误。所以我从程序代码中删除了指令宏,但它仍然可以正常工作。 那么pda初始化的时候是不需要bump值还是anchor系统会自动使用呢?

感谢任何帮助!

为了增强安全性,Solana 确保所有程序地址都不会位于 ed25519 curve 上。由于地址不在曲线上,因此不会有关联的私钥,因此没有风险。

为了生成程序地址,solana 使用 256 位 pre-image 抗散列函数,使用种子集合和程序 ID 作为输入,因为它的输出无法提前预测,也无法控制无论如何,新生成的地址有 50% 的机会位于 ed25519 曲线上。在这种情况下,生成的地址在曲线上,这是 solana 禁止的。 Solana 将使用一组不同的种子或种子凸块来找到有效地址(曲线外的地址)。

简而言之,bump 仅在提供的输入未生成有效程序地址的情况下使用。

Program addresses are deterministically derived from a collection of seeds and a program id using a 256-bit pre-image resistant hash function. Program address must not lie on the ed25519 curve to ensure there is no associated private key. During generation, an error will be returned if the address is found to lie on the curve. There is about a 50/50 chance of this happening for a given collection of seeds and program id. If this occurs a different set of seeds or a seed bump (additional 8 bit seed) can be used to find a valid program address off the curve.

参考文献:

PDA 用于在 Solana 中签署交易。当你签署交易时,你需要有一个密钥来证明你拥有相关地址。但是对于持有私钥的程序来说并不理想,因为程序存在 on-chain,每个人都可以查看 on-chain。所以存储私钥 on-chain 不是一个好主意,因为其他人都可以窃取私钥。这就是我们需要那些 PDA 的原因。因为有了 Pda,程序可以证明它被允许签署交易。你什么时候需要PDA?假设你有一个代币库,你想从那个库中发送一些代币到另一个地址。该程序可以通过使用种子和碰撞种子和系统程序 ID 进行签名来批准这一点,以告诉系统程序传输 sol。

  • 我们实际上正在寻找一个 PUBLIC 无法从秘密密钥派生的密钥

  • PDA 确保没有外部用户也可以为同一地址生成有效签名

我们的掌上电脑不应该在椭圆曲线上。如果是,那么我们使用 bump seeds。所以我们的智能合约会尝试最多 20 次,每次都使用新的 bump 种子来创建一个唯一的哈希值。

它从 bump = 255 开始,然后简单地向下迭代 bump = 254、bump = 253 等,直到我们得到一个不在椭圆曲线上的地址。 T