lib.rs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. use anchor_lang::prelude::*;
  2. use some_external_program;
  3. use std::str::FromStr;
  4. declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
  5. #[constant]
  6. pub const FOO_CONST: u128 = 1_000_000;
  7. #[constant]
  8. pub const BAR_CONST: u8 = 6;
  9. /// This is an example program used for testing
  10. #[program]
  11. pub mod example_program {
  12. use super::*;
  13. pub fn initialize(ctx: Context<Initialize>) -> Result<()> {
  14. ctx.accounts.state.set_inner(State::default());
  15. Ok(())
  16. }
  17. /// Initializes an account with specified values
  18. pub fn initialize_with_values(
  19. ctx: Context<Initialize>,
  20. bool_field: bool,
  21. u8_field: u8,
  22. i8_field: i8,
  23. u16_field: u16,
  24. i16_field: i16,
  25. u32_field: u32,
  26. i32_field: i32,
  27. f32_field: f32,
  28. u64_field: u64,
  29. i64_field: i64,
  30. f64_field: f64,
  31. u128_field: u128,
  32. i128_field: i128,
  33. bytes_field: Vec<u8>,
  34. string_field: String,
  35. pubkey_field: Pubkey,
  36. vec_field: Vec<u64>,
  37. vec_struct_field: Vec<FooStruct>,
  38. option_field: Option<bool>,
  39. option_struct_field: Option<FooStruct>,
  40. struct_field: FooStruct,
  41. array_field: [bool; 3],
  42. enum_field_1: FooEnum,
  43. enum_field_2: FooEnum,
  44. enum_field_3: FooEnum,
  45. enum_field_4: FooEnum,
  46. ) -> Result<()> {
  47. ctx.accounts.state.set_inner(State {
  48. bool_field,
  49. u8_field,
  50. i8_field,
  51. u16_field,
  52. i16_field,
  53. u32_field,
  54. i32_field,
  55. f32_field,
  56. u64_field,
  57. i64_field,
  58. f64_field,
  59. u128_field,
  60. i128_field,
  61. bytes_field,
  62. string_field,
  63. pubkey_field,
  64. vec_field,
  65. vec_struct_field,
  66. option_field,
  67. option_struct_field,
  68. struct_field,
  69. array_field,
  70. enum_field_1,
  71. enum_field_2,
  72. enum_field_3,
  73. enum_field_4,
  74. });
  75. Ok(())
  76. }
  77. /// a separate instruction due to initialize_with_values having too many arguments
  78. /// https://github.com/solana-labs/solana/issues/23978
  79. pub fn initialize_with_values2(
  80. ctx: Context<Initialize2>,
  81. vec_of_option: Vec<Option<u64>>,
  82. box_field: Box<bool>,
  83. ) -> Result<SomeRetStruct> {
  84. ctx.accounts.state.set_inner(State2 { vec_of_option, box_field });
  85. Ok(SomeRetStruct { some_field: 3})
  86. }
  87. pub fn cause_error(_ctx: Context<CauseError>) -> Result<()> {
  88. return Err(error!(ErrorCode::SomeError));
  89. }
  90. }
  91. /// Enum type
  92. #[derive(AnchorSerialize, AnchorDeserialize, Clone)]
  93. pub enum FooEnum {
  94. /// Tuple kind
  95. Unnamed(bool, u8, BarStruct),
  96. UnnamedSingle(BarStruct),
  97. Named {
  98. /// A bool field inside a struct tuple kind
  99. bool_field: bool,
  100. u8_field: u8,
  101. nested: BarStruct,
  102. },
  103. Struct(BarStruct),
  104. OptionStruct(Option<BarStruct>),
  105. VecStruct(Vec<BarStruct>),
  106. NoFields,
  107. }
  108. /// Bar struct type
  109. #[derive(AnchorSerialize, AnchorDeserialize, Clone)]
  110. pub struct BarStruct {
  111. /// Some field
  112. some_field: bool,
  113. other_field: u8,
  114. }
  115. impl Default for BarStruct {
  116. fn default() -> Self {
  117. return BarStruct {
  118. some_field: true,
  119. other_field: 10,
  120. };
  121. }
  122. }
  123. #[derive(AnchorSerialize, AnchorDeserialize, Clone)]
  124. pub struct FooStruct {
  125. field1: u8,
  126. field2: u16,
  127. nested: BarStruct,
  128. vec_nested: Vec<BarStruct>,
  129. option_nested: Option<BarStruct>,
  130. enum_field: FooEnum,
  131. }
  132. impl Default for FooStruct {
  133. fn default() -> Self {
  134. return FooStruct {
  135. field1: 123,
  136. field2: 999,
  137. nested: BarStruct::default(),
  138. vec_nested: vec![BarStruct::default()],
  139. option_nested: Some(BarStruct::default()),
  140. enum_field: FooEnum::Named {
  141. bool_field: true,
  142. u8_field: 15,
  143. nested: BarStruct::default(),
  144. },
  145. };
  146. }
  147. }
  148. /// An account containing various fields
  149. #[account]
  150. pub struct State {
  151. /// A boolean field
  152. bool_field: bool,
  153. u8_field: u8,
  154. i8_field: i8,
  155. u16_field: u16,
  156. i16_field: i16,
  157. u32_field: u32,
  158. i32_field: i32,
  159. f32_field: f32,
  160. u64_field: u64,
  161. i64_field: i64,
  162. f64_field: f64,
  163. u128_field: u128,
  164. i128_field: i128,
  165. bytes_field: Vec<u8>,
  166. string_field: String,
  167. pubkey_field: Pubkey,
  168. vec_field: Vec<u64>,
  169. vec_struct_field: Vec<FooStruct>,
  170. option_field: Option<bool>,
  171. option_struct_field: Option<FooStruct>,
  172. struct_field: FooStruct,
  173. array_field: [bool; 3],
  174. enum_field_1: FooEnum,
  175. enum_field_2: FooEnum,
  176. enum_field_3: FooEnum,
  177. enum_field_4: FooEnum,
  178. }
  179. impl Default for State {
  180. fn default() -> Self {
  181. // some arbitrary default values
  182. return State {
  183. bool_field: true,
  184. u8_field: 234,
  185. i8_field: -123,
  186. u16_field: 62345,
  187. i16_field: -31234,
  188. u32_field: 1234567891,
  189. i32_field: -1234567891,
  190. f32_field: 123456.5,
  191. u64_field: u64::MAX / 2 + 10,
  192. i64_field: i64::MIN / 2 - 10,
  193. f64_field: 1234567891.345,
  194. u128_field: u128::MAX / 2 + 10,
  195. i128_field: i128::MIN / 2 - 10,
  196. bytes_field: vec![1, 2, 255, 254],
  197. string_field: String::from("hello"),
  198. pubkey_field: Pubkey::from_str("EPZP2wrcRtMxrAPJCXVEQaYD9eH7fH7h12YqKDcd4aS7").unwrap(),
  199. vec_field: vec![1, 2, 100, 1000, u64::MAX],
  200. vec_struct_field: vec![FooStruct::default()],
  201. option_field: None,
  202. option_struct_field: Some(FooStruct::default()),
  203. struct_field: FooStruct::default(),
  204. array_field: [true, false, true],
  205. enum_field_1: FooEnum::Unnamed(false, 10, BarStruct::default()),
  206. enum_field_2: FooEnum::Named {
  207. bool_field: true,
  208. u8_field: 20,
  209. nested: BarStruct::default(),
  210. },
  211. enum_field_3: FooEnum::Struct(BarStruct::default()),
  212. enum_field_4: FooEnum::NoFields,
  213. };
  214. }
  215. }
  216. #[account]
  217. pub struct State2 {
  218. vec_of_option: Vec<Option<u64>>,
  219. box_field: Box<bool>,
  220. }
  221. impl Default for State2 {
  222. fn default() -> Self {
  223. return State2 {
  224. vec_of_option: vec![None, Some(10)],
  225. box_field: Box::new(true),
  226. };
  227. }
  228. }
  229. #[derive(Accounts)]
  230. pub struct NestedAccounts<'info> {
  231. /// Sysvar clock
  232. clock: Sysvar<'info, Clock>,
  233. rent: Sysvar<'info, Rent>,
  234. }
  235. #[derive(Accounts)]
  236. pub struct Initialize<'info> {
  237. /// State account
  238. #[account(
  239. init,
  240. space = 8 + 1000, // TODO: use exact space required
  241. payer = payer,
  242. )]
  243. state: Account<'info, State>,
  244. nested: NestedAccounts<'info>,
  245. zc_account: AccountLoader<'info, SomeZcAccount>,
  246. #[account(mut)]
  247. payer: Signer<'info>,
  248. system_program: Program<'info, System>,
  249. }
  250. #[derive(Accounts)]
  251. pub struct Initialize2<'info> {
  252. #[account(
  253. init,
  254. space = 8 + 1000, // TODO: use exact space required
  255. payer = payer,
  256. )]
  257. state: Account<'info, State2>,
  258. #[account(mut)]
  259. payer: Signer<'info>,
  260. system_program: Program<'info, System>,
  261. }
  262. #[derive(Accounts)]
  263. pub struct CauseError {}
  264. #[error_code]
  265. pub enum ErrorCode {
  266. #[msg("Example error.")]
  267. SomeError,
  268. #[msg("Another error.")]
  269. OtherError,
  270. ErrorWithoutMsg,
  271. }
  272. mod some_other_module {
  273. use super::*;
  274. #[derive(AnchorSerialize, AnchorDeserialize, Clone)]
  275. pub struct Baz {
  276. some_u8: u8,
  277. }
  278. }
  279. #[event]
  280. pub struct SomeEvent {
  281. bool_field: bool,
  282. external_baz: some_external_program::Baz,
  283. other_module_baz: some_other_module::Baz,
  284. }
  285. #[zero_copy]
  286. pub struct ZcStruct {
  287. pub some_field: u16,
  288. }
  289. #[account(zero_copy)]
  290. pub struct SomeZcAccount {
  291. field: ZcStruct,
  292. }
  293. #[derive(AnchorSerialize, AnchorDeserialize, Clone)]
  294. pub struct SomeRetStruct {
  295. pub some_field: u8,
  296. }