polkadot_sdk_docs/polkadot_sdk/frame_runtime.rs
1//! # FRAME
2//!
3//! ```no_compile
4//! ______ ______ ________ ___ __ __ ______
5//! /_____/\ /_____/\ /_______/\ /__//_//_/\ /_____/\
6//! \::::_\/_\:::_ \ \ \::: _ \ \\::\| \| \ \\::::_\/_
7//! \:\/___/\\:(_) ) )_\::(_) \ \\:. \ \\:\/___/\
8//! \:::._\/ \: __ `\ \\:: __ \ \\:.\-/\ \ \\::___\/_
9//! \:\ \ \ \ `\ \ \\:.\ \ \ \\. \ \ \ \\:\____/\
10//! \_\/ \_\/ \_\/ \__\/\__\/ \__\/ \__\/ \_____\/
11//! ```
12//!
13//! > **F**ramework for **R**untime **A**ggregation of **M**odularized **E**ntities: Substrate's
14//! > State Transition Function (Runtime) Framework.
15//!
16//! ## Introduction
17//!
18//! As described in [`crate::reference_docs::wasm_meta_protocol`], at a high-level Substrate-based
19//! blockchains are composed of two parts:
20//!
21//! 1. A *runtime* which represents the state transition function (i.e. "Business Logic") of a
22//! blockchain, and is encoded as a WASM blob.
23//! 2. A node whose primary purpose is to execute the given runtime.
24#![doc = simple_mermaid::mermaid!("../../../mermaid/substrate_simple.mmd")]
25//! *FRAME is the Substrate's framework of choice to build a runtime.*
26//!
27//! FRAME is composed of two major components, **pallets** and a **runtime**.
28//!
29//! ## Pallets
30//!
31//! A pallet is a unit of encapsulated logic. It has a clearly defined responsibility and can be
32//! linked to other pallets. In order to be reusable, pallets shipped with FRAME strive to only care
33//! about its own responsibilities and make as few assumptions about the general runtime as
34//! possible. A pallet is analogous to a _module_ in the runtime.
35//!
36//! A pallet is defined as a `mod pallet` wrapped by the [`frame::pallet`] macro. Within this macro,
37//! pallet components/parts can be defined. Most notable of these parts are:
38//!
39//! - [Config](frame::pallet_macros::config), allowing a pallet to make itself configurable and
40//! generic over types, values and such.
41//! - [Storage](frame::pallet_macros::storage), allowing a pallet to define onchain storage.
42//! - [Dispatchable function](frame::pallet_macros::call), allowing a pallet to define extrinsics
43//! that are callable by end users, from the outer world.
44//! - [Events](frame::pallet_macros::event), allowing a pallet to emit events.
45//! - [Errors](frame::pallet_macros::error), allowing a pallet to emit well-formed errors.
46//!
47//! Some of these pallet components resemble the building blocks of a smart contract. While both
48//! models are programming state transition functions of blockchains, there are crucial differences
49//! between the two. See [`crate::reference_docs::runtime_vs_smart_contract`] for more.
50//!
51//! Most of these components are defined using macros, the full list of which can be found in
52//! [`frame::pallet_macros`].
53//!
54//! ### Example
55//!
56//! The following example showcases a minimal pallet.
57#![doc = docify::embed!("src/polkadot_sdk/frame_runtime.rs", pallet)]
58//! ## Runtime
59//!
60//! A runtime is a collection of pallets that are amalgamated together. Each pallet typically has
61//! some configurations (exposed as a `trait Config`) that needs to be *specified* in the runtime.
62//! This is done with [`frame::runtime::prelude::construct_runtime`].
63//!
64//! A (real) runtime that actually wishes to compile to WASM needs to also implement a set of
65//! runtime-apis. These implementation can be specified using the
66//! [`frame::runtime::prelude::impl_runtime_apis`] macro.
67//!
68//! ### Example
69//!
70//! The following example shows a (test) runtime that is composing the pallet demonstrated above,
71//! next to the [`frame::prelude::frame_system`] pallet, into a runtime.
72#![doc = docify::embed!("src/polkadot_sdk/frame_runtime.rs", runtime)]
73//! ## More Examples
74//!
75//! You can find more FRAME examples that revolve around specific features at [`pallet_examples`].
76//!
77//! ## Alternatives ๐
78//!
79//! There is nothing in the Substrate's node side code-base that mandates the use of FRAME. While
80//! FRAME makes it very simple to write Substrate-based runtimes, it is by no means intended to be
81//! the only one. At the end of the day, any WASM blob that exposes the right set of runtime APIs is
82//! a valid Runtime form the point of view of a Substrate client (see
83//! [`crate::reference_docs::wasm_meta_protocol`]). Notable examples are:
84//!
85//! * writing a runtime in pure Rust, as done in [this template](https://github.com/JoshOrndorff/frameless-node-template).
86//! * writing a runtime in AssemblyScript, as explored in [this project](https://github.com/LimeChain/subsembly).
87
88/// A FRAME based pallet. This `mod` is the entry point for everything else. All
89/// `#[pallet::xxx]` macros must be defined in this `mod`. Although, frame also provides an
90/// experimental feature to break these parts into different `mod`s. See [`pallet_examples`] for
91/// more.
92#[docify::export]
93#[frame::pallet(dev_mode)]
94pub mod pallet {
95 use frame::prelude::*;
96
97 /// The configuration trait of a pallet. Mandatory. Allows a pallet to receive types at a
98 /// later point from the runtime that wishes to contain it. It allows the pallet to be
99 /// parameterized over both types and values.
100 #[pallet::config]
101 pub trait Config: frame_system::Config {
102 /// A type that is not known now, but the runtime that will contain this pallet will
103 /// know it later, therefore we define it here as an associated type.
104 #[allow(deprecated)]
105 type RuntimeEvent: IsType<<Self as frame_system::Config>::RuntimeEvent> + From<Event<Self>>;
106
107 /// A parameterize-able value that we receive later via the `Get<_>` trait.
108 type ValueParameter: Get<u32>;
109
110 /// Similar to [`Config::ValueParameter`], but using `const`. Both are functionally
111 /// equal, but offer different tradeoffs.
112 const ANOTHER_VALUE_PARAMETER: u32;
113 }
114
115 /// A mandatory struct in each pallet. All functions callable by external users (aka.
116 /// transactions) must be attached to this type (see [`frame::pallet_macros::call`]). For
117 /// convenience, internal (private) functions can also be attached to this type.
118 #[pallet::pallet]
119 pub struct Pallet<T>(PhantomData<T>);
120
121 /// The events that this pallet can emit.
122 #[pallet::event]
123 pub enum Event<T: Config> {}
124
125 /// A storage item that this pallet contains. This will be part of the state root trie
126 /// of the blockchain.
127 #[pallet::storage]
128 pub type Value<T> = StorageValue<Value = u32>;
129
130 /// All *dispatchable* call functions (aka. transactions) are attached to `Pallet` in a
131 /// `impl` block.
132 #[pallet::call]
133 impl<T: Config> Pallet<T> {
134 /// This will be callable by external users, and has two u32s as a parameter.
135 pub fn some_dispatchable(
136 _origin: OriginFor<T>,
137 _param: u32,
138 _other_para: u32,
139 ) -> DispatchResult {
140 Ok(())
141 }
142 }
143}
144
145/// A simple runtime that contains the above pallet and `frame_system`, the mandatory pallet of
146/// all runtimes. This runtime is for testing, but it shares a lot of similarities with a *real*
147/// runtime.
148#[docify::export]
149pub mod runtime {
150 use super::pallet as pallet_example;
151 use frame::{prelude::*, testing_prelude::*};
152
153 // The major macro that amalgamates pallets into `enum Runtime`
154 construct_runtime!(
155 pub enum Runtime {
156 System: frame_system,
157 Example: pallet_example,
158 }
159 );
160
161 // These `impl` blocks specify the parameters of each pallet's `trait Config`.
162 #[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
163 impl frame_system::Config for Runtime {
164 type Block = MockBlock<Self>;
165 }
166
167 impl pallet_example::Config for Runtime {
168 type RuntimeEvent = RuntimeEvent;
169 type ValueParameter = ConstU32<42>;
170 const ANOTHER_VALUE_PARAMETER: u32 = 42;
171 }
172}