The enterprise blockchain market is huge, and there are different solutions available to implement blockchain for enterprise -- Hyperledger, Corda, and Ethereum are the well-known providers. You can set up enterprise blockchain in different ways, on a cloud, or on-premise. Here in this post, we'll learn how you can setup a private ethereum blockchain on your server.
OS and Software
- OS: Ubutu 16.04 server
- Software: Geth Version: 1.9.18-stable
Validator nodes
We will use proof of authority (PoA) consensus to setup the private network. In PoA-based networks, transactions and blocks are validated by approved accounts, known as validators or sealer. The process is automated and does not require validators to be constantly monitoring their computers.
PoA algorithms rely on a set of N trusted nodes called the authorities. We'll create three sealer nodes to validate the transactions.
Types of Nodes in PoA NetworkValidator/Authority - Validate, confirm transactions, and add new blocks into blockchain.
- Full Node - This node keeps a copy of the full blockchain.
Here is the structure we'll build in this tutorial. A full template can be found from the attachment of this article.
blockchain
├── accounts.txt
├── genesis.json
├── node1
│ ├── geth
│ ├── keystore
│ ├── node1.sh
│ ├── password.txt
│ └── static-nodes.json
├── node2
│ ├── geth
│ ├── keystore
│ ├── node2.sh
│ ├── password.txt
│ └── static-nodes.json
└── node3
├── geth
├── keystore
├── node3.sh
├── password.txt
└── static-nodes.json
Create a main directory
$ mkdir blockchain
$ cd blockchain
blockchain$ mkdir node1 node2 node3Create validator accounts
The account required public-private keys to interact with the blockchain. Hence we need to create new accounts for validators.
Node 1
blockchain$ geth --datadir node1/ account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Password:
Repeat password:
Your new key was generated
Public address of the key: 0x5D9DD2d7ea19D886F6D69c7E14e4F4Eeb922F8d4
Path of the secret key file: node1/keystore/UTC--2020-07-29T15-48-00.687512615Z--5d9dd2d7ea19d886f6d69c7e14e4f4eeb922f8d4Node 2
blockchain$ geth --datadir node2/ account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Password:
Repeat password:
Your new key was generated
Public address of the key: 0x80051706C32359A75389EA36dDEbA2159067C360
Path of the secret key file: node2/keystore/UTC--2020-07-29T15-54-17.548848773Z--80051706c32359a75389ea36ddeba2159067c360Node 3
blockchain$ geth --datadir node3/ account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Password:
Repeat password:
Your new key was generated
Public address of the key: 0xf189Ee2c9b61487Fe26C72b8a0ba52f453E71c25
Path of the secret key file: node3/keystore/UTC--2020-07-29T15-56-15.523088698Z--f189ee2c9b61487fe26c72b8a0ba52f453e71c25Note that keystore files automatically generated inside node folders, and keystore files can be found inside the keystore directory.
Save Credentials
For future use, we'll copy these three wallet address to a text file.
blockchain$ echo '0x5D9DD2d7ea19D886F6D69c7E14e4F4Eeb922F8d4' >> accounts.txt
blockchain$ echo '0x80051706C32359A75389EA36dDEbA2159067C360' >> accounts.txt
blockchain$ echo '0xf189Ee2c9b61487Fe26C72b8a0ba52f453E71c25' >> accounts.txtTo make the process easier, save the password of each node to the respective folder.
blockchain$ echo 'pwd@node1' > node1/password.txt
blockchain$ echo 'pwd@node2' > node2/password.txt
blockchain$ echo 'pwd@node3' > node2/password.txtCreate your Genesis file
Geth comes with different tools included; if you're using tar file, you need to install it separately. Puppeth is a tool to create a new genesis file by selecting different options.
blockchain$ puppethSpecify the chain id
Please specify a network name to administer (no spaces, hyphens or capital letters please)
> 1515As we want to generate a new genesis file, choose the first option.
What would you like to do? (default = create)
1. Create new genesis from scratch
2. Import already existing genesis
> 1Select proof-of-authority.
Which consensus engine to use? (default = clique)
1. Ethash - proof-of-work
2. Clique - proof-of-authority
> 2For the fast transaction, hence provide 1 second.
How many seconds should blocks take? (default = 15)
> 1Provide accounts created previously
Which accounts are allowed to seal? (mandatory at least one)
> 0x5D9DD2d7ea19D886F6D69c7E14e4F4Eeb922F8d4
> 0x80051706C32359A75389EA36dDEbA2159067C360
> 0xf189Ee2c9b61487Fe26C72b8a0ba52f453E71c25
> 0xProvide accounts to get some free ethers
Which accounts should be pre-funded? (advisable at least one)
> 0x5D9DD2d7ea19D886F6D69c7E14e4F4Eeb922F8d4
> 0x80051706C32359A75389EA36dDEbA2159067C360
> 0xf189Ee2c9b61487Fe26C72b8a0ba52f453E71c25
> 0xShould the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei? (advisable yes)
> yesSpecify your chain/network ID if you want an explicit one (default = random)
> 1515
Configured new genesis blockThe genesis block is configured, now we need to export the configuration into a file.
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
> 21. Modify existing configurations
2. Export genesis configurations
3. Remove genesis configuration
> 2Which folder to save the genesis specs into? (default = current)
Will create 1515.json, 1515-aleth.json, 1515-harmony.json, 1515-parity.json
> // enter to create in existing folder
INFO [07-29|16:33:29.147] Saved native genesis chain spec path=1515.json
ERROR[07-29|16:33:29.147] Failed to create Aleth chain spec err="unsupported consensus engine"
ERROR[07-29|16:33:29.147] Failed to create Parity chain spec err="unsupported consensus engine"
INFO [07-29|16:33:29.149] Saved genesis chain spec client=harmony path=1515-harmony.jsonWhat 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 puppethYou should see the 1515.json created inside blockchain folder, rename it to genesis.json and delete the generated file that ends in -harmony.json.
Modify the Genesis file
Set block sealing period to 0, this will automatically force geth to only create a new block whenever there is a transaction in the network.
"clique": {
"period": 0,
"epoch": 30000
}Initialize the Nodes
Each node must initialize with the same genesis file.
blockchain$ geth --datadir node1/ init genesis.json
blockchain$ geth --datadir node2/ init genesis.json
blockchain$ geth --datadir node3/ init genesis.jsonRun the Nodes
We'll run node using geth with different available options. For reusable purposes, you can create a shell script. Put all the options you want to enable in one huge command.
Go inside the node1 directory and run the command.
blockchain/node1$geth --nousb --datadir=$pwd --syncmode 'full' --port 30310 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 8545 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x5D9DD2d7ea19D886F6D69c7E14e4F4Eeb922F8d4" --password password.txt- --nousb Disables monitoring for and managing USB hardware wallets.
- --datadir=$pwd Data directory for the databases and keystore.
- --syncmode 'full' Enables full chain sync (default: "fast").
- --port 3030 assign port geth process.
- --miner.gasprice 0 On private network we don't want to pay anything, so make it zero.
- --miner.gastarget 470000000000 use same as the genesis file. However, actual gaslimit is dynamic for new block and depends on the previous block.
- --http Enable the HTTP-RPC server.
- --http.addr 'localhost' HTTP-RPC server listening interface (default: "localhost").
- --http.port 8545 HTTP-RPC server listening port (default: 8545).
- --http.api Buch of apis to be used over RPC calls.
- --mine Enable mining.
- --allow-insecure-unlock Allow insecure account unlocking when account-related RPCs are exposed by http.
- --unlock "0x251B7dC42D7472314fE4d6c3b9CAD2fb5927d7c8" Account to unlock, we'll use the address of node1.
- --password password.txt Password file to use for non-interactive password input
Additional Parameters
- --rpccorsdomain "*" Comma separated list of domains from which to accept cross origin requests (browser enforced).
- --rpcvhosts="*" Comma separated list of virtual hostnames from which to accept requests (server enforced). Accepts '*' wildcard.
- --miner.threads value Number of CPU threads to use for mining (default: 0).
When you run the node, you will find the enode in the log, copy that enode and keep it with you.
Node 1
enode://e832f6b25b2025ecb8a192439255557944a5e1c12175f72a7f1b79de811b94f3f11f930d9dcbf0389429ecba579856185f231930fbaf86a09d1b8c8071555f8e@127.0.0.1:30310Node 2
blockchain/node2$geth --nousb --datadir=$pwd --syncmode 'full' --port 30311 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 8546 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x80051706C32359A75389EA36dDEbA2159067C360" --password password.txtEnode for node2
enode://0142f6ce892526b3c3a99fa986e5f58770ddddec88a8a0752542469006cac9dcd364386f8ce31ac2fe3fb58e5583108df21df4dd20497ab2a25b7056a60ae964@127.0.0.1:30311Node 3
blockchain/node3$geth --nousb --datadir=$pwd --syncmode 'full' --port 30312 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 8547 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0xf189Ee2c9b61487Fe26C72b8a0ba52f453E71c25" --password password.txtEnode for node3
enode://6948ac526196e3b0e71bf6718a83924d5471aaae1e763a66a0a615eb92b3ee62c1fbb896553e1187f1012cb11b0d154d431c77d3fe2489c6452b47cb113c98ce@127.0.0.1:30312Now you have all three enodes, we'll use this to connect all the nodes.
Prepare static-nodes.json file
Geth has a different feature to connect to the network, we'll use static nodes. It generally used when you know the peers and we always want to connect with them.\
Crate static-nodes.json in node1 and add values of enodes as follows,
blockchain/node1$touch static-nodes.jsonAdd all three enodes into it.
[
"enode://e832f6b25b2025ecb8a192439255557944a5e1c12175f72a7f1b79de811b94f3f11f930d9dcbf0389429ecba579856185f231930fbaf86a09d1b8c8071555f8e@127.0.0.1:30310",
"enode://0142f6ce892526b3c3a99fa986e5f58770ddddec88a8a0752542469006cac9dcd364386f8ce31ac2fe3fb58e5583108df21df4dd20497ab2a25b7056a60ae964@127.0.0.1:30311",
"enode://6948ac526196e3b0e71bf6718a83924d5471aaae1e763a66a0a615eb92b3ee62c1fbb896553e1187f1012cb11b0d154d431c77d3fe2489c6452b47cb113c98ce@127.0.0.1:30312"
]Copy that json file to other nodes.
blockchain/node1$cp static-nodes.json /home/dmdesai/blockchain/node2/
blockchain/node1$cp static-nodes.json /home/dmdesai/blockchain/node3/Start all the nodes
To make the process simpler, create a shall script file and paste a huge command into it.
blockchain/node1$touch node1.shnohup geth --nousb --datadir=$pwd --syncmode 'full' --port 30310 --miner.gasprice 0 --miner.gastarget 470000000000 --http --http.addr 'localhost' --http.port 8545 --http.api admin,eth,miner,net,txpool,personal,web3 --mine --allow-insecure-unlock --unlock "0x5D9DD2d7ea19D886F6D69c7E14e4F4Eeb922F8d4" --password password.txt &
echo "Geth started on node 1"Repeat this process for node2 and node3, then run the script file for each.
blockchain/node1$sh node1.sh
blockchain/node2$sh node2.sh
blockchain/node3$sh node3.shAttach Geth with the following command
blockchain/node1$ geth attach geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.9.18-stable-f5382591/linux-amd64/go1.14.2
coinbase: 0x5d9dd2d7ea19d886f6d69c7e14e4f4eeb922f8d4
at block: 0 (Wed Jul 29 2020 16:30:59 GMT+0000 (UTC))
datadir: /home/rsa-key-20200717/blockchain/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
>Check if the other two nodes are connected or not. It should show the peer count 2.
> net.peerCount
2Your private blockchain is ready! You can make a transaction on one node, and it will be synced with the connected peers.
Stop the nodes
$ ps ax | grep geth
$ kill <process id>
$ kill -9 <process id> //kill the process forcefullyWhat’s next ?
We will see how you can connect nodes of different servers, so even if one server is down, the second one can process transactions.
Reference
- https://github.com/ethereum/go-ethereum/wiki/Command-Line-Options

Rajendra CherukuriPosted Jun 5, 2021, 8:33 AM
Please confirm this is only node setup but not full node. Will the nodes connect using static-nodes entries? I tried above with couple of systems but the peers are not determined. I used host IP instead of localhost and opened ports still unable to locate peers. Any idea? I'm using latest geth and using generated network.json as genesis file