浏览代码

Add create_with_seed (#161)

* Add create_with_seed

* Add PDA_MARKER check

* rename owner to program_id, some nits
Stanislav Ladyzhenskiy 3 月之前
父节点
当前提交
9be19b9f65
共有 1 个文件被更改,包括 40 次插入0 次删除
  1. 40 0
      sdk/pinocchio/src/pubkey.rs

+ 40 - 0
sdk/pinocchio/src/pubkey.rs

@@ -237,3 +237,43 @@ pub fn checked_create_program_address(
 
     create_program_address(seeds, program_id)
 }
+
+/// Derive a Pubkey from another Pubkey, seed, and a program id.
+#[inline]
+pub fn create_with_seed(
+    base: &Pubkey,
+    seed: &[u8],
+    program_id: &Pubkey,
+) -> Result<Pubkey, ProgramError> {
+    if seed.len() > MAX_SEED_LEN {
+        return Err(ProgramError::MaxSeedLengthExceeded);
+    }
+
+    if program_id.ends_with(PDA_MARKER) {
+        return Err(ProgramError::IllegalOwner);
+    }
+
+    #[cfg(target_os = "solana")]
+    {
+        let mut bytes = core::mem::MaybeUninit::<[u8; PUBKEY_BYTES]>::uninit();
+
+        let vals = &[base, seed, program_id];
+
+        unsafe {
+            crate::syscalls::sol_sha256(
+                vals as *const _ as *const u8,
+                vals.len() as u64,
+                bytes.as_mut_ptr() as *mut _,
+            );
+        }
+
+        // SAFETY: The syscall has initialized the bytes.
+        Ok(unsafe { bytes.assume_init() })
+    }
+
+    #[cfg(not(target_os = "solana"))]
+    {
+        core::hint::black_box((base, seed, program_id));
+        panic!("create_with_seed is only available on target `solana`")
+    }
+}