macro_rules! entrypoint { ($process_instruction:ident) => { ... }; }
Expand description
Declare the program entrypoint and set up global handlers.
This macro emits the common boilerplate necessary to begin program execution, calling a provided function to process the program instruction supplied by the runtime, and reporting its result to the runtime.
It also sets up a global allocator and panic handler, using the
custom_heap_default
and custom_panic_default
macros.
The argument is the name of a function with this type signature:
fn process_instruction(
program_id: &Pubkey, // Public key of the account the program was loaded into
accounts: &[AccountInfo], // All accounts required to process the instruction
instruction_data: &[u8], // Serialized instruction-specific data
) -> ProgramResult;
§Cargo features
This macro emits symbols and definitions that may only be defined once
globally. As such, if linked to other Rust crates it will cause compiler
errors. To avoid this, it is common for Solana programs to define an
optional Cargo feature called no-entrypoint
, and use it to conditionally
disable the entrypoint
macro invocation, as well as the
process_instruction
function. See a typical pattern for this in the
example below.
The code emitted by this macro can be customized by adding cargo features to your own crate (the one that calls this macro) and enabling them:
-
If the
custom-heap
feature is defined then the macro will not set up the global allocator, allowingentrypoint
to be used with your own allocator. See documentation for thecustom_heap_default
macro for details of customizing the global allocator. -
If the
custom-panic
feature is defined then the macro will not define a panic handler, allowingentrypoint
to be used with your own panic handler. See documentation for thecustom_panic_default
macro for details of customizing the panic handler.
§Examples
Defining an entrypoint and making it conditional on the no-entrypoint
feature. Although the entrypoint
module is written inline in this example,
it is common to put it into its own file.
#[cfg(not(feature = "no-entrypoint"))]
pub mod entrypoint {
use solana_program::{
account_info::AccountInfo,
entrypoint,
entrypoint::ProgramResult,
msg,
pubkey::Pubkey,
};
entrypoint!(process_instruction);
pub fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
msg!("Hello world");
Ok(())
}
}