Declaring a constant value in a runtime is a useful tool to either define fixed values or define values that change dynamically according to some factor. This guide shows you how to create pallet constants that are used to reset a u32 value in storage. This value, we'll call SingleValue, can also be modified using a method called add_value.
Configure your pallet's types, events and errors
Define the constants in your pallet.
MaxAddend will be the value displayed in metadata.
ClearFrequency keeps track of the block numbers and will be used to reset SingleValue.
#[pallet::config]pubtraitConfig: frame_system::Config {typeRuntimeEvent:From<Event<Self>> +IsType<<Self as frame_system::Config>::RuntimeEvent>; #[pallet::constant] // put the constant in metadata/// Maximum amount added per invocation.typeMaxAddend:Get<u32>;/// Frequency with which the stored value is deleted.typeClearFrequency:Get<Self::BlockNumber>;}
Declare your storage items and events.
Using the storage attribute macro, declare SingleValue, the value that gets modified every block cycle.
#[pallet::event]#[pallet::generate_deposit(pub(super) fn deposit_event)]pubenumEvent<T:Config> {/// The value has been added to. The parameters are/// (initial amount, amount added, final amount).Added(u32, u32, u32),/// The value has been cleared. The parameter is the value before clearing.Cleared(u32)}
Add an error that handles operation overflow:
#[pallet::error]pubenumError<T> {/// An operation would lead to an overflow.Overflow}
Create pallet methods and runtime constants
Configure on_finalize.
SingleValue is set to 0 every ClearFrequency number of blocks in the on_finalize function that runs at the end of block execution. Specify this logic under the #[pallet::hooks] attribute:
Create a method that allows users to specify the value.
The add_value method increases SingleValue so long as each call adds to less than the MaxAddend value.
For this method you must:
Include checks.
Keep track of the previous value.
Check for overflow.
Update SingleValue.
// Extrinsics callable from outside the runtime.#[pallet::call]impl<T:Config> Pallet<T> { #[pallet::weight(1_000)]fnadd_value( origin:OriginFor<T>, val_to_add:u32 ) ->DispatchResultWithPostInfo {let _ =ensure_signed(origin)?;ensure!(val_to_add <=T::MaxAddend::get(), "value must be <= maximum add amount constant");// previous value gotlet c_val =SingleValue::<T>::get();// checks for overflow when new value addedlet result = c_val.checked_add(val_to_add).ok_or(Error::<T>::Overflow)?; <SingleValue<T>>::put(result); Self::deposit_event(Event::Added(c_val, val_to_add, result));Ok(().into()) }}
Supply the constant value for your runtime.
In runtime/src/lib.rs, declare the values for your pallet's runtime implementation of MaxAddend and ClearFrequency: