Skip to main content

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}