Newer
Older
/// Specifying the argument `dev_mode` on the `#[pallet]` or `#[frame_support::pallet]`
/// attribute attached to your pallet module will allow you to enable dev mode for a pallet.
/// The aim of dev mode is to loosen some of the restrictions and requirements placed on
/// production pallets for easy tinkering and development. Dev mode pallets should not be used
/// in production. Enabling dev mode has the following effects:
///
/// * Weights no longer need to be specified on every `#[pallet::call]` declaration. By
/// default, dev mode pallets will assume a weight of zero (`0`) if a weight is not
/// specified. This is equivalent to specifying `#[weight(0)]` on all calls that do not
/// specify a weight.
/// * Call indices no longer need to be specified on every `#[pallet::call]` declaration. By
/// default, dev mode pallets will assume a call index based on the order of the call.
/// * All storages are marked as unbounded, meaning you do not need to implement
/// `MaxEncodedLen` on storage types. This is equivalent to specifying `#[pallet::unbounded]`
/// on all storage type definitions.
/// * Storage hashers no longer need to be specified and can be replaced by `_`. In dev mode,
/// these will be replaced by `Blake2_128Concat`. In case of explicit key-binding, `Hasher`
/// can simply be ignored when in `dev_mode`.
///
/// Note that the `dev_mode` argument can only be supplied to the `#[pallet]` or
/// `#[frame_support::pallet]` attribute macro that encloses your pallet module. This argument
/// cannot be specified anywhere else, including but not limited to the `#[pallet::pallet]`
/// attribute macro.
///
/// <div class="example-wrap" style="display:inline-block"><pre class="compile_fail"
/// style="white-space:normal;font:inherit;">
/// <strong>WARNING</strong>:
/// You should not deploy or use dev mode pallets in production. Doing so can break your chain
/// and therefore should never be done. Once you are done tinkering, you should remove the
/// 'dev_mode' argument from your #[pallet] declaration and fix any compile errors before
/// attempting to use your pallet in a production scenario.
/// </pre></div>
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Pallet struct placeholder: `#[pallet::pallet]` (mandatory)
///
/// The pallet struct placeholder `#[pallet::pallet]` is mandatory and allows you to specify
/// pallet information.
///
/// The struct must be defined as follows:
/// ```ignore
/// #[pallet::pallet]
/// pub struct Pallet<T>(_);
/// ```
/// I.e. a regular struct definition named `Pallet`, with generic T and no where clause.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
/// ## Macro expansion:
///
/// The macro adds this attribute to the struct definition:
/// ```ignore
/// #[derive(
/// frame_support::CloneNoBound,
/// frame_support::EqNoBound,
/// frame_support::PartialEqNoBound,
/// frame_support::RuntimeDebugNoBound,
/// )]
/// ```
/// and replaces the type `_` with `PhantomData<T>`. It also implements on the pallet:
/// * [`GetStorageVersion`](`traits::GetStorageVersion`)
/// * [`OnGenesis`](`traits::OnGenesis`): contains some logic to write the pallet version into
/// storage.
/// * `PalletErrorTypeInfo`: provides the type information for the pallet error, if defined.
///
/// It declares `type Module` type alias for `Pallet`, used by `construct_runtime`.
///
/// It implements [`PalletInfoAccess`](`traits::PalletInfoAccess') on `Pallet` to ease access
/// to pallet information given by [`frame_support::traits::PalletInfo`]. (The implementation
/// uses the associated type `frame_system::Config::PalletInfo`).
///
/// It implements [`StorageInfoTrait`](`traits::StorageInfoTrait`) on `Pallet` which give
/// information about all storages.
///
/// If the attribute `generate_store` is set then the macro creates the trait `Store` and
/// implements it on `Pallet`.
///
/// If the attribute `set_storage_max_encoded_len` is set then the macro calls
/// [`StorageInfoTrait`](`traits::StorageInfoTrait`) for each storage in the implementation of
/// [`StorageInfoTrait`](`traits::StorageInfoTrait`) for the pallet. Otherwise it implements
/// [`StorageInfoTrait`](`traits::StorageInfoTrait`) for the pallet using the
/// [`PartialStorageInfoTrait`](`traits::PartialStorageInfoTrait`) implementation of storages.
///
/// # Config trait: `#[pallet::config]` (mandatory)
///
/// The mandatory attribute `#[pallet::config]` defines the configurable options for the
/// pallet.
///
/// Item must be defined as:
///
/// ```ignore
/// #[pallet::config]
/// pub trait Config: frame_system::Config + $optionally_some_other_supertraits
/// $optional_where_clause
/// {
/// ...
/// }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// I.e. a regular trait definition named `Config`, with the supertrait
/// `frame_system::pallet::Config`, and optionally other supertraits and a where clause.
/// (Specifying other supertraits here is known as [tight
/// coupling](https://docs.substrate.io/reference/how-to-guides/pallet-design/use-tight-coupling/))
///
/// The associated type `RuntimeEvent` is reserved. If defined, it must have the bounds
/// `From<Event>` and `IsType<<Self as frame_system::Config>::RuntimeEvent>`.
///
/// [`pallet::event`](`frame_support::pallet_macros::event`) must be present if `RuntimeEvent`
/// exists as a config item in your `#[pallet::config]`.
///
/// Also see [`pallet::config`](`frame_support::pallet_macros::config`)
///
/// ## `pallet::constant`
///
/// The `#[pallet::constant]` attribute can be used to add an associated type trait bounded by
/// [`Get`](crate::traits::Get) from [`pallet::config`](#palletconfig) into metadata, e.g.:
///
/// ```ignore
/// #[pallet::config]
/// pub trait Config: frame_system::Config {
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// #[pallet::constant]
/// type Foo: Get<u32>;
/// }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::constant`](`frame_support::pallet_macros::constant`)
///
/// ## `pallet::disable_frame_system_supertrait_check`
/// <a name="disable_supertrait_check"></a>
///
/// To bypass the `frame_system::Config` supertrait check, use the attribute
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// `pallet::disable_frame_system_supertrait_check`, e.g.:
///
/// ```ignore
/// #[pallet::config]
/// #[pallet::disable_frame_system_supertrait_check]
/// pub trait Config: pallet_timestamp::Config {}
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// NOTE: Bypassing the `frame_system::Config` supertrait check is typically desirable when you
/// want to write an alternative to the `frame_system` pallet.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see
/// [`pallet::disable_frame_system_supertrait_check`](`frame_support::pallet_macros::disable_frame_system_supertrait_check`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// ## Macro expansion:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The macro expands pallet constant metadata with the information given by
/// `#[pallet::constant]`.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # `pallet::generate_store($vis trait Store)`
///
/// To generate a `Store` trait associating all storages, annotate your `Pallet` struct with
/// the attribute `#[pallet::generate_store($vis trait Store)]`, e.g.:
///
/// ```ignore
/// #[pallet::pallet]
/// #[pallet::generate_store(pub(super) trait Store)]
![thiolliere thiolliere's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
thiolliere
committed
/// pub struct Pallet<T>(_);
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// More precisely, the `Store` trait contains an associated type for each storage. It is
/// implemented for `Pallet` allowing access to the storage from pallet struct.
///
/// Thus when defining a storage named `Foo`, it can later be accessed from `Pallet` using
/// `<Pallet as Store>::Foo`.
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// NOTE: this attribute is only valid when applied _directly_ to your `Pallet` struct
/// definition.
///
/// Also see [`pallet::generate_store`](`frame_support::pallet_macros::generate_store`).
///
/// # `pallet::storage_version`
///
/// Because the [`pallet::pallet`](#pallet-struct-placeholder-palletpallet-mandatory) macro
/// implements [`traits::GetStorageVersion`], the current storage version needs to be
/// communicated to the macro. This can be done by using the `pallet::storage_version`
/// attribute:
///
/// ```ignore
/// const STORAGE_VERSION: StorageVersion = StorageVersion::new(5);
///
/// #[pallet::pallet]
/// #[pallet::storage_version(STORAGE_VERSION)]
/// pub struct Pallet<T>(_);
/// ```
///
/// If not present, the current storage version is set to the default value.
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::storage_version`](`frame_support::pallet_macros::storage_version`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Hooks: `#[pallet::hooks]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The `pallet::hooks` attribute allows you to specify a `Hooks` implementation for `Pallet`
/// that specifies pallet-specific logic.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The item the attribute attaches to must be defined as follows:
/// ```ignore
/// #[pallet::hooks]
/// impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> $optional_where_clause {
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// ...
/// }
/// ```
/// I.e. a regular trait implementation with generic bound: `T: Config`, for the trait
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// `Hooks<BlockNumberFor<T>>` (they are defined in preludes), for the type `Pallet<T>` and
/// with an optional where clause.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// If no `#[pallet::hooks]` exists, then the following default implementation is
/// automatically generated:
/// ```ignore
/// #[pallet::hooks]
/// impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::hooks`](`frame_support::pallet_macros::hooks`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Call: `#[pallet::call]` (optional)
///
/// Implementation of pallet dispatchables.
///
/// Item must be defined as:
/// ```ignore
/// #[pallet::call]
/// impl<T: Config> Pallet<T> {
/// /// $some_doc
/// #[pallet::weight($ExpressionResultingInWeight)]
/// origin: OriginFor<T>,
/// $some_arg: $some_type,
/// // or with compact attribute: #[pallet::compact] $some_arg: $some_type,
/// ...
/// ) -> DispatchResultWithPostInfo { // or `-> DispatchResult`
/// ...
/// }
/// ...
/// }
/// ```
/// I.e. a regular type implementation, with generic `T: Config`, on type `Pallet<T>`, with
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// an optional where clause.
///
/// ## `#[pallet::weight($expr)]`
///
/// Each dispatchable needs to define a weight with `#[pallet::weight($expr)]` attribute, the
/// first argument must be `origin: OriginFor<T>`.
///
/// Also see [`pallet::weight`](`frame_support::pallet_macros::weight`)
///
/// ### `#[pallet::compact] $some_arg: $some_type`
///
/// Compact encoding for arguments can be achieved via `#[pallet::compact]`. The function must
/// return a `DispatchResultWithPostInfo` or `DispatchResult`.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::compact`](`frame_support::pallet_macros::compact`)
///
/// ## `#[pallet::call_index($idx)]`
/// Each dispatchable may also be annotated with the `#[pallet::call_index($idx)]` attribute,
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// which explicitly defines the codec index for the dispatchable function in the `Call` enum.
///
/// All call indexes start from 0, until it encounters a dispatchable function with a defined
/// call index. The dispatchable function that lexically follows the function with a defined
/// call index will have that call index, but incremented by 1, e.g. if there are 3
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// dispatchable functions `fn foo`, `fn bar` and `fn qux` in that order, and only `fn bar`
/// has a call index of 10, then `fn qux` will have an index of 11, instead of 1.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// **WARNING**: modifying dispatchables, changing their order, removing some, etc., must be
/// done with care. Indeed this will change the outer runtime call type (which is an enum with
/// one variant per pallet), this outer runtime call can be stored on-chain (e.g. in
/// `pallet-scheduler`). Thus migration might be needed. To mitigate against some of this, the
/// `#[pallet::call_index($idx)]` attribute can be used to fix the order of the dispatchable so
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// that the `Call` enum encoding does not change after modification. As a general rule of
/// thumb, it is therefore adventageous to always add new calls to the end so you can maintain
/// the existing order of calls.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::call_index`](`frame_support::pallet_macros::call_index`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Extra constants: `#[pallet::extra_constants]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Allows you to define some extra constants to be added into constant metadata.
///
/// Item must be defined as:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::extra_constants]
/// impl<T: Config> Pallet<T> where $optional_where_clause {
/// /// $some_doc
/// $vis fn $fn_name() -> $some_return_type {
/// ...
/// }
/// ...
/// }
/// ```
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// I.e. a regular rust `impl` block with some optional where clause and functions with 0 args,
/// 0 generics, and some return type.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// ## Macro expansion
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The macro add some extra constants to pallet constant metadata.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see: [`pallet::extra_constants`](`frame_support::pallet_macros::extra_constants`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Error: `#[pallet::error]` (optional)
///
/// The `#[pallet::error]` attribute allows you to define an error enum that will be returned
/// from the dispatchable when an error occurs. The information for this error type is then
/// stored in metadata.
///
/// Item must be defined as:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::error]
/// pub enum Error<T> {
/// /// $some_optional_doc
/// $SomeFieldLessVariant,
/// /// $some_more_optional_doc
/// $SomeVariantWithOneField(FieldType),
/// ...
/// }
/// ```
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// I.e. a regular enum named `Error`, with generic `T` and fieldless or multiple-field
/// variants.
///
/// Any field type in the enum variants must implement [`scale_info::TypeInfo`] in order to be
/// properly used in the metadata, and its encoded size should be as small as possible,
/// preferably 1 byte in size in order to reduce storage size. The error enum itself has an
/// absolute maximum encoded size specified by [`MAX_MODULE_ERROR_ENCODED_SIZE`].
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// (1 byte can still be 256 different errors. The more specific the error, the easier it is to
/// diagnose problems and give a better experience to the user. Don't skimp on having lots of
/// individual error conditions.)
///
/// Field types in enum variants must also implement [`PalletError`](traits::PalletError),
/// otherwise the pallet will fail to compile. Rust primitive types have already implemented
/// the [`PalletError`](traits::PalletError) trait along with some commonly used stdlib types
/// such as [`Option`] and
/// [`PhantomData`](`frame_support::__private::sp_std::marker::PhantomData`), and hence in most
/// use cases, a manual implementation is not necessary and is discouraged.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The generic `T` must not bound anything and a `where` clause is not allowed. That said,
/// bounds and/or a where clause should not needed for any use-case.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see: [`pallet::error`](`frame_support::pallet_macros::error`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Event: `#[pallet::event]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Allows you to define pallet events. Pallet events are stored under the `system` / `events`
/// key when the block is applied (and then replaced when the next block writes it's events).
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The Event enum must be defined as follows:
///
/// ```ignore
/// #[pallet::event]
/// #[pallet::generate_deposit($visibility fn deposit_event)] // Optional
/// pub enum Event<$some_generic> $optional_where_clause {
/// /// Some doc
/// $SomeName($SomeType, $YetanotherType, ...),
/// ...
/// }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// I.e. an enum (with named or unnamed fields variant), named `Event`, with generic: none or
/// `T` or `T: Config`, and optional w here clause.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Each field must implement [`Clone`], [`Eq`], [`PartialEq`], [`Encode`], [`Decode`], and
/// [`Debug`] (on std only). For ease of use, bound by the trait
/// [`Member`](`frame_support::pallet_prelude::Member`), available in
/// frame_support::pallet_prelude.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::event`](`frame_support::pallet_macros::event`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// ## `#[pallet::generate_deposit($visibility fn deposit_event)]`
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The attribute `#[pallet::generate_deposit($visibility fn deposit_event)]` generates a
/// helper function on `Pallet` that handles deposit events.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// NOTE: For instantiable pallets, the event must be generic over `T` and `I`.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::generate_deposit`](`frame_support::pallet_macros::generate_deposit`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Storage: `#[pallet::storage]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The `#[pallet::storage]` attribute lets you define some abstract storage inside of runtime
/// storage and also set its metadata. This attribute can be used multiple times.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Item should be defined as:
///
/// ```ignore
/// #[pallet::storage]
/// #[pallet::getter(fn $getter_name)] // optional
/// $vis type $StorageName<$some_generic> $optional_where_clause
/// = $StorageType<$generic_name = $some_generics, $other_name = $some_other, ...>;
/// ```
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// or with unnamed generic:
///
/// ```ignore
/// #[pallet::storage]
/// #[pallet::getter(fn $getter_name)] // optional
/// $vis type $StorageName<$some_generic> $optional_where_clause
/// = $StorageType<_, $some_generics, ...>;
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
/// I.e. it must be a type alias, with generics: `T` or `T: Config`. The aliased type must be
/// one of [`StorageValue`](`pallet_prelude::StorageValue`),
/// [`StorageMap`](`pallet_prelude::StorageMap`) or
/// [`StorageDoubleMap`](`pallet_prelude::StorageDoubleMap`). The generic arguments of the
/// storage type can be given in two manners: named and unnamed. For named generic arguments,
/// the name for each argument should match the name defined for it on the storage struct:
/// * [`StorageValue`](`pallet_prelude::StorageValue`) expects `Value` and optionally
/// `QueryKind` and `OnEmpty`,
/// * [`StorageMap`](`pallet_prelude::StorageMap`) expects `Hasher`, `Key`, `Value` and
/// optionally `QueryKind` and `OnEmpty`,
/// * [`CountedStorageMap`](`pallet_prelude::CountedStorageMap`) expects `Hasher`, `Key`,
/// `Value` and optionally `QueryKind` and `OnEmpty`,
/// * [`StorageDoubleMap`](`pallet_prelude::StorageDoubleMap`) expects `Hasher1`, `Key1`,
/// `Hasher2`, `Key2`, `Value` and optionally `QueryKind` and `OnEmpty`.
///
/// For unnamed generic arguments: Their first generic must be `_` as it is replaced by the
/// macro and other generic must declared as a normal generic type declaration.
///
/// The `Prefix` generic written by the macro is generated using
/// `PalletInfo::name::<Pallet<..>>()` and the name of the storage type. E.g. if runtime names
/// the pallet "MyExample" then the storage `type Foo<T> = ...` should use the prefix:
/// `Twox128(b"MyExample") ++ Twox128(b"Foo")`.
///
/// For the [`CountedStorageMap`](`pallet_prelude::CountedStorageMap`) variant, the `Prefix`
/// also implements
/// [`CountedStorageMapInstance`](`frame_support::storage::types::CountedStorageMapInstance`).
/// It also associates a [`CounterPrefix`](`pallet_prelude::CounterPrefix'), which is
/// implemented the same as above, but the storage prefix is prepend with `"CounterFor"`. E.g.
/// if runtime names the pallet "MyExample" then the storage `type Foo<T> =
/// CountedStorageaMap<...>` will store its counter at the prefix: `Twox128(b"MyExample") ++
/// Twox128(b"CounterForFoo")`.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::storage]
/// pub(super) type MyStorage<T> = StorageMap<Hasher = Blake2_128Concat, Key = u32, Value = u32>;
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// In this case the final prefix used by the map is `Twox128(b"MyExample") ++
/// Twox128(b"OtherName")`.
///
/// Also see [`pallet::storage`](`frame_support::pallet_macros::storage`)
///
/// ## `#[pallet::getter(fn $my_getter_fn_name)]` (optional)
///
/// The optional attribute `#[pallet::getter(fn $my_getter_fn_name)]` allows you to define a
/// getter function on `Pallet`.
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::getter`](`frame_support::pallet_macros::getter`)
///
/// ## `#[pallet::storage_prefix = "SomeName"]` (optional)
///
/// The optional attribute `#[pallet::storage_prefix = "SomeName"]` allows you to define the
/// storage prefix to use, see how `Prefix` generic is implemented above. This is helpful if
/// you wish to rename the storage field but don't want to perform a migration.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::storage]
/// #[pallet::storage_prefix = "foo"]
/// #[pallet::getter(fn my_storage)]
/// pub(super) type MyStorage<T> = StorageMap<Hasher = Blake2_128Concat, Key = u32, Value = u32>;
/// ```
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// or
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::storage]
/// #[pallet::getter(fn my_storage)]
/// pub(super) type MyStorage<T> = StorageMap<_, Blake2_128Concat, u32, u32>;
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::storage_prefix`](`frame_support::pallet_macros::storage_prefix`)
///
/// ## `#[pallet::unbounded]` (optional)
///
/// The optional attribute `#[pallet::unbounded]` declares the storage as unbounded. When
/// implementating the storage info (when `#[pallet::generate_storage_info]` is specified on
/// the pallet struct placeholder), the size of the storage will be declared as unbounded. This
/// can be useful for storage which can never go into PoV (Proof of Validity).
///
/// Also see [`pallet::unbounded`](`frame_support::pallet_macros::unbounded`)
///
/// ## `#[pallet::whitelist_storage]` (optional)
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The optional attribute `#[pallet::whitelist_storage]` will declare the storage as
/// whitelisted from benchmarking.
///
/// See
/// [`pallet::whitelist_storage`](frame_support::pallet_macros::whitelist_storage)
/// for more info.
///
/// ## `#[cfg(..)]` (for storage)
/// The optional attributes `#[cfg(..)]` allow conditional compilation for the storage.
///
/// E.g:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[cfg(feature = "my-feature")]
/// #[pallet::storage]
/// pub(super) type MyStorage<T> = StorageValue<Value = u32>;
/// All the `cfg` attributes are automatically copied to the items generated for the storage,
/// i.e. the getter, storage prefix, and the metadata element etc.
/// Any type placed as the `QueryKind` parameter must implement
/// [`frame_support::storage::types::QueryKindTrait`]. There are 3 implementations of this
/// trait by default:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// 1. [`OptionQuery`](`frame_support::storage::types::OptionQuery`), the default `QueryKind`
/// used when this type parameter is omitted. Specifying this as the `QueryKind` would cause
/// storage map APIs that return a `QueryKind` to instead return an [`Option`], returning
/// `Some` when a value does exist under a specified storage key, and `None` otherwise.
/// 2. [`ValueQuery`](`frame_support::storage::types::ValueQuery`) causes storage map APIs that
/// return a `QueryKind` to instead return the value type. In cases where a value does not
/// exist under a specified storage key, the `OnEmpty` type parameter on `QueryKindTrait` is
/// used to return an appropriate value.
/// 3. [`ResultQuery`](`frame_support::storage::types::ResultQuery`) causes storage map APIs
/// that return a `QueryKind` to instead return a `Result<T, E>`, with `T` being the value
/// type and `E` being the pallet error type specified by the `#[pallet::error]` attribute.
/// In cases where a value does not exist under a specified storage key, an `Err` with the
/// specified pallet error variant is returned.
/// NOTE: If the `QueryKind` generic parameter is still generic at this stage or is using some
/// type alias then the generation of the getter might fail. In this case the getter can be
/// implemented manually.
/// NOTE: The generic `Hasher` must implement the [`StorageHasher`] trait (or the type is not
/// usable at all). We use [`StorageHasher::METADATA`] for the metadata of the hasher of the
/// storage item. Thus generic hasher is supported.
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// ## Macro expansion
/// For each storage item the macro generates a struct named
/// `_GeneratedPrefixForStorage$NameOfStorage`, and implements
/// [`StorageInstance`](traits::StorageInstance) on it using the pallet and storage name. It
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// then uses it as the first generic of the aliased type. For
/// [`CountedStorageMap`](`pallet_prelude::CountedStorageMap`),
/// [`CountedStorageMapInstance`](`frame_support::storage::types::CountedStorageMapInstance`)
/// is implemented, and another similar struct is generated.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// For a named generic, the macro will reorder the generics, and remove the names.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The macro implements the function `storage_metadata` on the `Pallet` implementing the
/// metadata for all storage items based on their kind:
/// * for a storage value, the type of the value is copied into the metadata
/// * for a storage map, the type of the values and the key's type is copied into the metadata
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// * for a storage double map, the type of the values, and the types of `key1` and `key2` are
/// copied into the metadata.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Type value: `#[pallet::type_value]` (optional)
///
/// The `#[pallet::type_value]` attribute lets you define a struct implementing the
/// [`Get`](crate::traits::Get) trait to ease use of storage types. This attribute is meant to
/// be used alongside [`#[pallet::storage]`](#storage-palletstorage-optional) to define a
/// storage's default value. This attribute can be used multiple times.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Item must be defined as:
///
/// ```ignore
/// #[pallet::type_value]
/// fn $MyDefaultName<$some_generic>() -> $default_type $optional_where_clause { $expr }
/// ```
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// I.e.: a function definition with generics none or `T: Config` and a returned type.
///
/// E.g.:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::type_value]
/// fn MyDefault<T: Config>() -> T::Balance { 3.into() }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::type_value`](`frame_support::pallet_macros::type_value`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Genesis config: `#[pallet::genesis_config]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The `#[pallet::genesis_config]` attribute allows you to define the genesis configuration
/// for the pallet.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Item is defined as either an enum or a struct. It needs to be public and implement the
/// trait [`BuildGenesisConfig`](`traits::BuildGenesisConfig`) with
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// [`#[pallet::genesis_build]`](#genesis-build-palletgenesis_build-optional). The type
/// generics are constrained to be either none, or `T` or `T: Config`.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::genesis_config]
/// pub struct GenesisConfig<T: Config> {
/// _myfield: BalanceOf<T>,
/// }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::genesis_config`](`frame_support::pallet_macros::genesis_config`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Genesis build: `#[pallet::genesis_build]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The `#[pallet::genesis_build]` attribute allows you to define how `genesis_configuration`
/// is built. This takes as input the `GenesisConfig` type (as `self`) and constructs the
/// pallet's initial state.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The impl must be defined as:
///
/// ```ignore
/// #[pallet::genesis_build]
/// impl<T: Config> GenesisBuild<T> for GenesisConfig<$maybe_generics> {
/// fn build(&self) { $expr }
/// }
/// ```
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// I.e. a trait implementation with generic `T: Config`, of trait `GenesisBuild<T>` on
/// type `GenesisConfig` with generics none or `T`.
///
/// E.g.:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::genesis_build]
/// impl<T: Config> GenesisBuild<T> for GenesisConfig {
/// fn build(&self) {}
/// }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::genesis_build`](`frame_support::pallet_macros::genesis_build`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Inherent: `#[pallet::inherent]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The `#[pallet::inherent]` attribute allows the pallet to provide some
/// [inherent](https://docs.substrate.io/fundamentals/transaction-types/#inherent-transactions).
/// An inherent is some piece of data that is inserted by a block authoring node at block
/// creation time and can either be accepted or rejected by validators based on whether the
/// data falls within an acceptable range.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The most common inherent is the `timestamp` that is inserted into every block. Since there
/// is no way to validate timestamps, validators simply check that the timestamp reported by
/// the block authoring node falls within an acceptable range.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Item must be defined as:
///
/// ```ignore
/// #[pallet::inherent]
/// impl<T: Config> ProvideInherent for Pallet<T> {
/// // ... regular trait implementation
/// }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// I.e. a trait implementation with bound `T: Config`, of trait
/// [`ProvideInherent`](`pallet_prelude::ProvideInherent`) for type `Pallet<T>`, and some
/// optional where clause.
///
/// Also see [`pallet::inherent`](`frame_support::pallet_macros::inherent`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Validate unsigned: `#[pallet::validate_unsigned]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The `#[pallet::validate_unsigned]` attribute allows the pallet to validate some unsigned
/// transaction:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Item must be defined as:
///
/// ```ignore
/// #[pallet::validate_unsigned]
/// impl<T: Config> ValidateUnsigned for Pallet<T> {
/// // ... regular trait implementation
/// }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// I.e. a trait implementation with bound `T: Config`, of trait
/// [`ValidateUnsigned`](`pallet_prelude::ValidateUnsigned`) for type `Pallet<T>`, and some
/// optional where clause.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// NOTE: There is also the [`sp_runtime::traits::SignedExtension`] trait that can be used to
/// add some specific logic for transaction validation.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::validate_unsigned`](`frame_support::pallet_macros::validate_unsigned`)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Origin: `#[pallet::origin]` (optional)
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// The `#[pallet::origin]` attribute allows you to define some origin for the pallet.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Item must be either a type alias, an enum, or a struct. It needs to be public.
///
/// E.g.:
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
///
/// ```ignore
/// #[pallet::origin]
/// pub struct Origin<T>(PhantomData<(T)>);
/// ```
///
/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// can be stored on-chain (e.g. in `pallet-scheduler`), thus any change must be done with care
/// as it might require some migration.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// NOTE: for instantiable pallets, the origin must be generic over `T` and `I`.
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// Also see [`pallet::origin`](`frame_support::pallet_macros::origin`)
/// # Composite enum `#[pallet::composite_enum]` (optional)
/// The `#[pallet::composite_enum]` attribute allows you to define an enum on the pallet which
/// will then instruct `construct_runtime` to amalgamate all similarly-named enums from other
/// pallets into an aggregate enum. This is similar in principle with how the aggregate enum is
/// generated for `#[pallet::event]` or `#[pallet::error]`.
///
/// The item tagged with `#[pallet::composite_enum]` MUST be an enum declaration, and can ONLY
/// be the following identifiers: `FreezeReason`, `HoldReason`, `LockId` or `SlashReason`.
/// Custom identifiers are not supported.
///
/// NOTE: For ease of usage, when no `#[derive]` attributes are detected, the
/// `#[pallet::composite_enum]` attribute will automatically derive the following traits for
/// the enum:
///
/// ```ignore
/// Copy, Clone, Eq, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo, RuntimeDebug
/// ```
///
/// The inverse is also true: if there are any #[derive] attributes present for the enum, then
/// the attribute will not automatically derive any of the traits described above.
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # General notes on instantiable pallets
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// An instantiable pallet is one where Config is generic, i.e. `Config<I>`. This allows
/// runtime to implement multiple instances of the pallet, by using different types for the
/// generic. This is the sole purpose of the generic `I`, but because
/// [`PalletInfo`](`traits::PalletInfo`) requires the `Pallet` placeholder to be static, it is
/// important to bound by `'static` whenever [`PalletInfo`](`traits::PalletInfo`) can be used.
/// Additionally, in order to make an instantiable pallet usable as a regular pallet without an
/// instance, it is important to bound by `= ()` on every type.
///
/// Thus impl bound looks like `impl<T: Config<I>, I: 'static>`, and types look like
/// `SomeType<T, I=()>` or `SomeType<T: Config<I>, I: 'static = ()>`.
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Example of a non-instantiable pallet
/// pub use pallet::*; // reexport in crate namespace for `construct_runtime!`
///
/// #[frame_support::pallet]
/// // NOTE: The name of the pallet is provided by `construct_runtime` and is used as
/// // the unique identifier for the pallet's storage. It is not defined in the pallet itself.
/// pub mod pallet {
/// use frame_support::pallet_prelude::*; // Import various types used in the pallet definition
/// use frame_system::pallet_prelude::*; // Import some system helper types.
///
/// type BalanceOf<T> = <T as Config>::Balance;
///
/// // Define the generic parameter of the pallet
/// // The macro parses `#[pallet::constant]` attributes and uses them to generate metadata
/// // for the pallet's constants.
/// #[pallet::config]
/// pub trait Config: frame_system::Config {
/// #[pallet::constant] // put the constant in metadata
/// type MyGetParam: Get<u32>;
/// type Balance: Parameter + MaxEncodedLen + From<u8>;
/// type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
/// }
///
/// // Define some additional constant to put into the constant metadata.
/// #[pallet::extra_constants]
/// impl<T: Config> Pallet<T> {
/// /// Some description
/// fn exra_constant_name() -> u128 { 4u128 }
/// }
///
/// // Define the pallet struct placeholder, various pallet function are implemented on it.
/// #[pallet::pallet]
/// #[pallet::generate_store(pub(super) trait Store)]
![thiolliere thiolliere's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
thiolliere
committed
/// pub struct Pallet<T>(_);
/// #[pallet::hooks]
/// impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
/// fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
/// unimplemented!();
/// }
///
/// // can implement also: on_finalize, on_runtime_upgrade, offchain_worker, ...
/// // see `Hooks` trait
/// }
///
/// // Declare Call struct and implement dispatchables.
/// //
/// // WARNING: Each parameter used in functions must implement: Clone, Debug, Eq, PartialEq,
/// // Codec.
/// //
/// // The macro parses `#[pallet::compact]` attributes on function arguments and implements
/// // the `Call` encoding/decoding accordingly.
/// #[pallet::call]
/// impl<T: Config> Pallet<T> {
/// /// Doc comment put in metadata
/// #[pallet::weight(0)] // Defines weight for call (function parameters are in scope)
/// origin: OriginFor<T>,
/// ) -> DispatchResultWithPostInfo {
/// let _ = origin;
/// unimplemented!();
/// }
/// }
///
/// // Declare the pallet `Error` enum (this is optional).
/// // The macro generates error metadata using the doc comment on each variant.
/// #[pallet::error]
/// pub enum Error<T> {
/// /// doc comment put into metadata
/// InsufficientProposersBalance,
/// }
///
/// // Declare pallet Event enum (this is optional).
/// //
/// // WARNING: Each type used in variants must implement: Clone, Debug, Eq, PartialEq, Codec.
/// //
/// // The macro generates event metadata, and derive Clone, Debug, Eq, PartialEq and Codec
/// #[pallet::event]
/// // Generate a funciton on Pallet to deposit an event.
/// #[pallet::generate_deposit(pub(super) fn deposit_event)]
/// pub enum Event<T: Config> {
/// /// doc comment put in metadata
/// // `<T as frame_system::Config>::AccountId` is not defined in metadata list, the last
/// // Thus the metadata is `<T as frame_system::Config>::AccountId`.
/// Proposed(<T as frame_system::Config>::AccountId),
/// /// doc
/// // here metadata will be `Balance` as define in metadata list
/// Spending(BalanceOf<T>),
/// // here metadata will be `Other` as define in metadata list
/// Something(u32),
/// }
///
/// // Define a struct which implements `frame_support::traits::Get<T::Balance>` (optional).
/// #[pallet::type_value]
/// pub(super) fn MyDefault<T: Config>() -> T::Balance { 3.into() }
///
/// // Declare a storage item. Any amount of storage items can be declared (optional).
/// //
/// // Is expected either `StorageValue`, `StorageMap` or `StorageDoubleMap`.
/// // The macro generates the prefix type and replaces the first generic `_`.
/// //
/// // The macro expands the metadata for the storage item with the type used:
/// // * for a storage value the type of the value is copied into the metadata
/// // * for a storage map the type of the values and the type of the key is copied into the metadata
/// // * for a storage double map the types of the values and keys are copied into the
/// // metadata.
/// //
/// // NOTE: The generic `Hasher` must implement the `StorageHasher` trait (or the type is not
/// // usable at all). We use [`StorageHasher::METADATA`] for the metadata of the hasher of the
/// // storage item. Thus generic hasher is supported.
/// #[pallet::storage]
/// pub(super) type MyStorageValue<T: Config> =
/// StorageValue<Value = T::Balance, QueryKind = ValueQuery, OnEmpty = MyDefault<T>>;
/// #[pallet::storage]
/// #[pallet::getter(fn my_storage)]
/// #[pallet::storage_prefix = "SomeOtherName"]
/// pub(super) type MyStorage<T> =
/// StorageMap<Hasher = Blake2_128Concat, Key = u32, Value = u32>;
/// // Declare the genesis config (optional).
/// // The macro accepts either a struct or an enum; it checks that generics are consistent.
/// // Type must implement the `Default` trait.
/// #[pallet::genesis_config]
/// #[derive(frame_support::DefaultNoBound)]
/// pub struct GenesisConfig<T: Config> {
/// _config: sp_std::marker::PhantomData<T>,
/// _myfield: u32,
/// }
///
/// // Declare genesis builder. (This is need only if GenesisConfig is declared)
/// #[pallet::genesis_build]
/// impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
/// fn build(&self) {}
/// }
///
/// // Declare a pallet origin (this is optional).
/// //
/// // The macro accept type alias or struct or enum, it checks generics are consistent.
/// #[pallet::origin]
/// pub struct Origin<T>(PhantomData<T>);
///
/// // Declare a hold reason (this is optional).
/// //
/// // Creates a hold reason for this pallet that is aggregated by `construct_runtime`.
/// // A similar enum can be defined for `FreezeReason`, `LockId` or `SlashReason`.
/// #[pallet::composite_enum]
/// pub enum HoldReason {
/// SomeHoldReason
/// }
///
/// // Declare validate_unsigned implementation (this is optional).
/// #[pallet::validate_unsigned]
/// impl<T: Config> ValidateUnsigned for Pallet<T> {
/// type Call = Call<T>;
/// fn validate_unsigned(
/// source: TransactionSource,
/// call: &Self::Call
/// ) -> TransactionValidity {
/// Err(TransactionValidityError::Invalid(InvalidTransaction::Call))
/// }
/// }
///
/// // Declare inherent provider for pallet (this is optional).
/// #[pallet::inherent]
/// impl<T: Config> ProvideInherent for Pallet<T> {
/// type Call = Call<T>;
/// type Error = InherentError;
///
/// const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
///
/// fn create_inherent(_data: &InherentData) -> Option<Self::Call> {
/// unimplemented!();
/// }
///
/// fn is_inherent(_call: &Self::Call) -> bool {
/// unimplemented!();
/// }
/// }
///
/// // Regular rust code needed for implementing ProvideInherent trait
///
/// #[derive(codec::Encode, sp_runtime::RuntimeDebug)]
/// #[cfg_attr(feature = "std", derive(codec::Decode))]
/// pub enum InherentError {
/// }
///
/// impl sp_inherents::IsFatalError for InherentError {
/// fn is_fatal_error(&self) -> bool {
/// unimplemented!();
/// }
/// }
///
/// pub const INHERENT_IDENTIFIER: sp_inherents::InherentIdentifier = *b"testpall";
/// }
/// ```
///
![Sam Johnson Sam Johnson's avatar](/assets/no_avatar-849f9c04a3a0d0cea2424ae97b27447dc64a7dbfae83c036c45b403392f0e8ba.png)
Sam Johnson
committed
/// # Example of an instantiable pallet
/// #[frame_support::pallet]
/// pub mod pallet {
/// use frame_support::pallet_prelude::*;
/// use frame_system::pallet_prelude::*;
///
/// type BalanceOf<T, I = ()> = <T as Config<I>>::Balance;
///
/// #[pallet::config]
/// pub trait Config<I: 'static = ()>: frame_system::Config {
/// #[pallet::constant]
/// type MyGetParam: Get<u32>;
/// type Balance: Parameter + MaxEncodedLen + From<u8>;
/// type RuntimeEvent: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
/// }
///
/// #[pallet::extra_constants]
/// impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// /// Some description
/// fn extra_constant_name() -> u128 { 4u128 }
/// }
///
/// #[pallet::pallet]
/// #[pallet::generate_store(pub(super) trait Store)]
/// pub struct Pallet<T, I = ()>(PhantomData<(T, I)>);
///
/// #[pallet::hooks]
/// impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
/// }
///
/// #[pallet::call]
/// impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// /// Doc comment put in metadata
/// #[pallet::weight(0)]
/// pub fn toto(origin: OriginFor<T>, #[pallet::compact] _foo: u32) -> DispatchResultWithPostInfo {
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
/// let _ = origin;
/// unimplemented!();
/// }
/// }
///
/// #[pallet::error]
/// pub enum Error<T, I = ()> {
/// /// doc comment put into metadata
/// InsufficientProposersBalance,
/// }
///
/// #[pallet::event]
/// #[pallet::generate_deposit(pub(super) fn deposit_event)]
/// pub enum Event<T: Config<I>, I: 'static = ()> {
/// /// doc comment put in metadata
/// Proposed(<T as frame_system::Config>::AccountId),
/// /// doc
/// Spending(BalanceOf<T, I>),
/// Something(u32),
/// }
///
/// #[pallet::type_value]
/// pub(super) fn MyDefault<T: Config<I>, I: 'static>() -> T::Balance { 3.into() }
///
/// #[pallet::storage]