Developers Home»How-to Guide»Custom Chain Specifications

Custom Chain Specifications

Goal

Generate a chain-spec.json and include it for other nodes to join a common network

Use Cases

  • Starting a private network
  • Modify an existing plain chain spec without editing the node source code

Overview

Once you have a Substrate node crafted, you want to start a network with many peers! This guide shows one method to create chain specification files uniformly and distribute them so other nodes can discover and peer with your network explicitly.

Steps

1. Create a plain chain specification

Starting in the working directory of your node's working directory, and assuming the bin is node-template:

./target/release/node-template build-spec > chain-spec-plain.json

We have just generated a plain chain spec file for the default network set in your chain_spec.rs file. This file can be passed to other nodes

2. Modify the plain chain specification (optional)

This optional step we can leverage an existing plain chain specification for a network that otherwise would require modification of the source of the node to run on a new network. For example, this can be quite useful in the Cumulus Tutorial where we want to create a custom relay chain without customizing Polkadot's source.

Here we use the same chain spec, but pass a flag to disable bootnodes, as we want a new network where these nodes will be different.

./target/release/node-template build-spec --chain chain-spec-plain.json --raw --disable-default-bootnode > no-bootnodes-chain-spec-plain.json

This no-bootnodes-chain-spec-plain.json can be used to generate a SCALE storage encoded, distributable raw chain spec.

3. Generate the raw chain specification

With a plain spec available, you generate a final raw chain spec by:

./target/release/node-template build-spec --chain chain-spec-plain.json --raw > chain-spec.json

4. Publish the chain specification

Non-Determinism in Wasm & chain specs

Because Rust -> Wasm optimized builds aren't reproducible, each person will get a slightly different Wasm blob which will break consensus if each participant generates the file themselves. For the curious, learn more about this issue in this blog post.

It is conventional to include the chain specification files for your node within the source code itself so that anyone can build your node in the same way, whereby it becomes easy to check for non-determinism by comparing a genesis blob with another. Polkadot, Kusama, Rococo, and more network chain spec files are found in the source here along with a .gitignore file to ensure that you don't accidentally change these !/*.json files as you build further on your node's software and do runtime upgrades.

5. Start a new node

If you publish a node binary, or have users build their own and then they want to join your network, all then need is the same chain spec file and to run your binary with:

# binary named `node-template`
# `chain-spec.json` obtained from canonical common source
node-template --chain chain-spec.json

This can also simply be configured to be the default network. For reference, you can see how Polkadot implements a default command that uses the chain specs for various networks in the source here

Examples

Last edit: on

Run into problems?
Let us Know