cronos_anchor_lang/lib.rs
1//! Anchor ⚓ is a framework for Solana's Sealevel runtime providing several
2//! convenient developer tools.
3//!
4//! - Rust eDSL for writing safe, secure, and high level Solana programs
5//! - [IDL](https://en.wikipedia.org/wiki/Interface_description_language) specification
6//! - TypeScript package for generating clients from IDL
7//! - CLI and workspace management for developing complete applications
8//!
9//! If you're familiar with developing in Ethereum's
10//! [Solidity](https://docs.soliditylang.org/en/v0.7.4/),
11//! [Truffle](https://www.trufflesuite.com/),
12//! [web3.js](https://github.com/ethereum/web3.js) or Parity's
13//! [Ink!](https://github.com/paritytech/ink), then the experience will be
14//! familiar. Although the syntax and semantics are targeted at Solana, the high
15//! level workflow of writing RPC request handlers, emitting an IDL, and
16//! generating clients from IDL is the same.
17//!
18//! For detailed tutorials and examples on how to use Anchor, see the guided
19//! [tutorials](https://project-serum.github.io/anchor) or examples in the GitHub
20//! [repository](https://github.com/project-serum/anchor).
21//!
22//! Presented here are the Rust primitives for building on Solana.
23
24extern crate self as anchor_lang;
25
26use bytemuck::{Pod, Zeroable};
27use solana_program::account_info::AccountInfo;
28use solana_program::instruction::AccountMeta;
29use solana_program::pubkey::Pubkey;
30use std::collections::BTreeMap;
31use std::io::Write;
32
33mod account_meta;
34pub mod accounts;
35mod bpf_upgradeable_state;
36mod bpf_writer;
37mod common;
38pub mod context;
39mod ctor;
40pub mod error;
41#[doc(hidden)]
42pub mod idl;
43pub mod system_program;
44
45mod vec;
46pub use crate::bpf_upgradeable_state::*;
47pub use anchor_attribute_access_control::access_control;
48pub use anchor_attribute_account::{account, declare_id, zero_copy};
49pub use anchor_attribute_constant::constant;
50pub use anchor_attribute_error::*;
51pub use anchor_attribute_event::{emit, event};
52pub use anchor_attribute_interface::interface;
53pub use anchor_attribute_program::program;
54pub use anchor_attribute_state::state;
55pub use anchor_derive_accounts::Accounts;
56/// Borsh is the default serialization format for instructions and accounts.
57pub use borsh::{BorshDeserialize as AnchorDeserialize, BorshSerialize as AnchorSerialize};
58pub use solana_program;
59
60pub type Result<T> = std::result::Result<T, error::Error>;
61
62/// A data structure of validated accounts that can be deserialized from the
63/// input to a Solana program. Implementations of this trait should perform any
64/// and all requisite constraint checks on accounts to ensure the accounts
65/// maintain any invariants required for the program to run securely. In most
66/// cases, it's recommended to use the [`Accounts`](./derive.Accounts.html)
67/// derive macro to implement this trait.
68pub trait Accounts<'info>: ToAccountMetas + ToAccountInfos<'info> + Sized {
69 /// Returns the validated accounts struct. What constitutes "valid" is
70 /// program dependent. However, users of these types should never have to
71 /// worry about account substitution attacks. For example, if a program
72 /// expects a `Mint` account from the SPL token program in a particular
73 /// field, then it should be impossible for this method to return `Ok` if
74 /// any other account type is given--from the SPL token program or elsewhere.
75 ///
76 /// `program_id` is the currently executing program. `accounts` is the
77 /// set of accounts to construct the type from. For every account used,
78 /// the implementation should mutate the slice, consuming the used entry
79 /// so that it cannot be used again.
80 fn try_accounts(
81 program_id: &Pubkey,
82 accounts: &mut &[AccountInfo<'info>],
83 ix_data: &[u8],
84 bumps: &mut BTreeMap<String, u8>,
85 ) -> Result<Self>;
86}
87
88/// The exit procedure for an account. Any cleanup or persistence to storage
89/// should be done here.
90pub trait AccountsExit<'info>: ToAccountMetas + ToAccountInfos<'info> {
91 /// `program_id` is the currently executing program.
92 fn exit(&self, _program_id: &Pubkey) -> Result<()> {
93 // no-op
94 Ok(())
95 }
96}
97
98/// The close procedure to initiate garabage collection of an account, allowing
99/// one to retrieve the rent exemption.
100pub trait AccountsClose<'info>: ToAccountInfos<'info> {
101 fn close(&self, sol_destination: AccountInfo<'info>) -> Result<()>;
102}
103
104/// Transformation to
105/// [`AccountMeta`](../solana_program/instruction/struct.AccountMeta.html)
106/// structs.
107pub trait ToAccountMetas {
108 /// `is_signer` is given as an optional override for the signer meta field.
109 /// This covers the edge case when a program-derived-address needs to relay
110 /// a transaction from a client to another program but sign the transaction
111 /// before the relay. The client cannot mark the field as a signer, and so
112 /// we have to override the is_signer meta field given by the client.
113 fn to_account_metas(&self, is_signer: Option<bool>) -> Vec<AccountMeta>;
114}
115
116/// Transformation to
117/// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html)
118/// structs.
119pub trait ToAccountInfos<'info> {
120 fn to_account_infos(&self) -> Vec<AccountInfo<'info>>;
121}
122
123/// Transformation to an `AccountInfo` struct.
124pub trait ToAccountInfo<'info> {
125 fn to_account_info(&self) -> AccountInfo<'info>;
126}
127
128impl<'info, T> ToAccountInfo<'info> for T
129where
130 T: AsRef<AccountInfo<'info>>,
131{
132 fn to_account_info(&self) -> AccountInfo<'info> {
133 self.as_ref().clone()
134 }
135}
136
137/// A data structure that can be serialized and stored into account storage,
138/// i.e. an
139/// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html#structfield.data)'s
140/// mutable data slice.
141///
142/// Implementors of this trait should ensure that any subsequent usage of the
143/// `AccountDeserialize` trait succeeds if and only if the account is of the
144/// correct type.
145///
146/// In most cases, one can use the default implementation provided by the
147/// [`#[account]`](./attr.account.html) attribute.
148pub trait AccountSerialize {
149 /// Serializes the account data into `writer`.
150 fn try_serialize<W: Write>(&self, _writer: &mut W) -> Result<()> {
151 Ok(())
152 }
153}
154
155/// A data structure that can be deserialized and stored into account storage,
156/// i.e. an
157/// [`AccountInfo`](../solana_program/account_info/struct.AccountInfo.html#structfield.data)'s
158/// mutable data slice.
159pub trait AccountDeserialize: Sized {
160 /// Deserializes previously initialized account data. Should fail for all
161 /// uninitialized accounts, where the bytes are zeroed. Implementations
162 /// should be unique to a particular account type so that one can never
163 /// successfully deserialize the data of one account type into another.
164 /// For example, if the SPL token program were to implement this trait,
165 /// it should be impossible to deserialize a `Mint` account into a token
166 /// `Account`.
167 fn try_deserialize(buf: &mut &[u8]) -> Result<Self> {
168 Self::try_deserialize_unchecked(buf)
169 }
170
171 /// Deserializes account data without checking the account discriminator.
172 /// This should only be used on account initialization, when the bytes of
173 /// the account are zeroed.
174 fn try_deserialize_unchecked(buf: &mut &[u8]) -> Result<Self>;
175}
176
177/// An account data structure capable of zero copy deserialization.
178pub trait ZeroCopy: Discriminator + Copy + Clone + Zeroable + Pod {}
179
180/// Calculates the data for an instruction invocation, where the data is
181/// `Sha256(<namespace>::<method_name>)[..8] || BorshSerialize(args)`.
182/// `args` is a borsh serialized struct of named fields for each argument given
183/// to an instruction.
184pub trait InstructionData: AnchorSerialize {
185 fn data(&self) -> Vec<u8>;
186}
187
188/// An event that can be emitted via a Solana log. See [`emit!`](crate::prelude::emit) for an example.
189pub trait Event: AnchorSerialize + AnchorDeserialize + Discriminator {
190 fn data(&self) -> Vec<u8>;
191}
192
193// The serialized event data to be emitted via a Solana log.
194// TODO: remove this on the next major version upgrade.
195#[doc(hidden)]
196#[deprecated(since = "0.4.2", note = "Please use Event instead")]
197pub trait EventData: AnchorSerialize + Discriminator {
198 fn data(&self) -> Vec<u8>;
199}
200
201/// 8 byte unique identifier for a type.
202pub trait Discriminator {
203 fn discriminator() -> [u8; 8];
204}
205
206/// Bump seed for program derived addresses.
207pub trait Bump {
208 fn seed(&self) -> u8;
209}
210
211/// Defines an address expected to own an account.
212pub trait Owner {
213 fn owner() -> Pubkey;
214}
215
216/// Defines the id of a program.
217pub trait Id {
218 fn id() -> Pubkey;
219}
220
221/// Defines the Pubkey of an account.
222pub trait Key {
223 fn key(&self) -> Pubkey;
224}
225
226impl Key for Pubkey {
227 fn key(&self) -> Pubkey {
228 *self
229 }
230}
231
232/// The prelude contains all commonly used components of the crate.
233/// All programs should include it via `anchor_lang::prelude::*;`.
234pub mod prelude {
235 pub use super::{
236 access_control, account, accounts::account::Account,
237 accounts::account_loader::AccountLoader, accounts::program::Program,
238 accounts::signer::Signer, accounts::system_account::SystemAccount,
239 accounts::sysvar::Sysvar, accounts::unchecked_account::UncheckedAccount, constant,
240 context::Context, context::CpiContext, declare_id, emit, err, error, event, interface,
241 program, require, require_eq, require_gt, require_gte, require_keys_eq, require_keys_neq,
242 require_neq, solana_program::bpf_loader_upgradeable::UpgradeableLoaderState, source, state,
243 system_program::System, zero_copy, AccountDeserialize, AccountSerialize, Accounts,
244 AccountsExit, AnchorDeserialize, AnchorSerialize, Id, Key, Owner, ProgramData, Result,
245 ToAccountInfo, ToAccountInfos, ToAccountMetas,
246 };
247 pub use anchor_attribute_error::*;
248 pub use borsh;
249 pub use error::*;
250 pub use solana_program::account_info::{next_account_info, AccountInfo};
251 pub use solana_program::instruction::AccountMeta;
252 pub use solana_program::msg;
253 pub use solana_program::program_error::ProgramError;
254 pub use solana_program::pubkey::Pubkey;
255 pub use solana_program::sysvar::clock::Clock;
256 pub use solana_program::sysvar::epoch_schedule::EpochSchedule;
257 pub use solana_program::sysvar::instructions::Instructions;
258 pub use solana_program::sysvar::rent::Rent;
259 pub use solana_program::sysvar::rewards::Rewards;
260 pub use solana_program::sysvar::slot_hashes::SlotHashes;
261 pub use solana_program::sysvar::slot_history::SlotHistory;
262 pub use solana_program::sysvar::stake_history::StakeHistory;
263 pub use solana_program::sysvar::Sysvar as SolanaSysvar;
264 pub use thiserror;
265}
266
267/// Internal module used by macros and unstable apis.
268#[doc(hidden)]
269pub mod __private {
270 use super::Result;
271 /// The discriminator anchor uses to mark an account as closed.
272 pub const CLOSED_ACCOUNT_DISCRIMINATOR: [u8; 8] = [255, 255, 255, 255, 255, 255, 255, 255];
273
274 pub use crate::ctor::Ctor;
275
276 pub use anchor_attribute_account::ZeroCopyAccessor;
277
278 pub use anchor_attribute_event::EventIndex;
279
280 pub use base64;
281
282 pub use bytemuck;
283
284 use solana_program::pubkey::Pubkey;
285
286 pub mod state {
287 pub use crate::accounts::state::*;
288 }
289
290 // Calculates the size of an account, which may be larger than the deserialized
291 // data in it. This trait is currently only used for `#[state]` accounts.
292 #[doc(hidden)]
293 pub trait AccountSize {
294 fn size(&self) -> Result<u64>;
295 }
296
297 // Very experimental trait.
298 #[doc(hidden)]
299 pub trait ZeroCopyAccessor<Ty> {
300 fn get(&self) -> Ty;
301 fn set(input: &Ty) -> Self;
302 }
303
304 #[doc(hidden)]
305 impl ZeroCopyAccessor<Pubkey> for [u8; 32] {
306 fn get(&self) -> Pubkey {
307 Pubkey::new(self)
308 }
309 fn set(input: &Pubkey) -> [u8; 32] {
310 input.to_bytes()
311 }
312 }
313
314 #[doc(hidden)]
315 pub use crate::accounts::state::PROGRAM_STATE_SEED;
316}
317
318/// Ensures a condition is true, otherwise returns with the given error.
319/// Use this with or without a custom error type.
320///
321/// # Example
322/// ```ignore
323/// // Instruction function
324/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
325/// require!(ctx.accounts.data.mutation_allowed, MyError::MutationForbidden);
326/// ctx.accounts.data.data = data;
327/// Ok(())
328/// }
329///
330/// // An enum for custom error codes
331/// #[error_code]
332/// pub enum MyError {
333/// MutationForbidden
334/// }
335///
336/// // An account definition
337/// #[account]
338/// #[derive(Default)]
339/// pub struct MyData {
340/// mutation_allowed: bool,
341/// data: u64
342/// }
343///
344/// // An account validation struct
345/// #[derive(Accounts)]
346/// pub struct SetData<'info> {
347/// #[account(mut)]
348/// pub data: Account<'info, MyData>
349/// }
350/// ```
351#[macro_export]
352macro_rules! require {
353 ($invariant:expr, $error:tt $(,)?) => {
354 if !($invariant) {
355 return Err(anchor_lang::error!(crate::ErrorCode::$error));
356 }
357 };
358 ($invariant:expr, $error:expr $(,)?) => {
359 if !($invariant) {
360 return Err(anchor_lang::error!($error));
361 }
362 };
363}
364
365/// Ensures two NON-PUBKEY values are equal.
366///
367/// Use [require_keys_eq](crate::prelude::require_keys_eq)
368/// to compare two pubkeys.
369///
370/// Can be used with or without a custom error code.
371///
372/// # Example
373/// ```rust,ignore
374/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
375/// require_eq!(ctx.accounts.data.data, 0);
376/// ctx.accounts.data.data = data;
377/// Ok(())
378/// }
379/// ```
380#[macro_export]
381macro_rules! require_eq {
382 ($value1: expr, $value2: expr, $error_code:expr $(,)?) => {
383 if $value1 != $value2 {
384 return Err(error!($error_code).with_values(($value1, $value2)));
385 }
386 };
387 ($value1: expr, $value2: expr $(,)?) => {
388 if $value1 != $value2 {
389 return Err(error!(anchor_lang::error::ErrorCode::RequireEqViolated)
390 .with_values(($value1, $value2)));
391 }
392 };
393}
394
395/// Ensures two NON-PUBKEY values are not equal.
396///
397/// Use [require_keys_neq](crate::prelude::require_keys_neq)
398/// to compare two pubkeys.
399///
400/// Can be used with or without a custom error code.
401///
402/// # Example
403/// ```rust,ignore
404/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
405/// require_neq!(ctx.accounts.data.data, 0);
406/// ctx.accounts.data.data = data;
407/// Ok(());
408/// }
409/// ```
410#[macro_export]
411macro_rules! require_neq {
412 ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
413 if $value1 == $value2 {
414 return Err(error!($error_code).with_values(($value1, $value2)));
415 }
416 };
417 ($value1: expr, $value2: expr $(,)?) => {
418 if $value1 == $value2 {
419 return Err(error!(anchor_lang::error::ErrorCode::RequireNeqViolated)
420 .with_values(($value1, $value2)));
421 }
422 };
423}
424
425/// Ensures two pubkeys values are equal.
426///
427/// Use [require_eq](crate::prelude::require_eq)
428/// to compare two non-pubkey values.
429///
430/// Can be used with or without a custom error code.
431///
432/// # Example
433/// ```rust,ignore
434/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
435/// require_keys_eq!(ctx.accounts.data.authority.key(), ctx.accounts.authority.key());
436/// ctx.accounts.data.data = data;
437/// Ok(())
438/// }
439/// ```
440#[macro_export]
441macro_rules! require_keys_eq {
442 ($value1: expr, $value2: expr, $error_code:expr $(,)?) => {
443 if $value1 != $value2 {
444 return Err(error!($error_code).with_pubkeys(($value1, $value2)));
445 }
446 };
447 ($value1: expr, $value2: expr $(,)?) => {
448 if $value1 != $value2 {
449 return Err(error!(anchor_lang::error::ErrorCode::RequireKeysEqViolated)
450 .with_pubkeys(($value1, $value2)));
451 }
452 };
453}
454
455/// Ensures two pubkeys are not equal.
456///
457/// Use [require_neq](crate::prelude::require_neq)
458/// to compare two non-pubkey values.
459///
460/// Can be used with or without a custom error code.
461///
462/// # Example
463/// ```rust,ignore
464/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
465/// require_keys_neq!(ctx.accounts.data.authority.key(), ctx.accounts.other.key());
466/// ctx.accounts.data.data = data;
467/// Ok(())
468/// }
469/// ```
470#[macro_export]
471macro_rules! require_keys_neq {
472 ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
473 if $value1 == $value2 {
474 return Err(error!($error_code).with_pubkeys(($value1, $value2)));
475 }
476 };
477 ($value1: expr, $value2: expr $(,)?) => {
478 if $value1 == $value2 {
479 return Err(
480 error!(anchor_lang::error::ErrorCode::RequireKeysNeqViolated)
481 .with_pubkeys(($value1, $value2)),
482 );
483 }
484 };
485}
486
487/// Ensures the first NON-PUBKEY value is greater than the second
488/// NON-PUBKEY value.
489///
490/// To include an equality check, use [require_gte](crate::require_gte).
491///
492/// Can be used with or without a custom error code.
493///
494/// # Example
495/// ```rust,ignore
496/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
497/// require_gt!(ctx.accounts.data.data, 0);
498/// ctx.accounts.data.data = data;
499/// Ok(());
500/// }
501/// ```
502#[macro_export]
503macro_rules! require_gt {
504 ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
505 if $value1 <= $value2 {
506 return Err(error!($error_code).with_values(($value1, $value2)));
507 }
508 };
509 ($value1: expr, $value2: expr $(,)?) => {
510 if $value1 <= $value2 {
511 return Err(error!(anchor_lang::error::ErrorCode::RequireGtViolated)
512 .with_values(($value1, $value2)));
513 }
514 };
515}
516
517/// Ensures the first NON-PUBKEY value is greater than or equal
518/// to the second NON-PUBKEY value.
519///
520/// Can be used with or without a custom error code.
521///
522/// # Example
523/// ```rust,ignore
524/// pub fn set_data(ctx: Context<SetData>, data: u64) -> Result<()> {
525/// require_gte!(ctx.accounts.data.data, 1);
526/// ctx.accounts.data.data = data;
527/// Ok(());
528/// }
529/// ```
530#[macro_export]
531macro_rules! require_gte {
532 ($value1: expr, $value2: expr, $error_code: expr $(,)?) => {
533 if $value1 < $value2 {
534 return Err(error!($error_code).with_values(($value1, $value2)));
535 }
536 };
537 ($value1: expr, $value2: expr $(,)?) => {
538 if $value1 < $value2 {
539 return Err(error!(anchor_lang::error::ErrorCode::RequireGteViolated)
540 .with_values(($value1, $value2)));
541 }
542 };
543}
544
545/// Returns with the given error.
546/// Use this with a custom error type.
547///
548/// # Example
549/// ```ignore
550/// // Instruction function
551/// pub fn example(ctx: Context<Example>) -> Result<()> {
552/// err!(MyError::SomeError)
553/// }
554///
555/// // An enum for custom error codes
556/// #[error_code]
557/// pub enum MyError {
558/// SomeError
559/// }
560/// ```
561#[macro_export]
562macro_rules! err {
563 ($error:tt $(,)?) => {
564 Err(anchor_lang::error!(crate::ErrorCode::$error))
565 };
566 ($error:expr $(,)?) => {
567 Err(anchor_lang::error!($error))
568 };
569}
570
571/// Creates a [`Source`](crate::error::Source)
572#[macro_export]
573macro_rules! source {
574 () => {
575 anchor_lang::error::Source {
576 filename: file!(),
577 line: line!(),
578 }
579 };
580}