How to setup a Ethereum POA (private-proof-of-authority-ethereum-network) network on Amazon AWS (1st Part)

Akshay Pilankar
8 min readOct 4, 2019



I came across a lot of online tutorials and blogs to setup private proof of authority ethereum network on aws but none of them showed the bells and whistles to make to more like ethereum mainnet standards with WebSocket setup, network monitor, URL wrapped, SSL support, etc. So in this blog will cover all the necessary steps to set up a production-ready POA setup on ethereum.

PS: this is my first blog… I believe I will be good at this eventually. :)

The tutorial is divided into sections mentioned below —

  1. AWS EC2 instance setup and private network setup.
  2. Url wrapper & SSL support.
  3. network monitor and basic explorer.

Section 1 —

This is a link to setup Amazon AWS account. there are few other options available like digital ocean, google cloud, Microsoft azure with almost year worth of free subscription on the server. this provides basic server and can be easily upgraded for scaling. I prefer AWS cause I am using it for almost year and a half now.

Once you are registered on AWS, the next step is to start EC2 server

Click on EC2 tab in All services. and click on Launch Instance inside Create Instance tab.

AWS dashboard

2. This will take you to Launch Instance Wizard. In which we can select the type of OS, storage, ports and PEM file for instance or server we can say.

It takes at least 5 to 10 min to complete build once it’s done you can check the new instance in. I believe so far you have created an EC2 instance successfully. Congratulations! you can find all instances in EC2 dashboard under Instances tab. it will show all the servers. In our case, there will be only one server so click on that server and then click on connect.

this will show one modal which will have the command for our command prompt to connect to the server. any ubuntu /mac cmd will work in this case.

open CMd and go to the directory in which the key pair file is saved. the .pem key. copy this command and paste it to cmd and hit enter to connect to the server. it will ask you Are you sure you want to continue connecting (yes/no)? type yes and hit enter.

Upon a successful connection, you will see this screen where ubuntu@yourIp will be mentioned.

Now will start with ethereum geth and few other tools installations and it is same as we do it on our regular desktop and laptop(just for Mac and Ubuntu).. just copy the commands to cmd one at a time…

sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install ethereum
sudo apt install nginx
sudo ufw enable
sudo ufw allow 'Nginx Full'
sudo ufw allow 'OpenSSH'
sudo add-apt-repository ppa:certbot/certbot
sudo apt install python-certbot-nginx
sudo ufw status

now check the status of ufw by typing — sudo ufw status

OutputStatus: activeTo                         Action      From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)

then check for Nginx service — systemctl status Nginx

Output● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2018-04-20 16:08:19 UTC; 3 days ago
Docs: man:nginx(8)
Main PID: 2369 (nginx)
Tasks: 2 (limit: 1153)
CGroup: /system.slice/nginx.service
├─2369 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─2380 nginx: worker process

Till now we have installed ethereum geth on the sever and few tools for port forwarding(Nginx) and SSL encryption(certbot).

Next up is Private network setup

go to root folder by typing

cd ~

In this case, we are going to create a network of two signer nodes. make a folder for network files.

mkdir testnet
cd testnet
mkdir node1 node2
geth --datadir node1/ account new

This command will ask you to enter the password and uppon show some output like this. please copy-paste the Public address of the key given in this output to some notepad.

INFO [09–29|14:30:30.866] Maximum peer count ETH=50 LES=0 total=50

INFO [09–29|14:30:30.867] Smartcard socket not found, disabling err=”stat /run/pcscd/pcscd.comm: no such file or directory”

Your new account is locked with a password. Please give a password. Do not forget this password.


Repeat password:

Your new key was generated

Public address of the key: 0x518Ba9843d9a9c351B3c3B8719408583246c9241

Path of the secret key file: node3/keystore/UTC — 20129–09–29T14–30–36.547646701Z — 518ba9843d9a9c351b3c3b8719408583246c9241

- You can share your public address with anyone. Others need it to interact with you.

- You must NEVER share the secret key with anyone! The key controls access to your funds!

- You must BACKUP your key file! Without the key, it’s impossible to access account funds!

- You must REMEMBER your password! Without the password, it’s impossible to decrypt the key!

Now let’s create an account for node 2

geth --datadir node2/ account new

again it will ask for the password and same message with a different public key. again copy-paste the Public address of the key given in this output to some notepad.

Next is creating genesis.json. for that, we can use puppeth command directly on cmd.

Please specify a network name to administer (no spaces, please)
> devnet
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
Which consensus engine to use? (default = clique)
1. Ethash - proof-of-work
2. Clique - proof-of-authority
> 2
How many seconds should blocks take? (default = 15)
> 3 // in case you want to mine on demand then make it 0
Which accounts are allowed to seal? (mandatory at least one)
> 0x518Ba9843d9a9c351B3c3B8719408583246c9241 // remove 0x from the address and copy paste it here.
> 0x6a9c3c4d6e60c2c47d21ef607a00ccbb7ca3a581
Which accounts should be pre-funded? (advisable at least one)
> 0x518Ba9843d9a9c351B3c3B8719408583246c9241 // again same step for ethers.
> 0x6a9c3c4d6e60c2c47d21ef607a00ccbb7ca3a581
Specify your chain/network ID if you want an explicit one (default = random)
> 48333442 // for example. Do not use anything from 1 to 10
What would you like to do? (default = stats)1. Show network stats2. Manage existing genesis3. Track new remote server4. Deploy network components> 21. Modify existing configurations2. Export genesis configurations3. Remove genesis configuration> 2Which folder to save the genesis specs into? (default = current)
Will create genesis.json, genesis-aleth.json, genesis-harmony.json, genesis-parity.json
>INFO [09-29|14:47:47.760] Saved native genesis chain spec path=genesis.json
ERROR[09-29|14:47:47.760] Failed to create Aleth chain spec err="unsupported consensus engine"
ERROR[09-29|14:47:47.761] Failed to create Parity chain spec err="unsupported consensus engine"
INFO [09-29|14:47:47.762] Saved genesis chain spec client=harmony path=genesis-harmony.json
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 // ctrl+C to quit puppeth

Good job!!!!! Few things to keep in mind. POA has no mining rewards but there is a catch to it. whenever transaction is mined the gas used to mine the transaction is sent to the singer as a reward so ether will always flow back to start.

Now you have genesis file and accounts so you can initialize the nodes.

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


Next, now we have two accounts and we are good to go but when we need to set up a bootnode to help nodes discover for other peers since its gonna be peer to peer network shortly.

bootnode -genkey boot.key
bootnode -nodekey boot.key -verbosity 9 -addr :30310

now we have the bootnode key. to start the bootnode service first we need to understand that we are using the ubuntu command line to interact with the server. so there gona be cases when you want to check the logs in real-time so here I use a pre-installed program called screen.

to test screen program write this command in cmd. ls is to basically check the existing screens. keep in mind that if you restart will kill all the screens running in the background. will cover that in-depth in another tutorial. for now, will use screens program

screen -ls No Sockets found in /run/screen/S-ubuntu.

now will start screen and assign name to it

screen -S bootnode

Hit enter… once you will hit enter, it will take you to clean new same console

now will start bootnode service

bootnode -nodekey boot.key -verbosity 9 -addr :30310output >>
Note: you're using cmd/bootnode, a developer tool.We recommend using a regular node as bootstrap node for production deployments.INFO [09-29|15:00:36.497] New local node record seq=1 id=91ee0f8f428623a3 ip=<nil> udp=0 tcp=0

copy paste that full enode to notepad and most important to remove “0?discport=” from the enode, then to minimize screen again use

ctrl+A+D //to minimize screenscreen -ls // to check all screen 
There is a screen on:
2556.bootnode (09/29/19 15:00:32) (Detached)
1 Socket in /run/screen/S-ubuntu.

if you want to again maximize that screen then use -r flag

screen -r 2556 // -r to resume and screennumber in this case 2556.bootnode

now to minimize again use ctrl+A+D

To start node 1 -

again will create screen to make it more accessible

>> screen -S node1>> geth --datadir node1/ --syncmode 'full' --port 30311 --rpc --rpcaddr '' --rpcport 8501 --rpcapi 'personal,db,eth,net,web3,txpool,miner'   --ws  --wsaddr ''  --wsport 8601  --wsapi 'personal,db,eth,net,web3,txpool,miner'  --wsorigins * --rpccorsdomain * --bootnodes 'enode://613ebdf4fd061cdd6eec54c596f7748e3866c4ce2109ef02812cf57b0e18b2e3b0ba95e5d1bc7b4a1781b347bce85cd318523c65459092871cfd6ab569c3e02a@' --networkid 48333442 --gasprice '1'

it will start the node and to minimize again use ctrl+A+D //to minimize screen

To start node 2 -

again will create screen to make it more accessible

>> screen -S node2>> geth --datadir node2/ --syncmode 'full' --port 30311 --rpc --rpcaddr '' --rpcport 8502 --rpcapi 'personal,db,eth,net,web3,txpool,miner'   --ws  --wsaddr ''  --wsport 8602  --wsapi 'personal,db,eth,net,web3,txpool,miner'  --wsorigins * --rpccorsdomain * --bootnodes 'enode://613ebdf4fd061cdd6eec54c596f7748e3866c4ce2109ef02812cf57b0e18b2e3b0ba95e5d1bc7b4a1781b347bce85cd318523c65459092871cfd6ab569c3e02a@' --networkid 48333442 --gasprice '1'

it will start node 2. 🥰

now we have to manually connect to each node geth console and start mining in order to mine transactions.

>> personal.unlockAccount(eth.coinbase,”passme”,0)>> miner.start()>>eth.sendTransaction({from:eth.coinbase,value:3045345435435,to:’0x3592eb9861E427C4b9d7894E910690d58d7b340F’})

Good work!!!!

So far we have successfully set up a private POA network.

In next part will cover Url wrapper & SSL support. Stay tuned!

smash like button and share!!!!