Making a Cosmos chain

Making a Cosmos chain

Cosmos is a project creating an "Internet of blockchains" which will be linked together through the IBC protocol. Unlike many blockchains, where your application will have to pay fees to some weird guys with rooms full of GPUs, on Cosmos, you build your own chain, and most tx fees can go to your blockchain's token holders, with validators charging 0-10% of tx fees for running the infrastructure.

Building your own blockchain also gives you a lot of flexibility. If Bitcoin is a pocket calculator with a few functions, and Ethereum is a graphing calculator with the ability to upload some limited scripts, then Cosmos is Ruby on Rails. You start from a full-featured base application built from a robust set of libraries, and customize anything and everything about it.

The base application that you start from is called gaia. This is the same software that the Cosmos Hub chain runs. This blog post gives instructions for starting a chain with 2 validators, although it would be easy to adapt these instructions to a larger group of validators.


First install everything. These steps are the same if you are initializing a new Cosmos chain, or joining someone else's. They work on new DigitalOcean Ubuntu droplets, but will probably work on many other Linux systems, although you may have to install other dependencies such as Git.

Download and install Golang (from

tar -C /usr/local -xzf go1.12.5.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

Set up some required Golang environment variables (from

mkdir -p $HOME/go/bin
echo "export GOPATH=$HOME/go" >> ~/.bash_profile
echo "export PATH=\$PATH:\$GOPATH/bin" >> ~/.bash_profile
source ~/.bash_profile

Get some build tools used to build the binaries

apt install make
apt install gcc

Download gaia, the Cosmos hub codebase

mkdir -p $GOPATH/src/
cd $GOPATH/src/
git clone

Build the binaries

cd gaia && make install

Check that it was installed correctly

gaiad version --long
gaiacli version --long

gaiacli for instance should output something similar to:

cosmos-sdk: 0.33.0
git commit: 7b4104aced52aa5b59a96c28b5ebeea7877fc4f0
build tags: netgo ledger
go version go1.12 linux/amd64

Initializing a new Cosmos chain

Now it's time to set up the starting conditions for your network using a file called genesis.json. This is very important on a proof of stake chain, since everything else that will happen during the life of the chain will originate from the authority and value granted here. For example, on the Cosmos Hub, the genesis.json file contained the amounts of Atoms purchased by crowdsale participants.

The process of starting a Cosmos chain has multiple steps, but each step is important. Participants in a blockchain system trust the process instead of each other, and each step of this process lets them verify that everything is kosher.

  1. Someone creates a genesis.json file with initial token allocations and sends it to all the starting validators for inspection.
  2. If the validators feel that the genesis.json file is valid, they sign gentxs to get added as validators on the chain.
  3. Someone compiles all the gentxs and adds them to the genesis.json, again sending it out to all the validators for inspection.
  4. If the validators feel that the genesis.json is still valid, they start their nodes and start producing blocks.

We'll be using the instructions here for a "Single-node, Local, Manual Testnet", but we will modify them to create a multiple-node, remote, manual network. This assumes that you've got two servers set up according to the above instructions. If you only set up one, go ahead and set up another one now.

Step 1.

Follow these instructions for validator 1:

# These commands are run on validator 1

# You can run all of these commands from your home directory
cd $HOME

# Initialize the genesis.json file that will help you to bootstrap the network
gaiad init --chain-id=mychain validator1

# Create a key to hold your validator account
gaiacli keys add validator1

# Add that key into the genesis.app_state.accounts array in the genesis file
# NOTE: this command lets you set the number of coins. Make sure this account has some coins
# with the genesis.app_state.staking.params.bond_denom denom, the default is staking
gaiad add-genesis-account $(gaiacli keys show validator -a) 1000000000stake,1000000000footoken

Now, switch to validator 2

# These commands are run on validator 2

# Create a key to hold your validator account
gaiacli keys add validator2

# Show the address
gaiacli keys show validator2 -a

Copy the key output by the second command and switch back to validator 1:

# These commands are run on validator 1

# Add validator2's address and allocation to genesis.json
gaiad add-genesis-account <address copied from validator2> 1000000000stake,1000000000footoken

# Export genesis.json
gaiad export

Copy the genesis.json output by the second command and switch back to validator 2:

# These commands are run on validator 2

# Save the genesis.json from the last step in:

Step 2.

Now it is time to make the gentxs

# These commands are run on validator 2

gaiad gentx --name validator2

# This should output something like:
# Genesis transaction written to "/root/.gaiad/config/gentx/gentx-33e8c0fbef25d8d455aefa1fd33fb6982f5484ec.json"

# Copy the gentx from the file where it was saved
Step 3.

Switch back to validator 1

# These commands are run on validator 1

# Save the gentx from validator2 to:
# /root/.gaiad/config/gentx/<name of gentx file from validator2>.json

# Now make a gentx file for validator1 as well
gaiad gentx --name jehan

# Now generate the final genesis.json
gaiad collect-gentxs

Switch back to validator 2 and again save the genesis.json file produced by validator 1

# These commands are run on validator 2

# Save the genesis.json from the last step in:
Step 4.

Now, running gaiad start on both nodes should start your blockchain. You may have to start one or the other one first. You'll probably want to use something like systemd to keep the validators running when the system restarts, but that's beyond the scope of this blog post.

In the next post, we'll talk about how to send coins to another account, and how they can get added to the validator set.