The runtime of a blockchain is the business logic that defines its behavior. In Substrate-based chains, the runtime is referred to as the "state transition function"; it is where Substrate developers define the storage items that are used to represent the blockchain's state as well as the functions that allow blockchain users to make changes to this state.
Each Substrate node contains a runtime. The runtime contains the business logic of the chain. It defines what transactions are valid and invalid and determines how the chain's state changes in response to transactions. The "outer node", everything other than the runtime, does not compile to Wasm, only to native. The outer node is responsible for handling peer discovery, transaction pooling, block and transaction gossiping, consensus, and answering RPC calls from the outside world. While performing these tasks, the outer node sometimes needs to query the runtime for information, or provide information to the runtime. A Runtime API facilitates this kind of communication between the outer node and the runtime.
In Substrate, the
sp_api crate provides an interface to implement a runtime API. It is designed to give
developers the ability to define their own custom runtime APIs using the
macro. However, every runtime must implement the
Metadata runtime APIs. In addition to these, a basic Substrate Node
has the following runtime APIs implemented:
BlockBuilder: Provides the functionality required for building a block.
TaggedTransactionQueue: Handles validating transactions in the transaction queue.
OffchainWorkerApi: Handles off-chain capabilities.
AuraApi: Handles block authorship with Aura consensus.
SessionKeys: Generates and decodes session keys.
GrandpaApi: Integrates the GRANDPA finality gadget into the runtime.
AccountNonceApi: Handles querying transaction indices.
TransactionPaymentApi: Handles querying information about transactions.
Benchmark: Provides a way to benchmark a FRAME runtime.
In order to provide its defining forkless runtime upgrade capabilities, Substrate runtimes are built as WebAssembly (Wasm) bytecode. Substrate also defines the core primitives that the runtime must implement.
The Substrate framework makes minimal assumptions about what your runtime must provide to the other layers of Substrate. But there are a few data types need to be defined and must fulfill a particular interface in order to work within the Substrate framework.
Hash: A type which encodes a cryptographic digest of some data. Typically just a 256-bit quantity.
DigestItem: A type which must be able to encode one of a number of "hard-wired" alternatives relevant to consensus and change-tracking as well as any number of "soft-coded" variants, relevant to specific modules within the runtime.
Digest: A series of DigestItems. This encodes all information that is relevant for a light-client to have on hand within the block.
Extrinsic: A type to represent a single piece of data external to the blockchain that is recognized by the blockchain. This typically involves one or more signatures, and some sort of encoded instructions (e.g. for transferring ownership of funds or calling into a smart contract).
Header: A type which is representative (cryptographically or otherwise) of all information relevant to a block. It includes the parent hash, the storage root and the extrinsics trie root, the digest and a block number.
Block: Essentially just a combination of
Headerand a series of
Extrinsics, together with a specification of the hashing algorithm to be used.
BlockNumber: A type which encodes the total number of ancestors any valid block has. Typically a 32-bit quantity.
The core Substrate codebase ships with FRAME, Parity's system for Substrate runtime development that is used for chains like Kusama and Polkadot. FRAME defines additional runtime primitives and provides a framework that makes it easy to construct a runtime by composing modules, called pallets. Each pallet encapsulates domain-specific logic that is expressed as a set of a storage items, events, errors, and dispatchable functions. FRAME developers can create their own pallets and reuse existing pallets, including over 50 of those shipped with Substrate.
There are an additional set of primitives that are assumed about a runtime built with the Substrate FRAME. These are:
Call: The dispatch type that can be called via an extrinsic.
Origin: Represents where a call came from. For example, a signed message (a transaction), an unsigned message (an inherent extrinsic), or a call from the runtime itself (a root call).
Index: An account index (aka nonce) type. This stores the number of previous transactions associated with a sender account.
Hashing: The hashing algorithm being used in the runtime (e.g. Blake2).
AccountId: The type used to identify user accounts in the runtime.
Event: The type used for events emitted by the runtime.
Version: A type which represents the version of the runtime.
Although a lot of core runtime development can be enabled with FRAME and its related primitives, FRAME is not the only system for developing Substrate based blockchains.
- Learn about the Substrate FRAME.
- Follow a tutorial to develop your first Substrate chain.
- Follow a tutorial to add a pallet to your Substrate runtime.