Blockchain for Beginners: Build Your Own Private Ethereum Network with Geth (Step by step)

Ferdy Hahan Pradana
6 min readApr 27, 2024

--

Description

Are you ready to move beyond development tools? After I shared how to deploy smart contracts using ganache and remix, this time, we’ll build a private Ethereum network with Geth! This handy guide will get you started, perfect for beginners who want to experiment with blockchain technology.

Information of the device used

In this article, I am using Ubuntu 22.04.3 LTS for my OS, if you are using another linux distro, or using windows or mac, I think there is no problem but you have to adjust for installation prerequisites

Prerequisites

  • Go Language (in this article, I am using go version 1.22.0)
  • Go Ethereum (in this article, I am using geth version 1.13.14-stable)
  • VSCode (this is optional, you can use your favorite code editor)

The steps are as follows:

Make project folder

in the first step, we will create a project folder that will be used to create a blockchain network

mkdir geth-tutorial

Navigate to your project folder using the command line.

cd geth-tutorial

Creating nodes

In this step, we’ll set up separate folders for each node in our blockchain network. Let’s create folders named “node1” and “node2” to represent our network nodes.

mkdir node1 node2

Managing Node Information

after each node1 and node2 folder is created, we will create an info.txt file in the root of our project folder to store information such as account addresses and passwords for node1 and node2. This will help us keep track of important details related to our nodes.

touch info.txt

Open Code Editor (optional, for easy viewing)

In this step, iam using VS Code

code .

Creating Accounts for Node1 and Node2

Next we will create accounts for node1 and node2. We will open a separate terminal for each node folder and run the command as below

geth --datadir "./data" account new

Verifying Account Creation

To ensure that the accounts for node1 and node2 have been successfully created, we will check the keystore folder inside each node’s data directory.

  1. Open the keystore folder in the data directory of node1 and node2.
  2. Verify that new account files are present within each keystore folder.

By confirming the presence of account files, we can ensure that the accounts for node1 and node2 have been successfully created.

Saving Account Information

for the accounts created earlier, we’ll save the public addresses and passwords for the accounts created for node1 and node2 to the info.txt file.

  1. Open the info.txt file located at the root of the project folder.
  2. Add the public address and password for each account created for node1 and node2.

Creating Configuration File

In this step, the account has been created, next we will create a file called “privateblock.json” for configuration in the root directory of the project. Then, we will copy and paste the script provided below into the “privateblock.json” file.

  1. Create a file named “privateblock.json” in the root directory of your project.
  2. Copy and paste the following script into “privateblock.json”:
{
"config": {
"chainId": 1234567,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"clique": {
"period": 5,
"epoch": 30000
}
},
"difficulty": "1",
"gasLimit": "8000000",
"extradata": "0x0000000000000000000000000000000000000000000000000000000000000000{ INITIAL_SIGNER_ADDRESS }0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"alloc": {
"{ FIRST_NODE_ADDRESS }": {
"balance": "3000000000000000000000000000000000000"
},
"{ SECOND_NODE_ADDRESS }": {
"balance": "3000000000000000000000000000000000000"
}
}
}

3. Replace “{ FIRST_NODE_ADDRESS }” to the public address for each node account and change “{ INITIAL_SIGNER_ADDRESS }” to one of the node’s public addresses (remove the leading “0x” character).
for example, these are my accounts for each node

and, this is my script in privateblock.json

{
"config": {
"chainId": 1234567,
"homesteadBlock": 0,
"eip150Block": 0,
"eip155Block": 0,
"eip158Block": 0,
"byzantiumBlock": 0,
"constantinopleBlock": 0,
"petersburgBlock": 0,
"istanbulBlock": 0,
"berlinBlock": 0,
"clique": {
"period": 5,
"epoch": 30000
}
},
"difficulty": "1",
"gasLimit": "8000000",
"extradata": "0x0000000000000000000000000000000000000000000000000000000000000000A43ffF7C765A30f797C7F0108291958faA30Fa170000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"alloc": {
"A43ffF7C765A30f797C7F0108291958faA30Fa17": {
"balance": "3000000000000000000000000000000000000"
},
"5b5cD226194D0EDe2652102D52Fc0A9ed0F38C0D": {
"balance": "3000000000000000000000000000000000000"
}
}
}

Initializing Nodes

Account and configuration have been created, it’s time we initialize each node with the configuration that has been created using the following command:

geth --datadir ./data init ../privateblock.json

Setting Up Bootnode

In this step, we’ll create a folder named “bnode” in the root of our project directory to set up the bootnode. The bootnode acts as a central hub for node discovery in the Ethereum network. It generates unique enode URLs and facilitates the connection of new nodes, enabling network synchronization and decentralized communication.

Create a folder named “bnode” in the root directory of your project.

mkdir bnode
cd bnode

Generating Bootnode Key and Running Bootnode

Next we’ll generate the bootnode key and run the bootnode.

  1. Generate the bootnode key in the “bnode” folder:\
bootnode -genkey boot.key

2. After generating the key, run the bootnode with the following command:

bootnode -nodekey boot.key -verbosity 7 -addr "127.0.0.1:30301"

Storing Bootnode Enode

To make things easier, we will store the enode information for the bootnode in the “info.txt” file in the root project folder.

  1. Open the “info.txt” file located at the root of the project directory.
  2. Add the enode information for the bootnode:

Storing Passwords

Coming to one step before we run each of the nodes, we will create a file called “password.txt” inside the node1 and node2 folders and enter the password for each node in the respective file.

Starting Signer Account (Node1)

Okay, now we will run the script to start a signer account using node1. We will customize the script with appropriate parameters such as enode, network ID (chainId), signer node address, password, and signer address.

geth --datadir "./data"  --port 30304 --bootnodes enode://{ YOUR_VALUE } --authrpc.port 8547 --ipcdisable --allow-insecure-unlock  --http --http.corsdomain="https://remix.ethereum.org" --http.api web3,eth,debug,personal,net --networkid { NETWORK_ID } --unlock { ADDRESS_NODE1 } --password { PASSWORD_FILE_NAME_EXTENSION }  --mine --miner.etherbase= { SIGNER_ADDRESS }

For example, This is my script

geth - datadir "./data" - port 30304 - bootnodes enode://7c8ae5080a4e655b82868853abf24164dc62a13f16118ae0e9a6d6446fa5013e7e7809912474057836628804837380549d680b29f26b350c1350dad385e2b538@127.0.0.1:0?discport=30301 - authrpc.port 8547 - ipcdisable - allow-insecure-unlock - http - http.corsdomain="https://remix.ethereum.org" - http.api web3,eth,debug,personal,net - networkid 1234567 - unlock 0xA43ffF7C765A30f797C7F0108291958faA30Fa17 - password password.txt - mine - miner.etherbase=0xA43ffF7C765A30f797C7F0108291958faA30Fa17

Notes:

for set cors allow for “http://127.0.0.1:8000”, add “http://127.0.0.1:8000” to “ — http.corsdomain”

example:

geth --datadir "./data"  --port 30304 --bootnodes enode://7c8ae5080a4e655b82868853abf24164dc62a13f16118ae0e9a6d6446fa5013e7e7809912474057836628804837380549d680b29f26b350c1350dad385e2b538@127.0.0.1:0?discport=30301 --authrpc.port 8547 --ipcdisable --allow-insecure-unlock  --http --http.corsdomain="https://remix.ethereum.org, http://127.0.0.1:8000" --http.api web3,eth,debug,personal,net --networkid 1234567 --unlock 0xA43ffF7C765A30f797C7F0108291958faA30Fa17 --password password.txt  --mine --miner.etherbase=0xA43ffF7C765A30f797C7F0108291958faA30Fa17

Running Other Nodes

Then, how to run nodes other than the signer node? we can run nodes other than the signer node (node1) using script command below

geth --datadir "./data"  --port 30306 --bootnodes enode://{ YOUR_VALUE }  -authrpc.port 8546 --networkid { NETWORK_ID } --unlock { ADDRESS_NODE2 } --password { PASSWORD_FILE_WITH_EXTENSION }

and this example of my script for running node2

geth --datadir "./data"  --port 30306 --bootnodes enode://7c8ae5080a4e655b82868853abf24164dc62a13f16118ae0e9a6d6446fa5013e7e7809912474057836628804837380549d680b29f26b350c1350dad385e2b538@127.0.0.1:0?discport=30301  -authrpc.port 8546 --networkid 1234567 --unlock 0x5b5cD226194D0EDe2652102D52Fc0A9ed0F38C0D --password password.txt

Deploying Smart Contract

Blockchain network has been created, to check deploy smart contract, try to deploy in REMIX IDE with provider “custom — external http provider” with host and port http://127.0.0.1:8545

--

--

Ferdy Hahan Pradana
Ferdy Hahan Pradana

Written by Ferdy Hahan Pradana

Tech explorer | Always learning & experimenting with new tech | Sharing knowledge & experiences