Attribute Macro pallet_contracts_proc_macro::define_env
source · #[define_env]
Expand description
Defines a host functions set that can be imported by contract wasm code.
NB: Be advised that all functions defined by this macro will panic if called with unexpected arguments.
It’s up to you as the user of this macro to check signatures of wasm code to be executed and reject the code if any imported function has a mismatched signature.
Example
#[define_env]
pub mod some_env {
fn foo(ctx: _, memory: _, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<(), TrapReason> {
ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
}
}
This example will expand to the foo()
defined in the wasm module named seal0
. This is
because the module seal0
is the default when no module is specified.
To define a host function in seal2
and seal3
modules, it should be annotated with the
appropriate attribute as follows:
Example
#[define_env]
pub mod some_env {
#[version(2)]
fn foo(ctx: _, memory: _, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<ReturnCode, TrapReason> {
ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
}
#[version(3)]
#[unstable]
fn bar(ctx: _, memory: _, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<u32, TrapReason> {
ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
}
}
The function bar
is additionally annotated with unstable
which removes it from the stable
interface. Check out the README to learn about unstable functions.
In legacy versions of pallet_contracts, it was a naming convention that all host functions had
to be named with the seal_
prefix. For the sake of backwards compatibility, each host function
now can get a such prefix-named alias function generated by marking it by the
#[prefixed_alias]
attribute:
Example
#[define_env]
pub mod some_env {
#[version(1)]
#[prefixed_alias]
fn foo(ctx: _, memory: _, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<ReturnCode, TrapReason> {
ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
}
#[version(42)]
fn bar(ctx: _, memory: _, key_ptr: u32, value_ptr: u32, value_len: u32) -> Result<u32, TrapReason> {
ctx.some_host_fn(KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
}
}
In this example, the following host functions will be generated by the macro:
foo()
in moduleseal1
,seal_foo()
in moduleseal1
,bar()
in moduleseal42
.
Only following return types are allowed for the host functions defined with the macro:
Result<(), TrapReason>
,Result<ReturnCode, TrapReason>
,Result<u32, TrapReason>
.
The macro expands to pub struct Env
declaration, with the following traits implementations:
pallet_contracts::wasm::Environment<Runtime<E>> where E: Ext
pallet_contracts::wasm::Environment<()>
The implementation on ()
can be used in places where no Ext
exists, yet. This is useful
when only checking whether a code can be instantiated without actually executing any code.
Generating Documentation
Passing doc
attribute to the macro (like #[define_env(doc)]
) will make it also expand
additional pallet_contracts::api_doc::seal0
, pallet_contracts::api_doc::seal1
,
...
modules each having its Api
trait containing functions holding documentation for every
host function defined by the macro.
Deprecated Interfaces
An interface can be annotated with #[deprecated]
. It is mutually exclusive with #[unstable]
.
Deprecated interfaces have the following properties:
- New contract codes utilizing those interfaces cannot be uploaded.
- New contracts from existing codes utilizing those interfaces cannot be instantiated.
- Existing contracts containing those interfaces still work.
Those interfaces will eventually be removed.
To build up these docs, run:
cargo doc