Skip to main content

ab_contracts_macros/
lib.rs

1//! Macros for contracts
2#![no_std]
3
4#[doc(hidden)]
5pub mod __private;
6
7/// `#[contract]` macro to derive contract implementation.
8///
9/// This macro is supposed to be applied to an implementation of the struct that in turn
10/// implements [`IoType`] trait. [`IoType`] is most commonly obtained by deriving
11/// [`TrivialType`] ([`IoType`] is implemented for all types that implement [`TrivialType`]).
12///
13/// `#[contract]` macro will process *public* methods annotated with the following attributes:
14/// * `#[init]` - a method that can be called to produce an initial state of the contract,
15///   called once during contacts lifetime
16/// * `#[update]` - a method that can read and/or modify state and/or slots of the contact;
17///   might be called by user transaction directly or by another contract
18/// * `#[view]` - a method that can only read blockchain data, can read state or slots of the
19///   contract, but can't modify their contents
20///
21/// Each argument (except `self`) of these methods has to be annotated with one of the
22/// following attributes (must be in this order):
23/// * `#[env]` - an environment variable, used to access ephemeral execution environment, call
24///   methods on other contracts, etc.
25/// * `#[tmp]` - a temporary ephemeral value to store auxiliary data while processing a
26///   transaction
27/// * `#[slot]` - a slot corresponding to this contract
28/// * `#[input]` - a method input coming from user transaction or invocation from another
29///   contract
30/// * `#[output]` - a method output serving as an alternative to returning values from a
31///   function directly, useful to reduce stack usage, its current contents provided by the
32///   caller can be read as well, which allows updating values in-place
33///
34/// Metadata of the state type and of `#[tmp]`, `#[slot]`, `#[input]`, `#[output]` and return
35/// types must not be nested deeper than [`MAX_METADATA_DEPTH`], which is checked during
36/// compilation.
37///
38/// Contents of `#[input]` arguments and initial contents of `#[output]` arguments come from
39/// the caller, so they are not trusted: before the method is called, generated code parses
40/// them (see [`IoType::try_from_ptr()`] and [`IoType::try_from_mut_ptr()`]) and returns
41/// [`ContractError::BadInput`] if they are not valid values of their types. The method only
42/// gets valid values, and for types that accept every bit pattern (see [`AnyBitPattern`])
43/// there is nothing to check. Sizes, capacities and alignment of these arguments must match
44/// the method's metadata, which the executor guarantees: the RISC-V VM checks them, while the
45/// native executor trusts callers and only catches mismatches with debug assertions. The state
46/// and `#[tmp]` and `#[slot]` arguments are storage of the contract, which is only written by
47/// the contract itself or on its behalf, so they are not parsed.
48///
49/// A method gets [`Env`] with a lifetime that covers its call. To lend an `#[output]` to calls
50/// with [`Env::lend_output()`], the method must declare the output with that lifetime:
51/// ```ignore
52/// #[update]
53/// pub fn forward<'a>(#[env] env: &mut Env<'a>, #[output] out: &'a mut Output) {
54///     let mut out = env.lend_output(out);
55///     // ...
56/// }
57/// ```
58///
59/// A `#[view]` method does the same with `&Env<'a>`. With elided lifetimes compilation will
60/// fail with "lifetime may not live long enough", and rustc will suggest the signature above.
61/// Lifetimes of the state, `#[tmp]` and `#[slot]` arguments, and of the last `#[output]` of
62/// `#[init]` without a return value, which is the initial state, can't be named: they are
63/// trusted without being parsed, so they must not be lent. This includes lifetimes of
64/// containers, like `'a` in `&mut MaybeData<'a, T>`, since a container can be moved out and
65/// lent too.
66///
67/// Containers like `MaybeData<'_, T>` and `VariableBytes<'_, N>` have a lifetime parameter,
68/// which arguments must write out, usually as `'_`. Generated code gives containers a lifetime
69/// that only covers the call, so the method can't keep a container after it returns. A method
70/// that declares a longer lifetime, like `'static`, doesn't compile, even if a type alias
71/// hides it.
72///
73/// # For struct implementation
74///
75/// ## #\[init]
76///
77/// Initializer's purpose is to produce the initial state of the contract.
78///
79/// The initial state is the return value (`Self` or `Result<Self, ContractError>`) or, without
80/// a return value, the last `#[output]`, which must be `MaybeData<'_, Self>`.
81///
82/// This method type supports the following arguments (must be in this order):
83/// * `#[env]` read-only and read-write
84/// * `#[tmp]` read-only and read-write
85/// * `#[slot]` read-only and read-write
86/// * `#[input]`
87/// * `#[output]`
88///
89/// `self` argument is not supported in any way in this context since the state of the contract
90/// is just being created.
91///
92/// ## #\[update]
93///
94/// Generic method contract that can both update the contract's own state and contents of
95/// slots.
96///
97/// This method type supports the following arguments (must be in this order):
98/// * `&self` or `&mut self` depending on whether state reads and/or modification are required
99/// * `#[env]` read-only and read-write
100/// * `#[tmp]` read-only and read-write
101/// * `#[slot]` read-only and read-write
102/// * `#[input]`
103/// * `#[output]`
104///
105/// ## #\[view]
106///
107/// Similar to `#[update]`, but can only access read-only view of the state and slots, can be
108/// called outside of the block context and can only call other `#[view]` methods.
109///
110/// This method type supports the following arguments (must be in this order):
111/// * `&self`
112/// * `#[env]` read-only
113/// * `#[slot]` read-only
114/// * `#[input]`
115/// * `#[output]`
116///
117/// # For trait definition and trait implementation
118///
119/// ## #\[update]
120///
121/// Generic method contract that can (in case of trait indirectly) both update the contract's
122/// own state and contents of slots.
123///
124/// This method type supports the following arguments in the trait context (must be in this
125/// order):
126/// * `#[env]` read-only and read-write
127/// * `#[input]`
128/// * `#[output]`
129///
130/// ## #\[view]
131///
132/// Similar to `#[update]`, but can only access (in case of trait indirectly) read-only view of
133/// the state and slots, can be called outside of the block context and can only call other
134/// `#[view]` methods.
135///
136/// This method type supports the following arguments in the trait context (must be in this
137/// order):
138/// * `#[env]` read-only
139/// * `#[input]`
140/// * `#[output]`
141///
142/// # Generated code
143///
144/// This macro will produce several key outputs:
145/// * [`Contract`] trait implementation (for struct implementation)
146/// * FFI function for every method, which can be used by the host to call into the guest
147///   environment (for struct and trait implementation)
148/// * `InternalArgs` struct corresponding to each method, used as its sole input for FFI
149///   function
150/// * Struct implementing [`ExternalArgs`] trait for each method, usable by other contracts to
151///   call into this contract through the host, host will interpret it based on metadata and
152///   generate `InternalArgs` (for struct and trait implementation, trait definitions)
153/// * Extension trait (for struct and trait implementation) that simplifies interaction with
154///   host and removes the need to construct [`ExternalArgs`] manually, providing nice strongly
155///   typed methods instead, implemented for [`Env`] struct (for struct and trait
156///   implementation, trait definitions)
157/// * Metadata as defined in [`ContractMetadataKind`] stored in the `ab-contract-metadata` link
158///   section when compiled with `guest` feature enabled (for method, struct, and trait
159///   implementation)
160///
161/// ## [`Contract`] trait implementation
162///
163/// [`Contract`] trait is required by a few other components in the system, so it is
164/// automatically implemented by the macro, see trait details.
165///
166/// ## FFI function
167///
168/// Macro generates an FFI function with C ABI that looks like this:
169/// ```ignore
170/// #[cfg_attr(feature = "guest", unsafe(no_mangle))]
171/// pub unsafe extern "C" fn {prefix}_{method}(
172///     args: &mut InternalArgs,
173/// ) -> ExitCode {
174///     // ...
175/// }
176/// ```
177///
178/// Where `{prefix}` is derived from struct or trait name and `{method}` is the original method
179/// name from struct or trait implementation.
180///
181/// Example with struct implementation:
182/// ```ignore
183/// // This
184/// #[contract]
185/// impl Example {
186///     #[view]
187///     pub fn hello() {}
188/// }
189///
190/// // Will generate this
191/// #[cfg_attr(feature = "guest", unsafe(no_mangle))]
192/// pub unsafe extern "C" fn example_hello(
193///     _: &mut InternalArgs,
194/// ) -> ExitCode {
195///     // ...
196/// }
197/// ```
198///
199/// Example with trait implementation:
200/// ```ignore
201/// // This
202/// #[contract]
203/// impl Fungible for Token {
204///     #[view]
205///     pub fn balance(#[slot] address: &Address) -> Balance {}
206/// }
207///
208/// // Will generate this
209/// #[cfg_attr(feature = "guest", unsafe(no_mangle))]
210/// pub unsafe extern "C" fn fungible_balance(
211///     args: &mut InternalArgs,
212/// ) -> ExitCode {
213///     // ...
214/// }
215/// ```
216///
217/// These generated functions are public and available in generated submodules, but there
218/// should generally be no need to call them directly.
219///
220/// ## `InternalArgs` struct
221///
222/// `InternalArgs` is generated for each method and is used as input to the above FFI
223/// functions. Its fields are generated based on function arguments, processing them in the
224/// same order as in function signature. It is possible for the host to build this data
225/// structure dynamically using available contact metadata.
226///
227/// Fields in the data structure are pointers, along with sizes and capacities where needed,
228/// some are read-only, some can be written to if changes need to be communicated back to the
229/// host. `read-only` here means that the host will not read the value, even if the contract
230/// modifies it.
231///
232/// ### `&self`
233///
234/// `&self` is a read-only state of the contract and generates three fields, all of which are
235/// read-only:
236/// ```ignore
237/// #[repr(C)]
238/// pub struct InternalArgs<'internal_args> {
239///     pub self_ptr: NonNull<<StructName as IoType>::PointerType>,
240///     pub self_size: u32,
241///     pub self_capacity: u32,
242///     // ...
243/// }
244/// ```
245///
246/// This allows a contract to read the current state of the contract.
247///
248/// ### `&mut self`
249///
250/// `&mut self` is a read-write state of the contract and generates three fields, `self_ptr`
251/// and `self_size` can be written to, while `self_capacity` is read-only:
252/// ```ignore
253/// #[repr(C)]
254/// pub struct InternalArgs<'internal_args> {
255///     pub self_ptr: NonNull<<StructName as IoType>::PointerType>,
256///     pub self_size: u32,
257///     pub self_capacity: u32,
258///     // ...
259/// }
260/// ```
261///
262/// This allows a contract to not only read, but also change the current state of the contract.
263/// `self_capacity` is defined by both the type used and the size of the value used (whichever
264/// is bigger in the case of variable-sized types) and corresponds to the amount of memory that
265/// host allocated for the guest behind `self_ptr`. In the case of variable-sized types, guest
266/// can replace `self_ptr` with a pointer to a guest-allocated region of memory that the host
267/// must read updated value from. This is helpful in case an increase of the value size beyond
268/// allocated capacity is needed.
269///
270/// ### `#[env] env: &Env`
271///
272/// `#[env] env: &Env` is for accessing an ephemeral environment with method calls restricted
273/// to `#[view]`. Since this is a system-provided data structure with a known layout, only
274/// read-only field is generated:
275/// ```ignore
276/// #[repr(C)]
277/// pub struct InternalArgs<'internal_args> {
278///     // ...
279///     pub env: &'internal_args Env<'internal_args>,
280///     // ...
281/// }
282/// ```
283///
284/// ### `#[env] env: &mut Env`
285///
286/// `#[env] env: &mut Env` is for accessing ephemeral environment without method calls
287/// restrictions. Since this is a system-provided data structure with a known layout, only
288/// read-write field is generated:
289/// ```ignore
290/// #[repr(C)]
291/// pub struct InternalArgs<'internal_args> {
292///     // ...
293///     pub env: &'internal_args mut Env<'internal_args>,
294///     // ...
295/// }
296/// ```
297///
298/// ### `#[tmp] tmp: &MaybeData<'_, Tmp>`
299///
300/// `#[tmp] tmp: &MaybeData<'_, Tmp>` is for accessing ephemeral value with auxiliary data and
301/// generates three fields, all of which are read-only:
302/// ```ignore
303/// #[repr(C)]
304/// pub struct InternalArgs<'internal_args> {
305///     // ...
306///     pub tmp_ptr: NonNull<
307///         <
308///             <StructName as Contract>::Tmp as IoType
309///         >::PointerType,
310///     >,
311///     pub tmp_size: u32,
312///     pub tmp_capacity: u32,
313///     // ...
314/// }
315/// ```
316///
317/// This allows a contract to read the current ephemeral value of the contract.
318///
319/// ### `#[tmp] tmp: &mut MaybeData<'_, Tmp>`
320///
321/// `#[tmp] tmp: &mut MaybeData<'_, Tmp>` is for accessing ephemeral value with auxiliary data
322/// and generates three fields, `tmp_ptr` and `tmp_size` can be written to, while
323/// `tmp_capacity` is read-only:
324/// ```ignore
325/// #[repr(C)]
326/// pub struct InternalArgs<'internal_args> {
327///     // ...
328///     pub tmp_ptr: NonNull<
329///         <
330///             <StructName as Contract>::Tmp as IoType
331///         >::PointerType,
332///     >,
333///     pub tmp_size: u32,
334///     pub tmp_capacity: u32,
335///     // ...
336/// }
337/// ```
338///
339/// This allows a contract to not only read, but also change the ephemeral value of the
340/// contract. `tmp_capacity` is defined by both the type used and the size of the value used
341/// (whichever is bigger in the case of variable-sized types) and corresponds to the amount of
342/// memory that host allocated for the guest behind `tmp_ptr`. In the case of variable-sized
343/// types, guest can replace `tmp_ptr` with a pointer to a guest-allocated region of memory
344/// that the host must read updated value from. This is helpful in case an increase of the
345/// value size beyond allocated capacity is needed.
346///
347/// ### `#[slot] slot: &MaybeData<'_, Slot>` and `#[slot] (address, slot): (&Address, &MaybeData<'_, Slot>)`
348///
349/// `#[slot] slot: &MaybeData<'_, Slot>` and its variant with explicit address argument is for
350/// accessing slot data (that corresponds to an optional `address` argument) and generates four
351/// fields, all of which are read-only:
352/// ```ignore
353/// #[repr(C)]
354/// pub struct InternalArgs<'internal_args> {
355///     // ...
356///     pub slot_address: &'internal_args Address,
357///     pub slot_ptr: NonNull<
358///         <
359///             <StructName as Contract>::Slot as IoType
360///         >::PointerType,
361///     >,
362///     pub slot_size: u32,
363///     pub slot_capacity: u32,
364///     // ...
365/// }
366/// ```
367///
368/// This allows a contract to read slot data.
369///
370/// ### `#[slot] slot: &mut MaybeData<'_, Slot>` and `#[slot] (address, slot): (&Address, &mut MaybeData<'_, Slot>)`
371///
372/// `#[slot] slot: &mut MaybeData<'_, Slot>` and its variant with explicit address argument are
373/// for accessing slot data (that corresponds to optional `address` argument) and generates
374/// four fields, `slot_ptr` and `slot_size` can be written to, while `slot_address` and
375/// `slot_capacity` are read-only:
376/// ```ignore
377/// #[repr(C)]
378/// pub struct InternalArgs<'internal_args> {
379///     // ...
380///     pub slot_address: &'internal_args Address,
381///     pub slot_ptr: NonNull<
382///         <
383///             <StructName as Contract>::Slot as IoType
384///         >::PointerType,
385///     >,
386///     pub slot_size: u32,
387///     pub slot_capacity: u32,
388///     // ...
389/// }
390/// ```
391///
392/// This allows a contract to not only read, but also change slot data.
393/// `slot_capacity` is defined by both the type used and the size of the value used (whichever
394/// is bigger in the case of variable-sized types) and corresponds to the amount of memory that
395/// host allocated for the guest behind `slot_ptr`. In the case of variable-sized types,
396/// guest can replace `slot_ptr` with a pointer to a guest-allocated region of memory that the
397/// host must read updated value from. This is helpful in case an increase of the value size
398/// beyond allocated capacity is needed.
399///
400/// Slot changes done by the method call will not be persisted if it returns an error or the
401/// host rejects its results (like an invalid slot size), including changes done by methods it
402/// called, even if those calls succeeded.
403///
404/// ### `#[input] input: &InputValue`
405///
406/// `#[input] input: &InputValue` is a read-only input to the contract call and generates three
407/// fields, all of which are read-only:
408/// ```ignore
409/// #[repr(C)]
410/// pub struct InternalArgs<'internal_args> {
411///     // ...
412///     pub input_ptr: NonNull<<InputValue as IoType>::PointerType>,
413///     pub input_size: u32,
414///     pub input_capacity: u32,
415///     // ...
416/// }
417/// ```
418///
419/// The contents are parsed before the method is called, [`ContractError::BadInput`] is
420/// returned if they are not a valid `InputValue`.
421///
422/// ### `#[output] output: &mut OutputValue`
423///
424/// `#[output] output: &mut OutputValue` is a read-write output of the contract call, where
425/// `OutputValue` is any type implementing [`IoType`], like `MaybeData<T>`, `VariableBytes<N>`
426/// or a [`TrivialType`]. It generates three fields, `output_size` can be written to, while
427/// `output_ptr` and `output_capacity` are read-only (see the exception for `#[init]` below):
428/// ```ignore
429/// #[repr(C)]
430/// pub struct InternalArgs<'internal_args> {
431///     // ...
432///     pub output_ptr: NonNull<<OutputValue as IoType>::PointerType>,
433///     pub output_size: u32,
434///     pub output_capacity: u32,
435///     // ...
436/// }
437/// ```
438///
439/// The caller provides `output_size` bytes of current contents of the output (bytes beyond the
440/// size are not initialized), the contract can both read and modify them, and the modified
441/// value will be propagated back to the caller to observe. The current contents are parsed
442/// like those of `#[input]` before the method is called. The size of a [`TrivialType`] output
443/// is always the size of the type, while `MaybeData<T>` and `VariableElements<T>` (like
444/// `VariableBytes<N>`) can be empty when they are only used to return a value. Unlike an
445/// input, an empty `MaybeData<T>` output must still have capacity for `T`, since the contract
446/// can write a value into it.
447/// `output_ptr` pointer *must not be changed* as the host will not follow it to the new
448/// address, the output size is fully constrained by capacity specified in `output_capacity`.
449/// The only exception is the last `#[output]` of `#[init]` method without a return value,
450/// which is the contract's initial state. In this case, its pointer can be changed to point to
451/// a different memory location, which is not limited by `output_capacity` allocation from the
452/// host, while the capacity the host provides must still be at least the size of the state,
453/// like that of other `MaybeData<T>` outputs. With a return value, the return value is the
454/// initial state, and all `#[output]` arguments are regular outputs.
455///
456/// `#[output]` may be used as an alternative to `-> ReturnValue` and
457/// `-> Result<ReturnValue, ContractError>` in case the data structure is large and allocation
458/// on the stack is undesirable, which is especially helpful in case of a variable-sized
459/// contract state.
460///
461/// ### `-> ReturnValue` and `-> Result<ReturnValue, ContractError>`
462///
463/// Return values (wrapped in `Result` or not) are only possible with [`TrivialType`] types,
464/// hence they don't need size and capacity as separate fields:
465/// ```ignore
466/// #[repr(C)]
467/// pub struct InternalArgs<'internal_args> {
468///     // ...
469///     pub ok_result: &'internal_args mut MaybeUninit<ReturnValue>,
470/// }
471/// ```
472///
473/// NOTE: In case `ReturnValue` in `-> ReturnValue` or `-> Result<ReturnValue, ContractError>`
474/// is `()`, it will be omitted in `InternalArgs`.
475///
476///
477/// ## [`ExternalArgs`] implementation
478///
479/// Macro generates a struct that implements [`ExternalArgs`] for each method that other
480/// contracts give to the host when they want to call into another (or even the same) contract.
481///
482/// Here is an example with struct implementation, but it works the same way with trait
483/// definition and implementation too:
484/// ```ignore
485/// // This
486/// #[contract]
487/// impl Example {
488///     #[view]
489///     pub fn hello() {}
490/// }
491///
492/// #[repr(C)]
493/// pub struct ExampleHelloArgs<'external_args> {
494///     // ...
495/// }
496///
497/// #[automatically_derived]
498/// unsafe impl ExternalArgs for ExampleHelloArgs {
499///     // ...
500/// }
501///
502/// impl ExternalArgs<'external_args> {
503///     pub fn new(
504///         // ...
505///     ) -> Self {
506///         // ...
507///     }
508/// }
509/// ```
510///
511/// Struct name if generated by concatenating struct or trait name on which name was generated,
512/// method name, and `Args` suffix, which is done to make it more convenient to use externally.
513///
514/// `&self`, `&mut self`, `#[env]` and `#[tmp]` arguments of the method are controlled fully by
515/// the host and not present in `ExternalArgs`.
516///
517/// `ExternalArgs::new()` method is generated for convenient construction of the instance,
518/// though in most cases [Extension trait] is used with a more convenient API. Fields are
519/// private and are only set by `ExternalArgs::new()`, since the host dereferences pointers in
520/// them according to the method signature. Each `#[output]` is given as `&mut impl
521/// OutputArg<OutputValue>` (see [Extension trait] for why), and its updated size can be read
522/// with an `output_size()` getter after the method call.
523///
524/// [Extension trait]: #extension-trait
525///
526/// ### `#[slot]`
527///
528/// Each `#[slot]` argument in `ExternalArgs` is represented by a single read-only address
529/// pointer:
530/// ```ignore
531/// #[repr(C)]
532/// pub struct ExternalArgs<'external_args> {
533///     // ...
534///     slot_ptr: NonNull<Address>,
535///     // ...
536/// }
537/// ```
538///
539/// ### `#[input]`
540///
541/// Each `#[input]` argument in `ExternalArgs` is represented by three read-only fields,
542/// a pointer to data, and size + capacity:
543/// ```ignore
544/// #[repr(C)]
545/// pub struct ExternalArgs<'external_args> {
546///     // ...
547///     input_ptr: NonNull<<InputValue as IoType>::PointerType>,
548///     input_size: u32,
549///     input_capacity: u32,
550///     // ...
551/// }
552/// ```
553///
554/// ### `#[output]`, `-> ReturnValue` and `-> Result<ReturnValue, ContractError>`
555///
556/// Each `#[output]` argument in `ExternalArgs` is represented by three fields, `output_ptr`
557/// and `output_capacity` are read-only, while `output_size` is updated by the host after the
558/// method call:
559/// ```ignore
560/// #[repr(C)]
561/// pub struct ExternalArgs<'external_args> {
562///     // ...
563///     output_ptr: NonNull<<OutputValue as IoType>::PointerType>,
564///     output_size: u32,
565///     output_capacity: u32,
566///     // ...
567/// }
568/// ```
569///
570/// Each return value is represented by just a pointer since return type is [`TrivialType`] and
571/// don't need separate size and capacity fields:
572/// ```ignore
573/// #[repr(C)]
574/// pub struct ExternalArgs<'external_args> {
575///     // ...
576///     ok_result: &'external_args mut MaybeUninit<ReturnValue>,
577/// }
578/// ```
579///
580/// Some arguments are omitted in `ExternalArgs`:
581/// * the contract's initial state produced by `#[init]` method, which is processed by the
582///   execution environment itself: `ReturnValue` or, when it is `()`, the last `#[output]`
583/// * `ReturnValue` when it is `()`, since there is no point in having a pointer for it
584///
585/// The host passes the current `output_size` to the callee as is, so that the callee can both
586/// read and modify the output, and updates `output_size` after the call.
587///
588/// ## Extension trait
589///
590/// Extension trait is just a convenient wrapper, whose safe methods take strongly typed
591/// arguments, construct `ExternalArgs` while respecting Rust safety invariants, and call
592/// [`Env::call()`] with it. Extension trait usage is not mandatory, but it does make method
593/// calls much more convenient in most simple cases.
594///
595/// Generated methods are named like FFI functions and take `&self` for `#[view]` methods and
596/// `&mut self` otherwise. Their arguments reflect `ExternalArgs` fields, preceded by the
597/// method context (except when calling a `#[view]` method, where context is not applicable)
598/// and the address of the contract being called:
599/// ```ignore
600/// // This
601/// #[contract]
602/// impl Token {
603///     #[view]
604///     pub fn balance(#[slot] target: &MaybeData<'_, Slot>) -> Balance {
605///         // ...
606///     }
607///
608///     #[view]
609///     pub fn balances(
610///         #[slot] target: &MaybeData<'_, Slot>,
611///         #[output] balances: &mut VariableElements<'_, Balance>,
612///     ) {
613///         // ...
614///     }
615///
616///     #[update]
617///     pub fn transfer(
618///         #[env] env: &mut Env<'_>,
619///         #[slot] (from_address, from): (&Address, &mut MaybeData<'_, Slot>),
620///         #[slot] to: &mut MaybeData<'_, Slot>,
621///         #[input] &amount: &Balance,
622///     ) -> Result<(), ContractError> {
623///         // ...
624///     }
625/// }
626///
627/// // Will generate this
628/// pub trait TokenExt {
629///     fn token_balance(
630///         &self,
631///         contract: Address,
632///         target: &Address,
633///     ) -> Result<Balance, ContractError>;
634///
635///     fn token_balances<'balances>(
636///         &self,
637///         contract: Address,
638///         target: &Address,
639///         balances: &mut impl OutputArg<VariableElements<'balances, Balance>>,
640///     ) -> Result<(), ContractError>;
641///
642///     fn token_transfer(
643///         &mut self,
644///         method_context: MethodContext,
645///         contract: Address,
646///         from: &Address,
647///         to: &Address,
648///         amount: &Balance,
649///     ) -> Result<(), ContractError>;
650/// }
651///
652/// impl TokenExt for Env<'_> {
653///     // ...
654/// }
655/// ```
656///
657/// Each `#[output]` is given as [`OutputArg`]. A call can leave contents behind in it that are
658/// not valid values, for example when it fails halfway. Memory whose contents accept every bit
659/// pattern (see [`AnyBitPattern`]) is given directly, like `&mut value` for a `u64` or
660/// `&mut VariableElements::from_uninit(..).expect(..)` for `VariableElements<Balance>`. Memory
661/// of other types is given in a [`Lent`], which parses the contents before they are accessed.
662/// After a successful call, the size of each output is set to the one the callee reported. The
663/// return value is parsed, and [`ContractError::BadOutput`] is returned if it is not a valid
664/// value of its type, with sizes of outputs already set.
665///
666/// An `#[output]` whose type has a lifetime parameter gets a lifetime named after it, like
667/// `'balances` above, since `'_` is not allowed in `impl Trait` in arguments.
668///
669/// The name of the extension trait is created as struct or trait name followed by `Ext`
670/// suffix.
671///
672/// ## Metadata
673///
674/// There are several places where metadata is being generated, see [`ContractMetadataKind`]
675/// for details.
676///
677/// First, the `#[contract]` macro generates a public `METADATA` constant for each method
678/// individually.
679///
680/// Second, for each trait that contract can implement `#[contract]` macro generates an
681/// associated constant `METADATA` that essentially aggregates metadata of all annotated
682/// methods.
683///
684/// Third, [`Contract`] trait implementation generated by `#[contract]` macro contains
685/// `MAIN_CONTRACT_METADATA` associated constant, which is similar in nature to `METADATA`
686/// constant for traits described above.
687///
688/// Lastly, for the whole contract as a project, both trait and contract metadata is
689/// concatenated and stored in the `ab-contract-metadata` link section that can later be
690/// inspected externally to understand everything about the contract's interfaces,
691/// auto-generate UI, etc.
692///
693/// [`Contract`]: ab_contracts_common::Contract
694/// [`ContractError::BadInput`]: ab_contracts_common::ContractError::BadInput
695/// [`ContractError::BadOutput`]: ab_contracts_common::ContractError::BadOutput
696/// [`OutputArg`]: ab_contracts_common::output::OutputArg
697/// [`Lent`]: ab_contracts_common::output::Lent
698/// [`TrivialType`]: ab_io_type::trivial_type::TrivialType
699/// [`AnyBitPattern`]: ab_io_type::trivial_type::AnyBitPattern
700/// [`IoType::try_from_ptr()`]: ab_io_type::IoType::try_from_ptr()
701/// [`IoType::try_from_mut_ptr()`]: ab_io_type::IoType::try_from_mut_ptr()
702/// [`IoType`]: ab_io_type::IoType
703/// [`ExternalArgs`]: ab_contracts_common::method::ExternalArgs
704/// [`Env`]: ab_contracts_common::env::Env
705/// [`Env::call()`]: ab_contracts_common::env::Env::call()
706/// [`Env::lend_output()`]: ab_contracts_common::env::Env::lend_output()
707/// [`ContractMetadataKind`]: ab_contracts_common::metadata::ContractMetadataKind
708/// [`MAX_METADATA_DEPTH`]: ab_contracts_common::metadata::MAX_METADATA_DEPTH
709pub use ab_contracts_macros_impl::contract;