How to set up a Private Ethereum Blockchain (Proof of Authority) with Go Ethereum - Part 1

Written by isseikumagai | Published 2022/01/02
Tech Story Tags: web3 | ethereum | blockchain | metamask | geth | build-private-ethereum-chain | ubuntu | aws

TLDRvia the TL;DR App

Introduction

This article will go through the steps necessary to set up a Private Ethereum Blockchain using Go Ethereum (Geth) - the official Go implementation of the Ethereum protocol. This is useful when developers do not want to rely on the public testnets such as Rinkeby, Ropsten, Goerli.

The private blockchain will be deployed on the cloud Ubuntu server (AWS). We will also integrate with Metamask by creating a custom RPC URL, and look at some important web3 JSON RPCs. The Metamask integration and RPCs will be covered in Part 2 of this article.

This article contains the following:

  • Set up the Cloud Ubuntu Server
  • Connect to your Linux instance from Windows using PuTTY
  • Install Geth (Go Ethereum)
  • Create Validator Accounts
  • Create a Genesis File
  • Initialize and Start the Nodes

OS and Software

  • OS: Ubutu 20.04
  • Software: Geth Version: 1.10.14-stable

Set up the Cloud Ubuntu Server

Click on the Launch a Virtual machine.

Select the below Ubuntu Server version - 20.04

Choose the Free tier eligible instance.

No need to configure anything here.

Add 16 GiB.

No need to configure anything here.

Configure the Security Group (TCP/UDP) as follows. This is very important, as we need to make sure we open specific ports for the private blockchain network.

Create a new key pair as follows, then Download Key Pair.

Connect to your Linux instance from Windows using PuTTY

Note: This article assumes that you are puttying into the server from a Windows OS.

Please see the AWS Amazon link for setting this up. You need to install PuTTy before proceeding with this step.

https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html

Install Geth (Go Ethereum)

SSH into the server via PuTTY session. Type in the following commands. For more information, please see - https://geth.ethereum.org/downloads/

$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install ethereum

Create Validator Accounts

We will be setting up two nodes - node1 and node2 for the private blockchain. Therefore, we need to create two validator accounts (two Public Addresses). The so-called “Validators” also known as Sealers in PoA (Proof of Authority), will be confirming the transactions and adding new blocks.

SSH into the server via PuTTY session. Type in the following commands.

$ mkdir blockchain_nodes
$ cd blockchain_nodes
blockchain_nodes$ mkdir node1 node2

Create validator accounts as follows. Make sure you save the Public Address generated for node1 and node2.

blockchain_nodes$ geth --datadir node1/ account new

...
Your new key was generated

Public address of the key:   0x9F1C28A2C8D07d928968C3Dd7201d672D04D4DfD
Path of the secret key file: node1/keystore/UTC--2022-01-01T05-35-37.744385813Z--9f1c28a2c8d07d928968c3dd7201d672d04d4dfd

...

blockchain_nodes$ geth --datadir node2/ account new

...
Your new key was generated

Public address of the key:   0x7Bb542DEd40d0E6Bd01a1bAe39ec5E9984f36E48
Path of the secret key file: node2/keystore/UTC--2022-01-01T05-42-30.682329725Z--7bb542ded40d0e6bd01a1bae39ec5e9984f36e48

Save the Public Address generated to the accounts.txt file.

blockchain_nodes$ echo '0x9F1C28A2C8D07d928968C3Dd7201d672D04D4DfD' >> accounts.txt
blockchain_nodes$ echo '0x7Bb542DEd40d0E6Bd01a1bAe39ec5E9984f36E48' >> accounts.txt

Save the passwords you have inputted when creating the validator accounts.

blockchain_nodes$ echo 'node1Password' > node1/password.txt
blockchain_nodes$ echo 'node2Password' > node2/password.txt

Create a Genesis File

The Genesis File contains all the data required to create the genesis block (block 0), that is, the first block of the blockchain. The JSON file contains information such as how many Ether it starts with, etc - the initial state of the blockchain.

Run puppeth.

blockchain_nodes$ puppeth

Specify the networkID/chainID. You must save this as this will be used in the future.

Please specify a network name to administer (no spaces, hyphens or capital letters please)
> 4649

Configure new-genesis.

What would you like to do? (default = stats)
1. Show network stats
2. Configure new genesis
3. Track new remote server
4. Deploy network components
> 2

Create a new genesis.

What would you like to do? (default = create)
 1. Create new genesis from scratch
 2. Import already existing genesis
> 1

Select proof-of-authority.

Which consensus engine to use? (default = clique)
 1. Ethash - proof-of-work
 2. Clique - proof-of-authority
> 2

Use the default value.

How many seconds should blocks take? (default = 15)
> 15

Input the Public Address of the two nodes.

Which accounts are allowed to seal? (mandatory at least one)
> 0x9F1C28A2C8D07d928968C3Dd7201d672D04D4DfD
> 0x7Bb542DEd40d0E6Bd01a1bAe39ec5E9984f36E48
> 0x

Again do the same - which accounts require pre-funds.

Which accounts should be pre-funded? (advisable at least one)
> 0x9F1C28A2C8D07d928968C3Dd7201d672D04D4DfD
> 0x7Bb542DEd40d0E6Bd01a1bAe39ec5E9984f36E48
> 0x

Select Yes.

Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)
> yes

Specify you ChainID/NetworkID that you selected earlier.

Specify your chain/network ID if you want an explicit one (default = random)
> 4649
INFO [01-01|06:41:01.046] Configured new genesis block

Select Manage existing genesis.

What would you like to do? (default = stats)
 1. Show network stats
 2. Manage existing genesis
 3. Track new remote server
 4. Deploy network components
> 2

Export genesis configurations.

 1. Modify existing configurations
 2. Export genesis configurations
 3. Remove genesis configuration
> 2

Don’t type in anything - hit Enter.

The errors indicate that 4649-aleth.json and 4649-parity.json will not be created - which is correct.

Which folder to save the genesis specs into? (default = current)
  Will create 4649.json, 4649-aleth.json, 4649-harmony.json, 4649-parity.json
>
INFO [01-01|06:41:12.642] Saved native genesis chain spec          path=4649.json
ERROR[01-01|06:41:12.643] Failed to create Aleth chain spec        err="unsupported consensus engine"
ERROR[01-01|06:41:12.643] Failed to create Parity chain spec       err="unsupported consensus engine"
INFO [01-01|06:41:12.644] Saved genesis chain spec                 client=harmony path=4649-harmony.json

Hit Ctrl + C (or Ctrl + D) to exit out of puppeth.

What would you like to do? (default = stats)
 1. Show network stats
 2. Manage existing genesis
 3. Track new remote server
 4. Deploy network components
> ^C

Delete the XXXX-harmony.json file.

blockchain_nodes$ rm 4649-harmony.json

Re-name the genesis JSON file as follows.

blockchain_nodes$ mv 4649.json genesis.json

Initialize and Start the Nodes

Initialize and create the nodes with the gensis JSON file created earlier.

blockchain_nodes$ geth --datadir node1/ init genesis.json
blockchain_nodes$ geth --datadir node2/ init genesis.json

Create bash scripts. These bash scripts are used to start the geth service on the Ubuntu server.

blockchain_nodes$ touch node1/node1.sh 
blockchain_nodes$ touch node2/node1.sh

Use vim text editor to open up the bach scripts created.

blockchain_nodes$ vim node1/node1.sh

Copy and paste the below and save the bash script. Make sure you have the correct values for the following parameters:

  • port
  • networkid
  • http.addr
  • http.port
  • unlock

For more information regarding the geth command-line options, check out - https://geth.ethereum.org/docs/interface/command-line-options

# Node 1
nohup geth 	--nousb \
			--datadir=$pwd \
			--syncmode 'full' \
			--port 30310 \
			--networkid 4649 \
			--miner.gasprice 0 \
			--miner.gastarget 470000000000 \
			--http \
			--http.addr 172.31.15.81 \
			--http.corsdomain '*' \
			--http.port 8545 \
			--http.vhosts '*' \
			--http.api admin,eth,miner,net,txpool,personal,web3 \
			--mine \
			--allow-insecure-unlock \
			--unlock "0x9F1C28A2C8D07d928968C3Dd7201d672D04D4DfD" \
			--password password.txt &    
      
echo "Node 1 Start"

Use vim text editor to open up the second bash scripts created.

blockchain_nodes$ vim node2/node2.sh

Copy and paste the below and save the bash script. Make sure you alter the unlock address to the one you have generated previously.

# Node 2
nohup geth 	--nousb \
			--datadir=$pwd \
			--syncmode 'full' \
			--port 30311 \
			--networkid 4649 \
			--miner.gasprice 0 \
			--miner.gastarget 470000000000 \
			--http \
			--http.addr 172.31.15.81 \
			--http.corsdomain '*' \
			--http.port 8546 \
			--http.vhosts '*' \
			--http.api admin,eth,miner,net,txpool,personal,web3 \
			--mine \
			--allow-insecure-unlock \
			--unlock "0x7Bb542DEd40d0E6Bd01a1bAe39ec5E9984f36E48" \
			--password password.txt &

echo "Node 2 start"

Change directory to node1 and run the bash script - node1.sh.

blockchain_nodes$ cd node1
blockchain_nodes/node1$ sh node1.sh

Now, grep for the enode address. Save the enode address.

blockchain_nodes/node1$ grep "self=enode:" nohup.out
INFO [01-01|08:47:06.591] Started P2P networking                   self=enode://915fb194d8fdda7c96505c7100b5352c7fcfb7ad674b65b848da7089460b038abce961cfb83c5251e92ea10c7a970cf48b06f2a3f1d8f2e19c45c9082d1a9770@127.0.0.1:30310

Change directory to node2 and run the bash script - node2.sh.

blockchain_nodes$ cd node2
blockchain_nodes/node2$ sh node2.sh

Now, grep for the enode address, this time for node2. Save the enode address.

blockchain_nodes/node2$ grep "self=enode:" nohup.out
INFO [01-01|09:06:56.048] Started P2P networking                   self=enode://52c0bccf83affa7c1a25d3d87b3ffbb968c079b22c40b08082531fccdebea1166f6447ba3a953a3c780109942b2744ccf1afce3090e4e25d4f13e3376117acca@127.0.0.1:30311

We will use static nodes to connect to our private network.

Create the JSON file so that nodes always know which peers to connect to. We will be using the enodes identified earlier to connect the two nodes together.

We will first create this for node1 first.

blockchain_nodes$ touch node1/static-nodes.json

Open up the vim text editor.

blockchain_nodes$ vim node1/static-nodes.json

Paste the following - these are the enode addresses obtained earlier.

[
"enode://915fb194d8fdda7c96505c7100b5352c7fcfb7ad674b65b848da7089460b038abce961cfb83c5251e92ea10c7a970cf48b06f2a3f1d8f2e19c45c9082d1a9770@127.0.0.1:30310",

"enode://52c0bccf83affa7c1a25d3d87b3ffbb968c079b22c40b08082531fccdebea1166f6447ba3a953a3c780109942b2744ccf1afce3090e4e25d4f13e3376117acca@127.0.0.1:30311"
]

Copy the static-nodes.json file to the node2 folder.

blockchain_nodes$ cp node1/static-nodes.json node2/

Reboot the Ubuntu Server, then re-run the scripts - node1.sh & node2.sh

blockchain_nodes$ sudo reboot now
blockchain_nodes/node1$ sh node1.sh
blockchain_nodes/node2$ sh node2.sh

Run the following command to access the geth node.

blockchain_nodes/node1$ geth attach geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.10.14-stable-11a3a350/linux-amd64/go1.17.5
coinbase: 0x9f1c28a2c8d07d928968c3dd7201d672d04d4dfd
at block: 6 (Sat Jan 01 2022 13:04:43 GMT+0000 (UTC))
 datadir: /home/ubuntu/blockchain_nodes/node1
 modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0

Execute the following. Number ‘1’ should appear as the head node only has one peer.

> net.peerCount    
1

To make sure all the Geth Services are running, check the processes. Make sure you see the two Geth services with the correct Public Address for the nodes.

$ ps aux | grep geth
ubuntu       856  1.8 17.2 1738404 170944 ?      Sl   Jan01  53:01 geth --nousb --datadir= --syncmode full --port 30310 --networkid 4649 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 172.31.15.81 --http.corsdomain * --http.port 8545 --http.vhosts * --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock 0x9F1C28A2C8D07d928968C3Dd7201d672D04D4DfD --password password.txt
ubuntu       873  1.8 15.7 1738396 156456 ?      Sl   Jan01  52:32 geth --nousb --datadir= --syncmode full --port 30311 --networkid 4649 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 172.31.15.81 --http.corsdomain * --http.port 8546 --http.vhosts * --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock 0x7Bb542DEd40d0E6Bd01a1bAe39ec5E9984f36E48 --password password.txt
ubuntu      7146  0.0  0.0   8168   664 pts/0    S+   11:54   0:00 grep --color=auto geth


Written by isseikumagai | Loves blockchain/web3
Published by HackerNoon on 2022/01/02