Skip to main content

solana-program-library

一些关于 GitHub - solana-labs/solana-program-library: A collection of Solana programs maintained by Solana Labs 的实现细节

Program Derived Addresses (PDAs) 派生规则

Solana Cookbook | PDAs

一般有两个函数负责 PDA 的生成计算:

solana_program::pubkey::Pubkey

  • pub fn find_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> (Pubkey, u8)
  • pub fn create_program_address(seeds: &[&[u8]], program_id: &Pubkey) -> Result<Pubkey, PubkeyError>

他们的参数是相同的,其中 seeds 是一个 u8 的双重数组,最终会全部 flat 后concat为一个 u8 vec作为 seed,program pubkey 也会以 u8 stream的形式进入 hash buffer中,但是有个 PDA_MARKER 的常量拼接在后面:

hasher.hashv(&[program_id.as_ref(), PDA_MARKER]);

关键问题是 find_program_address 必定会追加 1byte 的 bump 到 seed 末尾,这是由于在寻找 bump 时,是直接追加一个 std::u8::MAX 的 bump 到seed末尾然后看是否在曲线上,如果在,则 bump-- ,循环测试直到找到一个不在曲线上的地址。

所以 find_program_address 所产生的地址所使用的 seeds 长度必定等于原 seeds 长度+1 。因此这个函数永远不可能产生冲突的PDA。

ref code lines: https://vscode.dev/github/hubbleprotocol/scope/blob/masterf17d22bba15001f/solana-program-1.16.18/src/pubkey.rs#L498-L514