lib.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #![cfg_attr(feature = "program", feature(proc_macro_hygiene))]
  2. use anchor::prelude::*;
  3. // Define the program's RPC handlers.
  4. #[program]
  5. mod example {
  6. use super::*;
  7. #[access_control(not_zero(authority))]
  8. pub fn create_root(ctx: Context<CreateRoot>, authority: Pubkey, data: u64) -> ProgramResult {
  9. let root = &mut ctx.accounts.root;
  10. root.account.authority = authority;
  11. root.account.data = data;
  12. root.account.initialized = true;
  13. Ok(())
  14. }
  15. pub fn update_root(ctx: Context<UpdateRoot>, data: u64) -> ProgramResult {
  16. let root = &mut ctx.accounts.root;
  17. root.account.data = data;
  18. Ok(())
  19. }
  20. pub fn create_leaf(ctx: Context<CreateLeaf>, data: u64, custom: MyCustomType) -> ProgramResult {
  21. let leaf = &mut ctx.accounts.leaf;
  22. leaf.account.data = data;
  23. leaf.account.custom = custom;
  24. Ok(())
  25. }
  26. pub fn update_leaf(ctx: Context<UpdateLeaf>, data: u64) -> ProgramResult {
  27. let leaf = &mut ctx.accounts.leaf;
  28. leaf.account.data = data;
  29. Ok(())
  30. }
  31. }
  32. // Define the validated accounts for each handler.
  33. #[derive(Accounts)]
  34. pub struct CreateRoot<'info> {
  35. #[account(signer)]
  36. pub authority: AccountInfo<'info>,
  37. #[account(mut, "!root.initialized")]
  38. pub root: ProgramAccount<'info, Root>,
  39. }
  40. #[derive(Accounts)]
  41. pub struct UpdateRoot<'info> {
  42. #[account(signer)]
  43. pub authority: AccountInfo<'info>,
  44. #[account(mut, "root.initialized", "&root.authority == authority.key")]
  45. pub root: ProgramAccount<'info, Root>,
  46. }
  47. #[derive(Accounts)]
  48. pub struct CreateLeaf<'info> {
  49. #[account("root.initialized")]
  50. pub root: ProgramAccount<'info, Root>,
  51. #[account(mut, "!leaf.initialized")]
  52. pub leaf: ProgramAccount<'info, Leaf>,
  53. }
  54. #[derive(Accounts)]
  55. pub struct UpdateLeaf<'info> {
  56. #[account(signer)]
  57. pub authority: AccountInfo<'info>,
  58. #[account("root.initialized", "&root.authority == authority.key")]
  59. pub root: ProgramAccount<'info, Root>,
  60. #[account(mut, belongs_to = root, "!leaf.initialized")]
  61. pub leaf: ProgramAccount<'info, Leaf>,
  62. }
  63. // Define the program owned accounts.
  64. #[derive(AnchorSerialize, AnchorDeserialize)]
  65. pub struct Root {
  66. pub initialized: bool,
  67. pub authority: Pubkey,
  68. pub data: u64,
  69. }
  70. #[derive(AnchorSerialize, AnchorDeserialize)]
  71. pub struct Leaf {
  72. pub initialized: bool,
  73. pub root: Pubkey,
  74. pub data: u64,
  75. pub custom: MyCustomType,
  76. }
  77. // Define custom types.
  78. #[derive(AnchorSerialize, AnchorDeserialize)]
  79. pub struct MyCustomType {
  80. pub my_data: u64,
  81. pub key: Pubkey,
  82. }
  83. // Define any auxiliary access control checks.
  84. fn not_zero(authority: Pubkey) -> ProgramResult {
  85. if authority != Pubkey::new_from_array([0; 32]) {
  86. return Err(ProgramError::InvalidInstructionData);
  87. }
  88. Ok(())
  89. }