LogoAnchor 中文文档

程序派生地址 PDA

学习如何在 Anchor 程序中使用 Program Derived Addresses (PDA) 来创建确定性账户地址。

Program Derived Addresses (PDA) 是 Solana 开发中的一项功能,它允许你从预定义的输入(种子)和程序 ID 确定性地生成一个唯一的地址。

本节将介绍如何在 Anchor 程序中使用 PDA 的基本示例。

Anchor PDA 约束

在 Anchor 程序中使用 PDA 时,通常使用 Anchor 的账户约束来定义生成 PDA 的种子。这些约束充当安全检查,以确保生成正确的地址。

用于定义 PDA 种子的约束包括:

  • seeds:用于生成 PDA 的可选种子数组。种子可以是静态值或对账户数据的动态引用。
  • bump:用于生成 PDA 的 bump seed。用于确保地址远离 Ed25519 曲线,并且是一个有效的 PDA。
  • seeds::program -(可选)用于生成 PDA 地址的程序 ID。此约束仅在程序 ID 不是当前程序时使用。

seedsbump 约束必须一起使用。

使用示例

以下是演示如何在 Anchor 程序中使用 PDA 约束的示例。

seeds 约束指定了用于生成 PDA 的可选值。

无可选种子

  • 使用空数组 [] 来定义没有可选种子的 PDA。
#[derive(Accounts)]
pub struct InstructionAccounts<'info> {
    #[account(

        seeds = [],
        bump,
    )]
    pub pda_account: SystemAccount<'info>,
}

单个静态种子

  • seeds 约束中指定可选种子。
#[derive(Accounts)]
pub struct InstructionAccounts<'info> {
    #[account(


        seeds = [b"hello_world"],
        bump,
    )]
    pub pda_account: SystemAccount<'info>,
}

多个种子和账户引用

  • 可以在 seeds 约束中指定多个种子。seeds 约束还可以引用其他账户地址或账户数据。
#[derive(Accounts)]
pub struct InstructionAccounts<'info> {
    pub signer: Signer<'info>,
    #[account(

        seeds = [b"hello_world", signer.key().as_ref()],
        bump,
    )]
    pub pda_account: SystemAccount<'info>,
}

上面的示例同时使用了一个静态种子 (b"hello_world") 和一个动态种子(签名者的公钥)。

IDL 中的 PDA 种子

seeds 约束中定义的 Program Derived Address (PDA) 种子包含在程序的 IDL 文件中。这使得 Anchor 客户端在构建指令时能够自动使用这些种子解析账户地址。

下面的示例展示了程序、IDL 和客户端之间的关系。

下面的程序使用静态种子 (b"hello_world") 和签名者的公钥作为动态种子来定义 pda_account

use anchor_lang::prelude::*;
 
declare_id!("BZLiJ62bzRryYp9mRobz47uA66WDgtfTXhhgM25tJyx5");
 
#[program]
mod hello_anchor {
    use super::*;
    pub fn test_instruction(ctx: Context<InstructionAccounts>) -> Result<()> {
        msg!("PDA: {}", ctx.accounts.pda_account.key());
        Ok(())
    }
}
 
#[derive(Accounts)]
pub struct InstructionAccounts<'info> {

    pub signer: Signer<'info>,
    #[account(

        seeds = [b"hello_world", signer.key().as_ref()],
        bump,
    )]
    pub pda_account: SystemAccount<'info>,
}

On this page

在GitHub上编辑