diff --git a/sdk/program/src/pubkey.rs b/sdk/program/src/pubkey.rs index 73571cba25..35a6a25eb3 100644 --- a/sdk/program/src/pubkey.rs +++ b/sdk/program/src/pubkey.rs @@ -223,7 +223,11 @@ impl Pubkey { /// derived in off-chain client programs, avoiding the compute cost of /// generating the address on-chain. The address may or may not then be /// verified by re-deriving it on-chain, depending on the requirements of - /// the program. + /// the program. This verification may be performed without the overhead of + /// re-searching for the bump key by using the [`create_program_address`] + /// function. + /// + /// [`create_program_address`]: Pubkey::create_program_address /// /// **Warning**: Because of the way the seeds are hashed there is a potential /// for program address collisions for the same program id. The seeds are @@ -482,17 +486,48 @@ impl Pubkey { } } - /// Create a valid [program derived address][pda] without a bump seed. + /// Create a valid [program derived address][pda] without searching for a bump seed. /// /// [pda]: https://docs.solana.com/developing/programming-model/calling-between-programs#program-derived-addresses /// - /// **Because this function does not create a bump seed, it may unpredictably - /// return an error and should not be used. It exists for backwards - /// compatibility reasons.** + /// Because this function does not create a bump seed, it may unpredictably + /// return an error for any given set of seeds and is not generally suitable + /// for creating program derived addresses. /// - /// See the documentation for [`find_program_address`] for a full description. + /// However, it can be used for efficiently verifying that a set of seeds plus + /// bump seed generated by [`find_program_address`] derives a particular + /// address as expected. See the example for details. + /// + /// See the documentation for [`find_program_address`] for a full description + /// of program derived addresses and bump seeds. /// /// [`find_program_address`]: Pubkey::find_program_address + /// + /// # Examples + /// + /// Creating a program derived address involves iteratively searching for a + /// bump seed for which the derived [`Pubkey`] does not lie on the ed25519 + /// curve. This search process is generally performed off-chain, with the + /// [`find_program_address`] function, after which the client passes the + /// bump seed to the program as instruction data. + /// + /// Depending on the application requirements, a program may wish to verify + /// that the set of seeds, plus the bump seed, do correctly generate an + /// expected address. + /// + /// The verification is performed by appending to the other seeds one + /// additional seed slice that contains the single `u8` bump seed, calling + /// `create_program_address`, checking that the return value is `Ok`, and + /// that the returned `Pubkey` has the expected value. + /// + /// ``` + /// # use solana_program::pubkey::Pubkey; + /// # let program_id = Pubkey::new_unique(); + /// let (expected_pda, bump_seed) = Pubkey::find_program_address(&[b"vault"], &program_id); + /// let actual_pda = Pubkey::create_program_address(&[b"vault", &[bump_seed]], &program_id)?; + /// assert_eq!(expected_pda, actual_pda); + /// # Ok::<(), anyhow::Error>(()) + /// ``` pub fn create_program_address( seeds: &[&[u8]], program_id: &Pubkey,