Understanding Basic Substrate Code
In this section, we are going to see how we can customize/update the substrate chain and block of the Substrate chain. If we want to make any fundamental changes in the Substrate chain we need to make changes in the Node or Runtime module. Let’s Explore these modules one by one: Node: The Node module is the center point of the blockchain and it is responsible for almost all the things we can do with the chain. Like: How to run the node, What will be the initial state of the block, how any external RPC interacts with the node, what will be the consensus algo of the chain,etc.
- ChainSpec.rs: The chainspec file is responsible for the initial fundamental root of the chain. From there we can do the following things:
- We can add or manage accounts that we will get during the starting of the chain.
- How We can generate a new account.
- We can pre-fund the account. So that we can make transactions on the chain.
- We can add any other prerequisite related to any pallet if the pallet needs it.
- Basically, we can do everything which we need on the chain during starting(Block 1) of the chain.
- Cli.rs: The cli file is responsible for all the customization of commands to interact with the chain. Like
- How the block will generate instant-seal, manual, or default.
- How we can build the spec for the chain, purge the chain, and many more.
- Basically whatever we can do with the chain by the help of commands.
- Command.rs: It is the extended or helper file of the cli one.
- Main.rs: It is the main file just for instantiation purposes of cli.
- Rpc.rs: The RPC file is responsible for all the methods or customization related to RPC(Remote Procedure Call). Like
- How the block will generate instant-seal, manual, or default.
- How we can build the spec for the chain, purge the chain, and many more.
- Basically whatever we can do with the chain by the help of commands.
- Service.rs: The service file is responsible for the main business logic for the block generation. Like
- Consensus protocol.
- How the block will generate differently for the different commands like manual, or instant seal.
- How the chain will interact between nodes.
- And all the things related to the database, telemetry, RPC, finality, and much more. It basically takes the configuration from the Runtime module which we do with respect to any pallet.
- Runtime: The Runtime is responsible for the coupling and config customizations of the pallets. It has the lib.rs which has the main code and also the benchmarking and other files also come in it.
- Lib.rs: This is the file where we can do the coupling and customization. Let’s understand one by one:
- Firstly it has all the basic configurations related to runtime like chain name, chain version, etc.
- We need to customize/implement all the pallets we are using in the chain. Like frame_system, grandpa, aura, timestamp, sudo, etc
- We create the chain runtime by adding all the pallets into it.
construct_runtime!( pub enum Runtime where Block = Block, NodeBlock = opaque::Block, UncheckedExtrinsic = UncheckedExtrinsic { System: frame_system, RandomnessCollectiveFlip: pallet_randomness_collective_flip, Timestamp: pallet_timestamp, Aura: pallet_aura, Grandpa: pallet_grandpa, Balances: pallet_balances, TransactionPayment: pallet_transaction_payment, Sudo: pallet_sudo, } ); - Lib.rs: This is the file where we can do the coupling and customization. Let’s understand one by one:
- We can also add more business logic respective to any pallet or node.
- We also implement the different traits for different transactions on the node. Like execute the block, finalize block, validate transactions, etc.
- Type 1: The changes we covered on the service .rs
- Type 2: The changes which we can make from runtime.
- We can update the time of the block generation from the configuration of the timestamp pallet. Same as we can do more customizations with the help of other pallets.
- We can customize the block in the transaction pool.
- We can add the conditions/validations in the different block transaction methods like execute the block, finalize block, etc.
- Above changes, we can do in the implementation of the traits related to it. Along with that if we want to customize the block we can look at the other methods in the traits of the executive file(link).