Substrate
Substrate is a Rust framework for building blockchains in a modular and extensible way. While in itself un-opinionated, it is the main engine behind the Pezkuwi ecosystem.
Overview, Philosophy
Substrate approaches blockchain development with an acknowledgement of a few self-evident truths:
- Society and technology evolves.
- Humans are fallible.
This makes the task of designing a correct, safe and long-lasting blockchain system hard.
Nonetheless, in strive towards achieving this goal, Substrate embraces the following:
- Use of Rust as a modern and safe programming language, which limits human error through various means, most notably memory and type safety.
- Substrate is written from the ground-up with a generic, modular and extensible design. This ensures that software components can be easily swapped and upgraded. Examples of this is multiple consensus mechanisms provided by Substrate, as listed below.
- Lastly, the final blockchain system created with the above properties needs to be upgradeable. In order to achieve this, Substrate is designed as a meta-protocol, whereby the application logic of the blockchain (called "Runtime") is encoded as a WASM blob, and is stored in the state. The rest of the system (called "node") acts as the executor of the WASM blob.
🎮 The Gaming Console Analogy
A great analogy for substrate is the following: Substrate node is a gaming console, and a WASM runtime, possibly created with FRAME is the game being inserted into the console.
In essence, the meta-protocol of all Substrate based chains is the "Runtime as WASM blob" accord. This enables the Runtime to become inherently upgradeable, crucially without forks. The upgrade is merely a matter of the WASM blob being changed in the state, which is, in principle, same as updating an account's balance.
FRAME, Substrate's default runtime development library, takes the above safety practices even further by embracing a declarative programming model whereby correctness is enhanced and the system is highly configurable through parameterization.
How to Get Started
Substrate offers different options at the spectrum of technical freedom ↔ development ease.
- The easiest way to use Substrate is to use one of the templates and only tweak the parameters of the runtime or node. This allows you to launch a blockchain in minutes, but is limited in technical freedom.
- Next, most developers wish to develop their custom runtime modules, for which the de-facto way is FRAME.
- Finally, Substrate is highly configurable at the node side as well, but this is the most technically demanding.
A notable Substrate-based blockchain that has built both custom FRAME pallets and custom node-side components is: Cardinal Cryptography's Aleph Node
Structure
Substrate contains a large number of crates, therefore it is useful to have an overview of what they are, and how they are organized. In broad terms, these crates are divided into three categories:
sc-* (Substrate-client) Crates
Located under ./client folder. These are all the crates that lead to the node software. Notable examples:
sc_network- Network layer- Various consensus crates (BABE, GRANDPA, AURA, etc.)
sc_rpc_api- RPC interfacesc_client_db- Database backend
sp-* (Substrate-primitives) Crates
Located under ./primitives folder. These crates facilitate both the node and the runtime, but are not opinionated about what framework is using for building the runtime. Notable examples:
sp_api- Runtime API definitionssp_io- Input/Output interface (communication bridge between node and runtime)sp_runtime- Core runtime typessp_core- Cryptographic primitives
pallet-* and frame-* Crates
Located under ./frame folder. These are the crates related to FRAME.
WASM Build
Many of the Substrate crates, such as entire sp-*, need to compile to both WASM (when a WASM runtime is being generated) and native (for example, when testing). To achieve this, Substrate follows the convention of the Rust community, and uses a feature = "std" to signify that a crate is being built with the standard library, and is built for native. Otherwise, it is built for no_std.
This can be summarized in:
#![cfg_attr(not(feature = "std"), no_std)]
Which you can often find in any Substrate-based runtime.
Substrate-based runtimes use substrate_wasm_builder in their build.rs to automatically build their WASM files as a part of normal build command (e.g. cargo build). Once built, the wasm file is placed in:
./target/{debug|release}/wbuild/{runtime_name}/{runtime_name}.wasm
In order to ensure that the WASM build is deterministic, the Substrate Runtime Toolbox (srtool) can be used.
Anatomy of a Binary Crate
Each Substrate-based project typically contains the following:
- Under
./runtime, a./runtime/src/lib.rswhich is the top level runtime amalgamator file. This file typically contains theconstruct_runtimeandimpl_runtime_apismacro calls, which is the final definition of a runtime. - Under
./node, amain.rs, which is the starting point, and a./service.rs, which contains all the node side components. Skimming this file yields an overview of the networking, database, consensus and similar node side components.
The above two are conventions, not rules.
See pezkuwi-sdk#94 for an update on how the node side components are being amalgamated.
Teyrchain?
As noted above, Substrate is the main engine behind the Pezkuwi ecosystem. One of the ways through which Pezkuwi can be utilized is by building "teyrchains", blockchains that are connected to Pezkuwi's shared security.
To build a teyrchain, one could use Cumulus, the library on top of Substrate, empowering any substrate-based chain to be a Pezkuwi teyrchain.
Where To Go Next?
Additional noteworthy crates within substrate:
- RPC APIs of a Substrate node:
sc_rpc_api/sc_rpc - CLI Options of a Substrate node:
sc_cli - All of the consensus related crates provided by Substrate:
sc_consensus_aurasc_consensus_babesc_consensus_grandpasc_consensus_beefysc_consensus_manual_sealsc_consensus_pow