// This file is part of Bizinikiwi. // Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute // SPDX-License-Identifier: MIT-0 // Permission is hereby granted, free of charge, to any person obtaining a copy of // this software and associated documentation files (the "Software"), to deal in // the Software without restriction, including without limitation the rights to // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is furnished to do // so, subject to the following conditions: // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. //! # Kitchensink Example Pezpallet //! //! **This pezpallet serves as an example and is not meant to be used in production.** //! //! The kitchen-sink catalog of the the FRAME macros and their various syntax options. //! //! This example does not focus on pezpallet instancing, `dev_mode`, and does nto include any //! 'where' clauses on `T`. These will both incur additional complexity to the syntax, but are not //! discussed here. #![cfg_attr(not(feature = "std"), no_std)] // Re-export pezpallet items so that they can be accessed from the crate namespace. pub use pezpallet::*; #[cfg(test)] mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; #[cfg(feature = "try-runtime")] use pezsp_runtime::TryRuntimeError; pub mod weights; pub use weights::*; extern crate alloc; #[pezframe_support::pezpallet] pub mod pezpallet { use super::*; use pezframe_support::pezpallet_prelude::*; use pezframe_system::pezpallet_prelude::*; /// The config trait of the pezpallet. You can basically do anything with the config trait that /// you can do with a normal rust trait: import items consisting of types, constants and /// functions. /// /// A very common pattern is for a pezpallet to import implementations of traits such as /// [`pezframe_support::traits::Currency`], [`pezframe_support::traits::fungibles::Inspect`] and /// [`pezframe_support::traits::Get`]. These are all types that the pezpallet is delegating to /// the top level runtime to provide to it. /// /// The `FRAME`-specific syntax are: /// /// * the use of `#[pezpallet::constant]`([`pezframe_support::procedural`]), which places a /// `Get` implementation in the metadata. /// * `type RuntimeEvent`, which is mandatory if your pezpallet has events. See TODO. /// * Needless to say, because [`Config`] is bounded by [`pezframe_system::Config`], you can use /// all the items from [`pezframe_system::Config`] as well, such as `AccountId`. /// * `#[pezpallet::disable_pezframe_system_supertrait_check]` would remove the need for /// `pezframe_system::Config` to exist, which you should almost never need. #[pezpallet::config] pub trait Config: pezframe_system::Config { /// Type representing the weight of this pezpallet type WeightInfo: WeightInfo; /// This is a normal Rust type, nothing specific to FRAME here. type Currency: pezframe_support::traits::fungible::Inspect; /// Similarly, let the runtime decide this. fn some_function() -> u32; /// And this const FOO: u32; /// This is a FRAME-specific item. It will be placed in the metadata of the pezpallet, and /// therefore can be queried by offchain applications. #[pezpallet::constant] type InMetadata: Get; } /// Allows you to define some extra constants to be added into constant metadata. #[pezpallet::extra_constants] impl Pezpallet { #[allow(non_snake_case)] fn SomeValue() -> u32 { unimplemented!() } #[pezpallet::constant_name(OtherValue)] fn arbitrary_name() -> u32 { unimplemented!() } } const STORAGE_VERSION: pezframe_support::traits::StorageVersion = StorageVersion::new(1); /// The pezpallet struct. There's nothing special to FRAME about this; it can implement /// functions in an impl blocks, traits and so on. #[pezpallet::pezpallet] #[pezpallet::without_storage_info] #[pezpallet::storage_version(STORAGE_VERSION)] pub struct Pezpallet(_); /// Allows you to define some origin for the pezpallet. #[pezpallet::origin] pub type Origin = pezframe_system::RawOrigin<::AccountId>; // first, we showcase all the possible storage types, with most of their details. /// A storage value. We mark this as unbounded, alter its prefix, and define a custom storage /// getter for it. /// /// The value is stored a single trie node, and therefore can be retrieved with a single /// database access. #[pezpallet::storage] #[pezpallet::unbounded] // optional #[pezpallet::storage_prefix = "OtherFoo"] // optional pub type Foo = StorageValue; #[pezpallet::type_value] pub fn DefaultForFoo() -> u32 { 1 } #[pezpallet::storage] pub type FooWithDefault = StorageValue; /// A storage map. This creates a mapping from keys of type `u32` to values of type `u32`. /// /// Keys and values can be iterated, albeit each value is stored under a unique trie key, /// meaning that an iteration consists of many database accesses. #[pezpallet::storage] pub type Bar = StorageMap; /// Conceptually same as `StorageMap<>` where the key is a tuple of `(u32, u32)`. On top, it /// provides some functions to iterate or remove items based on only the first key. #[pezpallet::storage] pub type Qux = StorageDoubleMap< Hasher1 = Blake2_128Concat, Key1 = u32, Hasher2 = Blake2_128Concat, Key2 = u32, Value = u32, >; /// Same as `StorageDoubleMap`, but with arbitrary number of keys. #[pezpallet::storage] pub type Quux = StorageNMap< Key = ( NMapKey, NMapKey, NMapKey, ), Value = u64, >; /// In all of these examples, we chose a syntax where the storage item is defined using the /// explicit generic syntax (`X = Y`). Alternatively: #[pezpallet::storage] pub type AlternativeSyntax = StorageMap<_, Blake2_128Concat, u32, u32>; /// Lastly, all storage items, as you saw, had to be generic over `T`. If they want to use an /// item from `Config`, `` should be used. #[pezpallet::storage] pub type AlternativeSyntax2 = StorageMap<_, Blake2_128Concat, T::AccountId, u32>; /// The genesis config type. This allows the pezpallet to define how it should initialized upon /// genesis. /// /// It can be generic over `T` or not, depending on whether it is or not. #[pezpallet::genesis_config] pub struct GenesisConfig { pub foo: u32, pub bar: BlockNumberFor, } impl Default for GenesisConfig { fn default() -> Self { Self { foo: 0, bar: Default::default() } } } /// Allows you to define how `genesis_configuration is built. #[pezpallet::genesis_build] impl BuildGenesisConfig for GenesisConfig { fn build(&self) { Foo::::put(self.foo); } } /// The call declaration. This states the entry points that we handle. The /// macro takes care of the marshalling of arguments and dispatch. #[pezpallet::call] impl Pezpallet { #[pezpallet::call_index(0)] #[pezpallet::weight(T::WeightInfo::set_foo_benchmark())] /// Marks this call as feeless if `new_foo` is zero. #[pezpallet::feeless_if(|_origin: &OriginFor, new_foo: &u32, _other_compact: &u128| -> bool { *new_foo == 0 })] pub fn set_foo( _: OriginFor, new_foo: u32, #[pezpallet::compact] _other_compact: u128, ) -> DispatchResult { Foo::::set(Some(new_foo)); Ok(()) } /// A call that is specially authorized. /// Authorized call can be dispatched by anybody without requiring any signature or fee. #[pezpallet::call_index(1)] #[pezpallet::authorize(| _source: TransactionSource, new_foo: &u32, | -> TransactionValidityWithRefund { if *new_foo == 42 && Foo::::get().is_none() { // This is the amount to refund, here we refund nothing. let refund = Weight::zero(); // The transaction needs to give a provided tag. // See `ValidTransaction` documentation. let validity = ValidTransaction::with_tag_prefix("pezpallet-kitchen-sink") .and_provides("set_foo_using_authorize") .into(); Ok((validity, refund)) } else { Err(InvalidTransaction::Call.into()) } })] #[pezpallet::weight(T::WeightInfo::set_foo_using_authorize())] #[pezpallet::weight_of_authorize(T::WeightInfo::authorize_set_foo_using_authorize())] pub fn set_foo_using_authorize(origin: OriginFor, new_foo: u32) -> DispatchResult { // We only dispatch if it comes from the authorized origin. Meaning that the closure // passed in `pezpallet::authorize` has successfully authorized the call. ensure_authorized(origin)?; Foo::::set(Some(new_foo)); Ok(()) } } /// The event type. This exactly like a normal Rust enum. /// /// It can or cannot be generic over ``. Note that unlike a normal enum, if none of /// the variants actually use ``, the macro will generate a hidden `PhantomData` /// variant. /// /// The `generate_deposit` macro generates a function on `Pezpallet` called `deposit_event` /// which will properly convert the error type of your pezpallet into `RuntimeEvent` (recall /// `type RuntimeEvent: From>`, so it can be converted) and deposit it via /// `pezframe_system::Pezpallet::deposit_event`. #[pezpallet::event] #[pezpallet::generate_deposit(pub fn deposit_event)] pub enum Event { /// A simple tuple style variant. SomethingHappened(u32), /// A simple struct-style variant. Note that we use `AccountId` from `T` because `T: /// Config`, which by extension implies `T: pezframe_system::Config`. SomethingDetailedHappened { at: u32, to: T::AccountId }, /// Another variant. SomeoneJoined(T::AccountId), } /// The error enum. Must always be generic over ``, which is expanded to ``. #[pezpallet::error] pub enum Error { SomethingWentWrong, SomethingBroke, } /// All the possible hooks that a pezpallet can have. See [`pezframe_support::traits::Hooks`] /// for more info. #[pezpallet::hooks] impl Hooks> for Pezpallet { fn integrity_test() {} fn offchain_worker(_n: BlockNumberFor) { unimplemented!() } fn on_initialize(_n: BlockNumberFor) -> Weight { unimplemented!() } fn on_finalize(_n: BlockNumberFor) { unimplemented!() } fn on_idle(_n: BlockNumberFor, _remaining_weight: Weight) -> Weight { unimplemented!() } fn on_runtime_upgrade() -> Weight { unimplemented!() } #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result, TryRuntimeError> { unimplemented!() } #[cfg(feature = "try-runtime")] fn post_upgrade(_state: Vec) -> Result<(), TryRuntimeError> { unimplemented!() } #[cfg(feature = "try-runtime")] fn try_state(_n: BlockNumberFor) -> Result<(), TryRuntimeError> { unimplemented!() } } /// Allows you to define an enum on the pezpallet which will then instruct `construct_runtime` /// to amalgamate all similarly-named enums from other pallets into an aggregate enum. #[pezpallet::composite_enum] pub enum HoldReason { Staking, } /// Allows the pezpallet to provide some inherent. See /// [`pezframe_support::inherent::ProvideInherent`] for more info. #[pezpallet::inherent] impl ProvideInherent for Pezpallet { type Call = Call; type Error = MakeFatalError<()>; const INHERENT_IDENTIFIER: [u8; 8] = *b"test1234"; fn create_inherent(_data: &InherentData) -> Option { unimplemented!(); } fn is_inherent(_call: &Self::Call) -> bool { unimplemented!() } } }