Attribute Macro concordium_std::init

#[init]
Expand description

Derive the appropriate export for an annotated init function.

This macro requires the following items to be present

  • contract="<name>" where <name> is the name of the smart contract and the generated function is exported as this name prefixed with init_. The name should be unique in the module, as a contract can only have one init-function.

The annotated function must be of a specific type, which depends on the enabled attributes. Without any of the optional attributes the function must have a signature of

#[init(contract = "my_contract")]
fn some_init(ctx: &InitContext, state_builder: &mut StateBuilder) -> InitResult<MyState> {...}

Where InitContext, InitResult, and StateBuilder are exposed from concordium-std and MyState is a user-defined type.

§Optional attributes

§payable: Make function accept an amount of CCD

Without setting the payable attribute, the generated function will reject any non-zero amount of CCD supplied with the transaction. This means we are required to explicitly mark our functions as payable, if they are to accept CCD.

Setting the payable attribute changes the required signature to include an extra argument of type Amount, allowing the function to access the amount of CCD supplied with the transaction.

§Example

#[init(contract = "my_contract", payable)]
fn some_init(ctx: &InitContext, state_builder: StateBuilder, amount: Amount) -> InitResult<MyState> {...}

§enable_logger: Function can access event logging

Setting the enable_logger attribute changes the required signature to include an extra argument &mut Logger, allowing the function to log events.

§Example

#[init(contract = "my_contract", enable_logger)]
fn some_init(ctx: &InitContext, state_builder: StateBuilder, logger: &mut Logger) -> InitResult<MyState> {...}

§low_level: Manually deal with the low-level state.

Setting the low_level attribute disables the generated code for serializing the contract state.

If low_level is set, the &mut StateBuilder in the signature is replaced by &mut StateApi found in concordium-std, which gives access to manipulating the low-level contract state directly. This means there is no need to return the contract state and the return type becomes InitResult<()>.

§Example

#[init(contract = "my_contract", low_level)]
fn some_init(ctx: &InitContext, state: &mut StateApi) -> InitResult<()> {...}

§parameter="<Param>": Generate schema for parameter

To make schema generation include the parameter for this function, add the attribute parameter and set it equal to a string literal containing the name of the type used for the parameter. The parameter type must implement the SchemaType trait, which for most cases can be derived automatically.

§Example

#[derive(SchemaType)]
struct MyParam { ... }

#[init(contract = "my_contract", parameter = "MyParam")]

§error="<Error>": Generate schema for error

To make schema generation include the error for this function, add the attribute error and set it equal to a string literal containing the name of the type used for the error. The error type must implement the SchemaType trait, which for most cases can be derived automatically.

§Example

#[derive(SchemaType)]
enum MyError { ... }

#[init(contract = "my_contract", parameter = "MyError")]
fn some_init(ctx: &impl InitContext, state: &mut StateApi) -> Result<(), MyError> {...}

§crypto_primitives: Function can access cryptographic primitives

Setting the crypto_primitives attribute changes the required signature to include an extra argument &CryptoPrimitives, which provides cryptographic primitives such as verifying signatures and hashing data.

§Example

#[init(contract = "my_contract", crypto_primitives)]
fn some_init(
    ctx: &InitContext,
    state_build: StateBuilder,
    crypto_primitives: &CryptoPrimitives,
) -> InitResult<MyState> {...}