Get started with Substrate on Ubuntu 18.04

Muhammad Bashir Sharif
2021-04-16T20:54:07Z

README.md

Install Substrate

sudo apt update && sudo apt upgrade -y && sudo apt autoremove -y \
  && sudo apt install -y docker.io pwgen jq joe screen \
  && sudo reboot

Now run screen and inside

curl https://getsubstrate.io -sSf | bash

Press ^A ^D to detach screen and run screen -r to resume to installation.

Generate account

Subkey is Substrate's command line tool to handle Ed25519 keypairs. To generate a new keypair, use subkey generate:

$ subkey generate
Seed 0xd26c63905a3b2f455185cff37dfbe1b70ec3c16ea33138772d430f24d6c1d7d2 is account:
  Public key (hex): 0x8d240d69a6b5006da03bfb7ee59888bd310bf7727ff193ebed73a13a8067b0db
  Address (SS58): 5FFmKSNARNV4gkJLczvWMakv8ooNRufmQtEwuwoheesqAHEc

Address is in the Substrate-specific SS58 format (base58 of network identifier + pubkey + checksum)

Generate new chain

1. Create new chainspec.json

export PUBLIC_IP_ADDRESS=$(curl -sS 'https://api.ipify.org?format=json' | jq '.ip' --raw-output)
cat /dev/urandom | head -c 32 | xxd -p -c 256 > ~/.node_key
substrate --chain=staging --node-key "$(< ~/.node_key)" build-spec \
  | jq '.name = "TSP"' \
  | jq '.id = "tsp_testnet_123"' \
  | jq '.bootNodes[0] |= gsub("127\\.0\\.0\\.1"; env.PUBLIC_IP_ADDRESS)' \
  | jq '.genesis.runtime.timestamp.period = 20' \
  | jq '.genesis.runtime.balances.balances[0][1] = 1000000000000000' \
  > ~/chainspec.json

2. Set your address in authorities of ~/chainspec.json, e.g.

"consensus": {
  "authorities": [
    "5FFmKSNARNV4gkJLczvWMakv8ooNRufmQtEwuwoheesqAHEc"
  ],
  [...]
}

3. Set your public key in balances, validators, intentions, upgradeKey, sudo of ~/chainspec.json, e.g.

"balances": [
  [
    "0x8d240d69a6b5006da03bfb7ee59888bd310bf7727ff193ebed73a13a8067b0db",
    1000000000000000
  ]
]

"session": {
  "validators": [
    "0x8d240d69a6b5006da03bfb7ee59888bd310bf7727ff193ebed73a13a8067b0db"
  ],
  [...]
}

"staking": {
  "intentions": [
    "0x8d240d69a6b5006da03bfb7ee59888bd310bf7727ff193ebed73a13a8067b0db"
  ],
  [...]
}

"upgradeKey": {
  "key": "0x8d240d69a6b5006da03bfb7ee59888bd310bf7727ff193ebed73a13a8067b0db"
},

"sudo": {
  "key": "0x8d240d69a6b5006da03bfb7ee59888bd310bf7727ff193ebed73a13a8067b0db"
}

4. Build raw chain definition

substrate --chain ~/chainspec.json build-spec --raw > ~/mychain.json

5. Start chain as a validator

The --key is the password from above

substrate --chain ~/mychain.json --node-key "$(< ~/.node_key)" --validator --key 0xd26c63905a3b2f455185cff37dfbe1b70ec3c16ea33138772d430f24d6c1d7d2

Run a second node (on the same machine, different Linux user)

adduser --disabled-login --gecos "" bob && usermod -a -G docker bob
cp mychain.json ~bob

Now start Substrate node as bob via docker

su bob
cd ~
mkdir --mode=777 substrate_data
export NODE_PORT=8002
docker run \
  --user "$UID" \
  -v "$HOME":/data \
  -p "$NODE_PORT:$NODE_PORT/tcp" \
  parity/substrate:latest \
  --chain /data/mychain.json --base-path /data/substrate_data --port "$NODE_PORT"

Update substrate

cargo install --git https://github.com/paritytech/substrate subkey --force
cargo install --git https://github.com/paritytech/substrate substrate --force