DEV Community

Cover image for Set up a private network with multiple PCs using Go Ethereum (Geth)
Yongchang He
Yongchang He

Posted on • Edited on

Set up a private network with multiple PCs using Go Ethereum (Geth)

This blog explains how to set up a private blockchain network with multiple nodes running on different computers.

This tutorial is meant for those with some knowledge of Ethereum and smart contracts, who have some knowledge of nodes, geth and POA, etc.
The purpose of building this blog is to write down the detailed operation history and my memo for learning the dApps.
If you are also interested and want to get hands dirty, just follow these steps below and have fun!~

Prerequisites

  • Two PCs (I used macOS and Linux)
  • Geth and Node.js installed
  • MetaMask (optional)

NOTE: In the following Command Line Interface (CLI) We mark the two CLIs running on different computers as pc1$ and pc2$.
Do not copy the prefix pc1$ and pc2$.

Getting started

Check IP address

We use this CLI command to know the IP address of macOS device pc1:

pc1$ ifconfig|grep netmask|awk '{print $2}'
Enter fullscreen mode Exit fullscreen mode

Output:
127.0.0.1
1X.1XX.2XX.35

Use the second one not 127.0.0.1.

Generate a new Geth account

pc1$ geth account new
Enter fullscreen mode Exit fullscreen mode

Output:
E.g. :
Your new key was generated
Public address of the key:
0xXa79b38262Xf270d5A3141X4F326X76A9F37e9E4
Path of the secret key file:
......

NOTE: The path of the secret key file is import because you will find the private key of your account in that directory. It will be used when you want to import Geth account to MetaMask.

Initializing the Geth Database

Copy and paste the following code and name it genesis.json.

{
    "config": {
      "chainId": 15,
      "homesteadBlock": 0,
      "eip150Block": 0,
      "eip155Block": 0,
      "eip158Block": 0,
      "byzantiumBlock": 0,
      "constantinopleBlock": 0,
      "petersburgBlock": 0,
      "ethash": {}
    },
    "difficulty": "1",
    "gasLimit": "8000000",
    "alloc": {}
  }
Enter fullscreen mode Exit fullscreen mode

This is the code for creating the genesis block.
To create a blockchain node using this, we navigate to the directory that created this file, and run the following command:

This imports and sets the canonical genesis block for your chain.

pc1$ geth init --datadir . genesis.json
Enter fullscreen mode Exit fullscreen mode

Image description

Setting up networking

Once the node is initialized to the desired genesis state, it is time to set up the peer-to-peer network.

Any node can be used as an entry point. I recommend dedicating a single node as the rendezvous point which all other nodes use to join. This node is called the ‘bootstrap node’.

pc1$ geth --datadir . --keystore ~/Library/ethereum/keystore --unlock 0 --nodiscover -http --http.api 'personal,eth,net,web3,txpool,miner' --http.corsdomain "*" --networkid 15 --nat extip:IP_ADDRESS --mine --miner.etherbase="GETH_ACCOUNT_ADDRESS" 
Enter fullscreen mode Exit fullscreen mode

Replace the keystore route, GETH_ACCOUNT_ADDRESS and the IP_ADDRESS with yours.

Now use another CLI to extract the ‘node record’ of the boot-node using the JS console.

pc1$ geth attach geth.ipc --exec admin.nodeInfo.enr
Enter fullscreen mode Exit fullscreen mode

This command should print a base64 string such as the following example. Other nodes will use the information contained in the bootstrap node record to connect to your peer-to-peer network.

Image description

Running member nodes on another machine

Before running a member node on Linux Ubuntu, we have to first initialize it with the same genesis file as used for the bootstrap node.

Navigate to the directory /genesis.json first.

pc2$ geth init --datadir . genesis.json
Enter fullscreen mode Exit fullscreen mode

Image description

Then we connect the second node to the bootstrap node:
Option 1:

pc2$ geth --datadir . --networkid 15 --port 30304 --bootnodes "enr:-YOUR_ENR_STRING"
Enter fullscreen mode Exit fullscreen mode

In this option:
Node 2 will not be a miner.
Use your own enr string.

Option 2:
(Recommended) Alternatively use this one to connect the second node to the bootstrap node:

pc2$ geth account new
pc2$ geth --datadir . --keystore /home/yongchang/.ethereum/keystore --allow-insecure-unlock --http --http.api 'personal,eth,net,web3,txpool,miner' --http.corsdomain "*" --networkid 15 --port 30304 --mine --miner.etherbase="YOUR_ACCOUNT_ADDRESS" --bootnodes "BOOTNODE ENR"
Enter fullscreen mode Exit fullscreen mode

Node 2 will be a miner using this command
Use your own keystore route, account address and enr string.

Check the connection status.

Open a new CLI and input the following:

pc2$ geth attach geth.ipc
Enter fullscreen mode Exit fullscreen mode

Image description

Find peers:

> admin.peers
Enter fullscreen mode Exit fullscreen mode

Show peer numbers:

> net.peerCount
Enter fullscreen mode Exit fullscreen mode

Image description

Mining Ethereum blocks

To begin mining our blockchain, we can run:

> miner.start()
Enter fullscreen mode Exit fullscreen mode

Let's allow it to run for a while, and then stop the mining by typing:

> miner.stop()
Enter fullscreen mode Exit fullscreen mode

Now We have rewarded some tokens for mining new blocks. We can verify this by running the following command:

> eth.getBalance(eth.accounts[0])
Enter fullscreen mode Exit fullscreen mode

Image description

Sending Tokens

Option 1:

> eth.sendTransaction({from: ACCOUNT_pc1_STRING, to: ACCOUNT_pc2_STRING, value: 5000})
Enter fullscreen mode Exit fullscreen mode

Value here is in Wei (Where 1 ETH equals 1 x 10 ^ 18 Wei)

We should get a green transaction hash if the transaction has been done correctly (should mining for a while).
Image description

Option 2:
We can use MetaMask to transfer ETH from account_pc1 to account_pc2 and vice versa. Should be faster and simpler.

ENJOY!

References

https://geth.ethereum.org/
https://spectrum.ieee.org/blockchain-interoperability

Top comments (1)

Collapse
 
trimarchi profile image
Matteo

Hi, i’m usign raspberry pi 4 as nodes.
Does each node have to be connected with the enode of the first node started? Or does each new node want the enode of the previous node?