Attribute Macro frame_support::pallet_macros::call
source · #[call]
Expand description
Allows a pallet to declare a set of functions as a dispatchable extrinsic.
In slightly simplified terms, this macro declares the set of “transactions” of a pallet.
The exact definition of extrinsic can be found in
sp_runtime::generic::UncheckedExtrinsic
.
A dispatchable is a common term in FRAME, referring to process of constructing a
function, and dispatching it with the correct inputs. This is commonly used with
extrinsics, for example “an extrinsic has been dispatched”. See
sp_runtime::traits::Dispatchable
and crate::traits::UnfilteredDispatchable
.
§Call Enum
The macro is called call
(rather than #[pallet::extrinsics]
) because of the
generation of a enum Call
. This enum contains only the encoding of the function
arguments of the dispatchable, alongside the information needed to route it to the
correct function.
#[frame_support::pallet(dev_mode)]
pub mod custom_pallet {
#[pallet::call]
impl<T: Config> Pallet<T> {
pub fn some_dispatchable(_origin: OriginFor<T>, _input: u32) -> DispatchResult {
Ok(())
}
pub fn other(_origin: OriginFor<T>, _input: u64) -> DispatchResult {
Ok(())
}
}
// generates something like:
// enum Call<T: Config> {
// some_dispatchable { input: u32 }
// other { input: u64 }
// }
}
fn main() {
construct_runtime! {
pub enum Runtime {
System: frame_system,
Custom: custom_pallet
}
}
let origin: RuntimeOrigin = frame_system::RawOrigin::Signed(10).into();
// calling into a dispatchable from within the runtime is simply a function call.
let _ = custom_pallet::Pallet::<Runtime>::some_dispatchable(origin.clone(), 10);
// calling into a dispatchable from the outer world involves constructing the bytes of
let call = custom_pallet::Call::<Runtime>::some_dispatchable { input: 10 };
let _ = call.clone().dispatch_bypass_filter(origin);
// the routing of a dispatchable is simply done through encoding of the `Call` enum,
// which is the index of the variant, followed by the arguments.
assert_eq!(call.encode(), vec![0u8, 10, 0, 0, 0]);
// notice how in the encoding of the second function, the first byte is different and
// referring to the second variant of `enum Call`.
let call = custom_pallet::Call::<Runtime>::other { input: 10 };
assert_eq!(call.encode(), vec![1u8, 10, 0, 0, 0, 0, 0, 0, 0]);
}
Further properties of dispatchable functions are as follows:
- Unless if annotated by
dev_mode
, it must containweight
to denote the pre-dispatch weight consumed. - The dispatchable must declare its index via
call_index
, which can override the position of a function inenum Call
. - The first argument is always an
OriginFor
(orT::RuntimeOrigin
). - The return type is always
crate::dispatch::DispatchResult
(orcrate::dispatch::DispatchResultWithPostInfo
).
WARNING: modifying dispatchables, changing their order (i.e. using call_index
),
removing some, etc., must be done with care. This will change the encoding of the , and
the call can be stored on-chain (e.g. in pallet-scheduler
). Thus, migration might be
needed. This is why the use of call_index
is mandatory by default in FRAME.
§Default Behavior
If no #[pallet::call]
exists, then a default implementation corresponding to the
following code is automatically generated:
#[frame_support::pallet(dev_mode)]
mod pallet {
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::call] // <- automatically generated
impl<T: Config> Pallet<T> {} // <- automatically generated
#[pallet::config]
pub trait Config: frame_system::Config {}
}
§Note on deprecation of Calls
- Usage of
deprecated
attribute will propagate deprecation information to the pallet metadata where the item was declared. - For general usage examples of
deprecated
attribute please refer to https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-deprecated-attribute
Documentation for this macro can be found at frame_support::pallet_macros::call
.