create_pda.rs 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. use crate::state::Favorites;
  2. use borsh::BorshSerialize;
  3. use solana_program::{
  4. account_info::{next_account_info, AccountInfo},
  5. entrypoint::ProgramResult,
  6. msg,
  7. program::invoke_signed,
  8. program_error::ProgramError,
  9. pubkey::Pubkey,
  10. rent::Rent,
  11. system_instruction,
  12. sysvar::Sysvar,
  13. };
  14. pub fn create_pda(program_id: &Pubkey, accounts: &[AccountInfo], data: Favorites) -> ProgramResult {
  15. let account_iter = &mut accounts.iter();
  16. let user = next_account_info(account_iter)?; // the user who's signing the transaction
  17. let favorite_account = next_account_info(account_iter)?; // The target account that will be created in the process
  18. let system_program = next_account_info(account_iter)?;
  19. // deriving the favorite pda
  20. let (favorite_pda, favorite_bump) =
  21. Pubkey::find_program_address(&[b"favorite", user.key.as_ref()], program_id);
  22. // Checking if the favorite account is same as the derived favorite pda
  23. if favorite_account.key != &favorite_pda {
  24. return Err(ProgramError::IncorrectProgramId);
  25. }
  26. // Checking if the pda is already initialized
  27. if favorite_account.data.borrow().len() == 0 {
  28. // Initialize the favorite account if it's not initialized
  29. let space = data.try_to_vec()?.len();
  30. let lamports = (Rent::get()?).minimum_balance(space);
  31. let ix = system_instruction::create_account(
  32. user.key,
  33. favorite_account.key,
  34. lamports,
  35. space as u64,
  36. program_id,
  37. );
  38. invoke_signed(
  39. &ix,
  40. &[
  41. user.clone(),
  42. favorite_account.clone(),
  43. system_program.clone(),
  44. ],
  45. &[&[b"favorite", user.key.as_ref(), &[favorite_bump]]],
  46. )?;
  47. // Serialize and store the data
  48. data.serialize(&mut &mut favorite_account.data.borrow_mut()[..])?;
  49. msg!("{:#?}", data);
  50. } else {
  51. return Err(ProgramError::AccountAlreadyInitialized.into());
  52. }
  53. Ok(())
  54. }