lib.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. use borsh::{BorshDeserialize, BorshSerialize};
  2. #[cfg(not(feature = "no-entrypoint"))]
  3. use solana_program::entrypoint;
  4. use solana_program::{
  5. account_info::{next_account_info, AccountInfo},
  6. entrypoint::ProgramResult,
  7. msg,
  8. program::invoke,
  9. program_error::ProgramError,
  10. pubkey::Pubkey,
  11. rent::Rent,
  12. system_instruction,
  13. sysvar::Sysvar,
  14. };
  15. #[cfg(not(feature = "no-entrypoint"))]
  16. entrypoint!(process_instruction);
  17. pub fn process_instruction(
  18. program_id: &Pubkey,
  19. accounts: &[AccountInfo],
  20. instruction_data: &[u8],
  21. ) -> ProgramResult {
  22. if let Ok(power_status) = PowerStatus::try_from_slice(instruction_data) {
  23. return initialize(program_id, accounts, power_status);
  24. }
  25. if let Ok(set_power_status) = SetPowerStatus::try_from_slice(instruction_data) {
  26. return switch_power(accounts, set_power_status.name);
  27. }
  28. Err(ProgramError::InvalidInstructionData)
  29. }
  30. pub fn initialize(
  31. program_id: &Pubkey,
  32. accounts: &[AccountInfo],
  33. power_status: PowerStatus,
  34. ) -> ProgramResult {
  35. let accounts_iter = &mut accounts.iter();
  36. let power = next_account_info(accounts_iter)?;
  37. let user = next_account_info(accounts_iter)?;
  38. let system_program = next_account_info(accounts_iter)?;
  39. let account_span = (power_status.try_to_vec()?).len();
  40. let lamports_required = (Rent::get()?).minimum_balance(account_span);
  41. invoke(
  42. &system_instruction::create_account(
  43. user.key,
  44. power.key,
  45. lamports_required,
  46. account_span as u64,
  47. program_id,
  48. ),
  49. &[user.clone(), power.clone(), system_program.clone()],
  50. )?;
  51. power_status.serialize(&mut &mut power.data.borrow_mut()[..])?;
  52. Ok(())
  53. }
  54. pub fn switch_power(accounts: &[AccountInfo], name: String) -> ProgramResult {
  55. let accounts_iter = &mut accounts.iter();
  56. let power = next_account_info(accounts_iter)?;
  57. let mut power_status = PowerStatus::try_from_slice(&power.data.borrow())?;
  58. power_status.is_on = !power_status.is_on;
  59. power_status.serialize(&mut &mut power.data.borrow_mut()[..])?;
  60. msg!("{} is pulling the power switch!", &name);
  61. match power_status.is_on {
  62. true => msg!("The power is now on."),
  63. false => msg!("The power is now off!"),
  64. };
  65. Ok(())
  66. }
  67. #[derive(BorshDeserialize, BorshSerialize, Debug)]
  68. pub struct SetPowerStatus {
  69. pub name: String,
  70. }
  71. #[derive(BorshDeserialize, BorshSerialize, Debug)]
  72. pub struct PowerStatus {
  73. pub is_on: bool,
  74. }