pubfncreate_program_address( seeds: &[&[u8]], program_id: &Pubkey, ) -> Result<Pubkey, PubkeyError> { if seeds.len() > MAX_SEEDS { // 种子最多有 16 个 returnErr(PubkeyError::MaxSeedLengthExceeded); } for seed in seeds.iter() { if seed.len() > MAX_SEED_LEN { // 每个种子最长 32 returnErr(PubkeyError::MaxSeedLengthExceeded); } }
// Perform the calculation inline, calling this from within a program is // not supported #[cfg(not(target_os = "solana"))] { letmut hasher = crate::hash::Hasher::default(); // 就是一个 Sha256 for seed in seeds.iter() { hasher.hash(seed); } // PDA_MARKER 是一个 21 字节长的字符串 // const PDA_MARKER: &[u8; 21] = b"ProgramDerivedAddress"; hasher.hashv(&[program_id.as_ref(), PDA_MARKER]); let hash = hasher.result();
if bytes_are_curve_point(hash) { // PDA 账户需要确保不在爱德华曲线上 returnErr(PubkeyError::InvalidSeeds); }
Ok(Pubkey::from(hash.to_bytes())) } // Call via a system call to perform the calculation #[cfg(target_os = "solana")] { letmut bytes = [0; 32]; let result = unsafe { crate::syscalls::sol_create_program_address( seeds as *const _ as *constu8, seeds.len() asu64, program_id as *const _ as *constu8, &mut bytes as *mut _ as *mutu8, ) }; match result { crate::entrypoint::SUCCESS => Ok(Pubkey::from(bytes)), _ => Err(result.into()), } } }