pallet_example_kitchensink/
lib.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! # Kitchensink Example Pallet
19//!
20//! **This pallet serves as an example and is not meant to be used in production.**
21//!
22//! The kitchen-sink catalog of the the FRAME macros and their various syntax options.
23//!
24//! This example does not focus on pallet instancing, `dev_mode`, and does nto include any 'where'
25//! clauses on `T`. These will both incur additional complexity to the syntax, but are not discussed
26//! here.
27
28#![cfg_attr(not(feature = "std"), no_std)]
29
30// Re-export pallet items so that they can be accessed from the crate namespace.
31pub use pallet::*;
32
33#[cfg(test)]
34mod tests;
35
36#[cfg(feature = "runtime-benchmarks")]
37mod benchmarking;
38
39#[cfg(feature = "try-runtime")]
40use sp_runtime::TryRuntimeError;
41
42pub mod weights;
43pub use weights::*;
44
45#[frame_support::pallet]
46pub mod pallet {
47	use super::*;
48	use frame_support::pallet_prelude::*;
49	use frame_system::pallet_prelude::*;
50
51	/// The config trait of the pallet. You can basically do anything with the config trait that you
52	/// can do with a normal rust trait: import items consisting of types, constants and functions.
53	///
54	/// A very common pattern is for a pallet to import implementations of traits such as
55	/// [`frame_support::traits::Currency`], [`frame_support::traits::fungibles::Inspect`] and
56	/// [`frame_support::traits::Get`]. These are all types that the pallet is delegating to the top
57	/// level runtime to provide to it.
58	///
59	/// The `FRAME`-specific syntax are:
60	///
61	/// * the use of `#[pallet::constant]`([`frame_support::procedural`]), which places a `Get`
62	///   implementation in the metadata.
63	/// * `type RuntimeEvent`, which is mandatory if your pallet has events. See TODO.
64	/// * Needless to say, because [`Config`] is bounded by [`frame_system::Config`], you can use
65	///   all the items from [`frame_system::Config`] as well, such as `AccountId`.
66	/// * `#[pallet::disable_frame_system_supertrait_check]` would remove the need for
67	///   `frame_system::Config` to exist, which you should almost never need.
68	#[pallet::config]
69	pub trait Config: frame_system::Config {
70		/// The overarching runtime event type.
71		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
72
73		/// Type representing the weight of this pallet
74		type WeightInfo: WeightInfo;
75
76		/// This is a normal Rust type, nothing specific to FRAME here.
77		type Currency: frame_support::traits::fungible::Inspect<Self::AccountId>;
78
79		/// Similarly, let the runtime decide this.
80		fn some_function() -> u32;
81
82		/// And this
83		const FOO: u32;
84
85		/// This is a FRAME-specific item. It will be placed in the metadata of the pallet, and
86		/// therefore can be queried by offchain applications.
87		#[pallet::constant]
88		type InMetadata: Get<u32>;
89	}
90
91	/// Allows you to define some extra constants to be added into constant metadata.
92	#[pallet::extra_constants]
93	impl<T: Config> Pallet<T> {
94		#[allow(non_snake_case)]
95		fn SomeValue() -> u32 {
96			unimplemented!()
97		}
98
99		#[pallet::constant_name(OtherValue)]
100		fn arbitrary_name() -> u32 {
101			unimplemented!()
102		}
103	}
104
105	const STORAGE_VERSION: frame_support::traits::StorageVersion = StorageVersion::new(1);
106
107	/// The pallet struct. There's nothing special to FRAME about this; it can implement functions
108	/// in an impl blocks, traits and so on.
109	#[pallet::pallet]
110	#[pallet::without_storage_info]
111	#[pallet::storage_version(STORAGE_VERSION)]
112	pub struct Pallet<T>(_);
113
114	/// Allows you to define some origin for the pallet.
115	#[pallet::origin]
116	pub type Origin<T> = frame_system::RawOrigin<<T as frame_system::Config>::AccountId>;
117
118	// first, we showcase all the possible storage types, with most of their details.
119
120	/// A storage value. We mark this as unbounded, alter its prefix, and define a custom storage
121	/// getter for it.
122	///
123	/// The value is stored a single trie node, and therefore can be retrieved with a single
124	/// database access.
125	#[pallet::storage]
126	#[pallet::unbounded] // optional
127	#[pallet::storage_prefix = "OtherFoo"] // optional
128	#[pallet::getter(fn foo)] // optional
129	pub type Foo<T> = StorageValue<Value = u32>;
130
131	#[pallet::type_value]
132	pub fn DefaultForFoo() -> u32 {
133		1
134	}
135
136	#[pallet::storage]
137	pub type FooWithDefault<T> =
138		StorageValue<Value = u32, QueryKind = ValueQuery, OnEmpty = DefaultForFoo>;
139
140	/// A storage map. This creates a mapping from keys of type `u32` to values of type `u32`.
141	///
142	/// Keys and values can be iterated, albeit each value is stored under a unique trie key,
143	/// meaning that an iteration consists of many database accesses.
144	#[pallet::storage]
145	pub type Bar<T> = StorageMap<Hasher = Blake2_128Concat, Key = u32, Value = u32>;
146
147	/// Conceptually same as `StorageMap<>` where the key is a tuple of `(u32, u32)`. On top, it
148	/// provides some functions to iterate or remove items based on only the first key.
149	#[pallet::storage]
150	pub type Qux<T> = StorageDoubleMap<
151		Hasher1 = Blake2_128Concat,
152		Key1 = u32,
153		Hasher2 = Blake2_128Concat,
154		Key2 = u32,
155		Value = u32,
156	>;
157
158	/// Same as `StorageDoubleMap`, but with arbitrary number of keys.
159	#[pallet::storage]
160	pub type Quux<T> = StorageNMap<
161		Key = (
162			NMapKey<Blake2_128Concat, u8>,
163			NMapKey<Blake2_128Concat, u16>,
164			NMapKey<Blake2_128Concat, u32>,
165		),
166		Value = u64,
167	>;
168
169	/// In all of these examples, we chose a syntax where the storage item is defined using the
170	/// explicit generic syntax (`X = Y`). Alternatively:
171	#[pallet::storage]
172	pub type AlternativeSyntax<T> = StorageMap<_, Blake2_128Concat, u32, u32>;
173
174	/// Lastly, all storage items, as you saw, had to be generic over `T`. If they want to use an
175	/// item from `Config`, `<T: Config>` should be used.
176	#[pallet::storage]
177	pub type AlternativeSyntax2<T: Config> = StorageMap<_, Blake2_128Concat, T::AccountId, u32>;
178
179	/// The genesis config type. This allows the pallet to define how it should initialized upon
180	/// genesis.
181	///
182	/// It can be generic over `T` or not, depending on whether it is or not.
183	#[pallet::genesis_config]
184	pub struct GenesisConfig<T: Config> {
185		pub foo: u32,
186		pub bar: BlockNumberFor<T>,
187	}
188
189	impl<T: Config> Default for GenesisConfig<T> {
190		fn default() -> Self {
191			Self { foo: 0, bar: Default::default() }
192		}
193	}
194
195	/// Allows you to define how `genesis_configuration is built.
196	#[pallet::genesis_build]
197	impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
198		fn build(&self) {
199			Foo::<T>::put(self.foo);
200		}
201	}
202
203	/// The call declaration. This states the entry points that we handle. The
204	/// macro takes care of the marshalling of arguments and dispatch.
205	#[pallet::call]
206	impl<T: Config> Pallet<T> {
207		#[pallet::call_index(0)]
208		#[pallet::weight(T::WeightInfo::set_foo_benchmark())]
209		/// Marks this call as feeless if `new_foo` is zero.
210		#[pallet::feeless_if(|_origin: &OriginFor<T>, new_foo: &u32, _other_compact: &u128| -> bool {
211			*new_foo == 0
212		})]
213		pub fn set_foo(
214			_: OriginFor<T>,
215			new_foo: u32,
216			#[pallet::compact] _other_compact: u128,
217		) -> DispatchResult {
218			Foo::<T>::set(Some(new_foo));
219
220			Ok(())
221		}
222	}
223
224	/// The event type. This exactly like a normal Rust enum.
225	///
226	/// It can or cannot be generic over `<T: Config>`. Note that unlike a normal enum, if none of
227	/// the variants actually use `<T: Config>`, the macro will generate a hidden `PhantomData`
228	/// variant.
229	///
230	/// The `generate_deposit` macro generates a function on `Pallet` called `deposit_event` which
231	/// will properly convert the error type of your pallet into `RuntimeEvent` (recall `type
232	/// RuntimeEvent: From<Event<Self>>`, so it can be converted) and deposit it via
233	/// `frame_system::Pallet::deposit_event`.
234	#[pallet::event]
235	#[pallet::generate_deposit(pub fn deposit_event)]
236	pub enum Event<T: Config> {
237		/// A simple tuple style variant.
238		SomethingHappened(u32),
239		/// A simple struct-style variant. Note that we use `AccountId` from `T` because `T:
240		/// Config`, which by extension implies `T: frame_system::Config`.
241		SomethingDetailedHappened { at: u32, to: T::AccountId },
242		/// Another variant.
243		SomeoneJoined(T::AccountId),
244	}
245
246	/// The error enum. Must always be generic over `<T>`, which is expanded to `<T: Config>`.
247	#[pallet::error]
248	pub enum Error<T> {
249		SomethingWentWrong,
250		SomethingBroke,
251	}
252
253	/// All the possible hooks that a pallet can have. See [`frame_support::traits::Hooks`] for more
254	/// info.
255	#[pallet::hooks]
256	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
257		fn integrity_test() {}
258
259		fn offchain_worker(_n: BlockNumberFor<T>) {
260			unimplemented!()
261		}
262
263		fn on_initialize(_n: BlockNumberFor<T>) -> Weight {
264			unimplemented!()
265		}
266
267		fn on_finalize(_n: BlockNumberFor<T>) {
268			unimplemented!()
269		}
270
271		fn on_idle(_n: BlockNumberFor<T>, _remaining_weight: Weight) -> Weight {
272			unimplemented!()
273		}
274
275		fn on_runtime_upgrade() -> Weight {
276			unimplemented!()
277		}
278
279		#[cfg(feature = "try-runtime")]
280		fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
281			unimplemented!()
282		}
283
284		#[cfg(feature = "try-runtime")]
285		fn post_upgrade(_state: Vec<u8>) -> Result<(), TryRuntimeError> {
286			unimplemented!()
287		}
288
289		#[cfg(feature = "try-runtime")]
290		fn try_state(_n: BlockNumberFor<T>) -> Result<(), TryRuntimeError> {
291			unimplemented!()
292		}
293	}
294
295	/// Allows you to define an enum on the pallet which will then instruct `construct_runtime` to
296	/// amalgamate all similarly-named enums from other pallets into an aggregate enum.
297	#[pallet::composite_enum]
298	pub enum HoldReason {
299		Staking,
300	}
301
302	/// Allows the pallet to validate some unsigned transaction. See
303	/// [`sp_runtime::traits::ValidateUnsigned`] for more info.
304	#[pallet::validate_unsigned]
305	impl<T: Config> ValidateUnsigned for Pallet<T> {
306		type Call = Call<T>;
307		fn validate_unsigned(_: TransactionSource, _: &Self::Call) -> TransactionValidity {
308			unimplemented!()
309		}
310
311		fn pre_dispatch(_: &Self::Call) -> Result<(), TransactionValidityError> {
312			unimplemented!()
313		}
314	}
315
316	/// Allows the pallet to provide some inherent. See [`frame_support::inherent::ProvideInherent`]
317	/// for more info.
318	#[pallet::inherent]
319	impl<T: Config> ProvideInherent for Pallet<T> {
320		type Call = Call<T>;
321		type Error = MakeFatalError<()>;
322
323		const INHERENT_IDENTIFIER: [u8; 8] = *b"test1234";
324
325		fn create_inherent(_data: &InherentData) -> Option<Self::Call> {
326			unimplemented!();
327		}
328
329		fn is_inherent(_call: &Self::Call) -> bool {
330			unimplemented!()
331		}
332	}
333}