Running a “quick” Ethereum private network for experimentation and testing
This post provides step by step instructions on how to install a quick Ethereum private network on Ubuntu 16.04 LTS. By “quick” I mean a private Ethereum network with very fast block creation intervals. The premis is to have a reserved and private testbed for no other purpose than rapid experimentation and testing. Put simply, the ability to completely control, as well as instantly mine, an Ethereum private network. The trade off of course, is that this Ethereum private network is not protected or secure. But as there is no real value on this network (aside from the findings which result from experiments and testing) this will not be an issue. It goes without saying, that it can and should be run behind a properly configured firewall.
Explaining Ethereum networks
For peer-to-peer nodes to interact on the same network they have to have the identical protocol version and the right network ID. In order for peer nodes to connect to the main Ethereum network, nothing extra is required; simply starting the Ethereum software will suffice.
From an experimental, testing perspective there are two main drawbacks to using the main Ethereum network. Firstly, of course starting Ethereum with the default network settings will result in your peer (full) node downloading the entire Ethereum blockchain. This takes a significant amount of time and requires a lot of storage on your local disk. Secondly any activity on the main Ethereum network requires “gas”. Whilst this gas is obtainable, it involves purchasing and depositing actual ETH into your account. You may not want to do this just for rapid experimentation and testing. So what about running a test network?
There are other ways to start your Ethereum node. You may want to use an Ethereum test network like Ropsten as this will provide the flexibility to participate on the network without purchasing ETH. Testnet ETH can be obtained without having to pay real money. This solves one problem, however using a testnet like Ropsten also requires you to download the Ropsten testnet blockchain. This again, takes a considerable amount of time and also requires quite a lot of local disk space.
One final alternative is to run your very own private Ethereum network. A private network requires negligible local disk storage and can be operated without having to purchase ETH with real money. So what constitutes a private Ethereum network?
“An Ethereum network is a private network if the nodes are not connected to the main network nodes. In this context private only means reserved or isolated, rather than protected or secure.”
As mentioned on the Ethereum GitHub page a private network is neither protected or secure. In addition, setting up a private network requires a little bit of extra configuration. You can alleviate the security aspect by simply running the private Ethereum network behind a properly configured firewall. With security aside, all that is left, is to perform is the extra configuration (which we will detail below).
Installation on Ubuntu 16.04 LTS
Firstly we will perform some general housekeeping and download some extra software.
After the basic housekeeping, change to your home directory and download Go1.9.3
Your download can be verified against the live Go website using the following sha256sum command
To unpack Go, type the following command (using sudo)
To ensure that the Go path is set for your user profile. Add the following line to the end of your ~/.profile file
Log out and then log back in (or reboot) to ensure the PATH environment variable has activated. To test the PATH and the version of Go, use the following two commands
Reducing the mining difficulty of Ethereum
As previously discussed this will be an exclusive private testing network, and as such we do not want the Ethereum installation constantly adjusting the mining difficulty; we want the quickest mining time possible
The lowest mining value is 1. To set the difficulty at 1, statically, we need to run the following command which opens the consensus.go source code (which we already fetched during the housekeeping section above)
At around line 298 you will see a function called CalcDifficulty. The following image shows how this function sets the mining difficulty by calling one of 3 other functions (more specifically the Frontier, Homestead or Byzantium related difficulty adjustment).
If you remove everything inside this particular CalcDifficulty function and just add a single return statement, as pictured below, the mining difficulty will remain at its lowest possible difficulty level on an ongoing basis.
Building Go Ethereum
We have altered the source code and so we will now build Go Ethereum (from source) by simply running the following commands
Configuring and running Go Ethereum
The following paragraphs will help with configuring and running the Ethereum private network.
The network ID for the main Ethereum network is 1. If started in default mode, the code will automatically connect to the main Ethereum network.
Alternatively, the network ID can be passed into the command line when starting Go Ethereum
Obviously, in order to keep other nodes from connecting to your private Ethereum network it would be in your best interests to a) secure the network using a properly configured firewall and b) choose a unique network ID within your network. We will be using a network id of 15 today
In a moment we will be using a once off mechanism to fund our accounts. Before we use that mechanism we need to:
a) create a data directory for Ethereum
b) create our new accounts and
c) save those account details for use on future steps.
It is recommended that you run the “geth account new …” command shown above at least twice. This will provide you with at least two accounts; accounts which you can use to transfer your free ETH back and forth.
When running Ethereum for the first time, if the default settings are used, the blockchain will start at the “hard coded” genesis block (first block in the public main net blockchain). From this point onward the code will find peers and synchronize until the Ethereum instance which you are running is up to date. Being synchronized, or up to date, means that you are storing everything from the genesis block, right up, to the most recent block, locally.
Ethereum’s blockchain is almost 45GB in size and so for our purpose of testing this is not desirable. You may recall that this is one of the reasons why we chose to run our own private network.
In order to run our own network, we are going to create our own genesis block. To do so, we create a file, such as below, and save it (into the recently created ~/gethDataDir) with the name genesis.json
Note you must paste your newly created account addresses in the “alloc” section and then fund them in the “alloc/balance” section (as demonstrated above)
Note how the “chainId” section is deliberately set to 15 (our private networkid)
Initializing the blockchain
Type the following initialization command, this will reference the genesis block and initialize a new blockchain for our private network
Type the following command to start Ethereum. Please note that the networkid (15) must be the same as the “chainId” in our genesis.json file
The above command will start our Ethereum private network and, among other things, will provide an Inter-Process Communication (IPC) endpoint
Connecting to the IPC endpoint (starting and using the console)
The following commands will:
a) list the Ethereum accounts which we recently created
b) show our account balances
c) reveal our coinbase address (where mining rewards are sent) and
d) show our mining status (true/false)
Mining the Ethereum private network
As you can see from above, the Geth instance that we are running is not performing any mining. To mine the Ethereum private network you must:
a) stop the original geth instance by pressing “ctrl + c” in the main window
b) disconnect from IPC by typing exit in the console
c) type the following commands
Please note the specific parameters which we provide such as datadir and networkid. These are to ensure the mining takes place using the correct accounts and network
As you can see from the output, we are now mining and sealing new blocks every few seconds
If we open a new tab and connect to the console again, we can see that the coinbase account balance has increased significantly due to its successful mining operations.
Note the two different ways in which we accessed the coinbase account’s balance. Firstly by obtaining and using the account’s address explicitly and secondly by nesting the two web3 commands together (passing the coinbase account address as an argument to the getBalance function).
From this moment onward, you can create transactions, write smart contracts and configure more and more nodes to join your private network. These additional tasks are out of scope for this post, however they will be covered in other posts, so feel free to follow for updates.