Creating a Private Chain/Testnet

This guide is here to help you set-up a private blockchain in Ethereum using Geth.

Information that helped me compile this guide:

Tasha at π Tech Lab has an excellent write up on the Ethereum genesis block and creating a private test network. Please go there for more detailed information about custom genesis blocks and what some of the lines in a custom genesis block mean.

Ade Duke also has a great private Ethereum chain guide that helped me write this article.

What is Geth?

Geth is the CLI Ethereum client that runs on Windows, Mac, and Linux platforms. Geth is widely used to interact with Ethereum networks.

Creating a Private Ethereum Chain

Ethereum software enables a user to set up a "private" or "testnet" Ethereum chain that is separate from the main Ethereum chain. This is useful for testing distributed apps built on Ethereum without having to expose your apps or trials to the real Ethereum network using real Ether. You either pre-generate or mine your own Ether on your private Ethereum chain, so it is a much more cost effective way of trying out Ethereum. What are the components that tell Geth that we want to use/create a private Ethereum chain? The things that dictate a private Ethereum chain are:

  • Custom Genesis File
  • Custom Data Directory
  • Custom NetworkID
  • (Recommended) Disable Node Discovery

The Genesis File

The Genesis block is the start block of the Blockchain - the first block, block 0, and the only block that does not point to a predecessor block. the genesis block is hard coded into clients, but in Ethereum it can be whatever you like. This gives us lots of options to create a customized, private blockchains based on our needs. Ethereum's consensus algorithm ensures that no other node will agree with your version of the blockchain unless they have the same genesis block.


    "nonce": "0x0000000000000042",
    "timestamp": "0x0",
    "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "extraData": "0x0",
    "gasLimit": "0x8000000",
    "difficulty": "0x400",
    "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "coinbase": "0x3333333333333333333333333333333333333333",
    "alloc": {

Save a file called CustomGenesis.json (or whatever you want to call it). You will reference this when starting your geth node using the flag:

--genesis CustomGenesis.json

Note: The above flag may need to be changed depending on where you saved the JSON file.

Flags For Your Private Network

There are some command line options (also called "flags") that are necessary in order to make sure that your network is private.


Use this to make sure that your node is not discoverable by people who do not manually add you. Otherwise, there is a chance that your node may be inadvertently added to a stranger's node if they have the same genesis file and network id.

--maxpeers 0

Use maxpeers 0 if you do not want anyone else connecting to your test chain. Alternatively, you can adjust this number if you know exactly how many peers you want connecting to your private chain.


This will enable RPC interface on your node. This is generally enabled by default in Geth.

--rpcapi "db,eth,net,web3"

This dictates what APIs that are allowed to be accessed over RPC. By default, Geth enables the web3 interface over RPC.

IMPORTANT: Please note that offering an API over the RPC/IPC interface will give everyone access to the API who can access this interface (e.g. DApp's). Be careful which API's you enable. By default geth enables all API's over the ipc interface and only the db,eth,net and web3 API's over the RPC interface.

--rpcport "8080"

Change 8000 to any port that is open on your network. The default for geth is 8080 and althzero is 8545.

--rpccorsdomain "*"

This dictates what URLs can connect to your node in order to perform RPC client tasks. Be very careful with this and when possible, put a specific URL rather than the wildcard (*) which allows any URL to connect to your RPC instance. Since this is a private chain that will not hold real Ether, I usually put a wildcard so I can use sites such as Browser Solidity or DApps like Notareth. When you build DApps outside of Mist or Alethzero, you will need to connect your website to an Ethereum node.

--datadir "/home/HudsonChain1"

This is the data directory that your private chain data will be stored in. Choose a location that is separate from the public Ethereum chain folder.

--port "30303"

This is the "network listening port", which you will use to connect with other peers manually.

--nat "any"

I use the NAT any setting, but this will be dependent on your network configuration.

--identity "HudsonMainNode" This will set up an identity for your node so it can be identified more easily in a list of peers. Here is an example of how these identities show up on the network.

Notice the lines with "HudsonMainNode" and "Hudson2ndNode"

Putting it All Together

You will need to start your geth instance with your custom chain command every time you want to access your custom chain. If you just type “geth” in your console, it will not remember all of the flags you have set.

After you have created your custom genesis block JSON file and created a directory for your chain to go into, type the following command into your console that has access to geth:

geth --identity "MyNodeName" --genesis CustomGenesis.json --rpc --rpcport "8000" --rpccorsdomain "*" --datadir "C:\chains\VPSChain" --port "30303" --nodiscover --ipcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --rpcapi "db,eth,net,web3" --autodag --networkid 1900 --nat "any" console

Note: Please change the flags to match your custom settings.

You will need to start your geth instance with your custom chain command every time you want to access your custom chain. If you just type "geth" in your console, it will not remember all of the flags you have set. Different operating systems have ways to make this easier. Most allow you to make a shortcut file that will automatically open a console window and run commands that you specify. On Windows systems, look up how to create a .bat or .cmd file that runs the commands you require. On Linux/Unix/Mac systems, look up .sh files.

Running Geth from 2+ Consoles

There is a --verbosity flag that will allow you to decide how much of the inner working of Geth are shown when youa re running Geth in your console.

In Geth it is defined as:

Logging verbosity: 0-6 (0=silent, 1=error, 2=warn, 3=info, 4=core, 5=debug, 6=debug detail)

It can be compared to a log-level flag that you may find on other programs. If is possible to have 2 console windows open with different levels log levels. I do this because if I have my miner running on my first console window, it will sometimes be spitting out log details too fast for me to type commands cleanly. Once you have your first geth instance open, open another console/terminal and type the following:

geth attach

This will connect your 2nd console to the Geth instane on your first console. If you'd like to attach a remote console to a Geth instance using either the IPC or RPC interface, see this article in the Ethereum wiki.

Pre-Allocating Ether to Your Account

A difficulty of “0x400” allows you to mine Ether very quickly on your private testnet chain. If you create your chain and start mining, you should have hundreds of Ether in a matter of minutes which is way more than enough to test transactions on your network. If you would still like to pre-allocate Ether to your account, you will need to:

  1. Create a new Ethereum account after you create your private chain
  2. Copy your new account address
  3. Add the following command to your Custom_Genesis.json file:
    "<your account address e.g. 0x1fb891f92eb557f4d688463d0d7c560552263b5a>":
    { "balance": "20000000000000000000" } 

Note: Replace 0x1fb891f92eb557f4d688463d0d7c560552263b5a with your account address.

Save your genesis file and re-run your private chain command. Once geth is fully loaded, close Geth.

We want to assign an address as “primary” and check it’s balance.

Run the command geth account list in your console to see what account # your new address was assigned.

> geth account list
Account #0: {d1ade25ccd3d550a7eb532ac759cac7be09c2719}
Account #1: {da65665fc30803cb1fb7e6d86691e20b1826dee0}
Account #2: {e470b1a7d2c9c5c6f03bbaa8fa20db6d404a0c32}
Account #3: {f4dd5c3794f1fd0cdc0327a83aa472609c806e99}

Take note of which account # is the one that you pre-allocated Ether to.

> primary = eth.accounts[0];

Note: Replace 0 with your account’s number. This console command should return your primary Ethereum address.

Type the following command:

> balance = web3.fromWei(eth.getBalance(primary), "ether");

This should return you 20 Ether in your account. The reason we had to put such a large number in the alloc section of your genesis file is because the “balance” field takes a number in wei which is the smallest sub-unit of Ether.

Set Up Static Nodes

Geth supports a feature called static nodes if you have certain peers you always want to connect to. Static nodes are re-connected on disconnects. You can configure permanent static nodes by putting something like the following into <datadir>/static-nodes.json (this should be the same folder that the chaindata and keystore folders are in)

  "enode://f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de10[email protected]",
  "enode://[email protected]:port"

You can also add static nodes at runtime via the Javascript console using admin.addPeer()

> admin.addPeer("enode://f4642fa65af50cfdea8fa7414a5def7bb7991478b768e296f5e4a54e8b995de10[email protected]")

See this page for more information

Running Your Node in The Background

If you are putting your node on an external server like AWS, DigitalOcean, or another VPS, you may want to put your geth process in the background so Geth doesn't shut down once you close your console window. There are many ways to do this. My reccomendation is NoHUP when your node is run on a Linux/Unix instance such as an Ubuntu Server.

Read about NOHUP Here

After making sure nohup is installed, simply add nohup to the beginning your geth command, delete console, and add & to the end of the statement:

nohup geth --identity "MyNodeName" --genesis CustomGenesis.json --rpc --rpcport "8000" --rpccorsdomain "*" --datadir "C:\chains\VPSChain" --port "30303" --nodiscover --ipcapi "admin,db,eth,debug,miner,net,shh,txpool,personal,web3" --rpcapi "db,eth,net,web3" --autodag --networkid 1900 --nat "any" &

Your console output is placed in a nohup logfile in the directory that you ran nohup from. To make sure your geth instance is running in the background, run the following command (or an equivalent for your OS):

ps aux | less