Introduction to Private Blockchains
At its core, a blockchain is a specialized type of distributed, non-relational database. It is designed specifically for inserting and querying data, operating without a central administrator.
Its primary function is to store information. You can write any data that needs to be preserved into the blockchain and read it back out, making it a database. Furthermore, anyone can set up a server to join the blockchain network as a node. In the blockchain world, there is no central node; every node is equal and holds a complete copy of the entire database. You can write to or read from any node, as all nodes will eventually synchronize to ensure consensus across the blockchain.
Software Installation and Configuration
Installing on Ubuntu
To install the necessary Ethereum software on Ubuntu, execute the following commands in your terminal:
sudo apt upgrade -y
sudo apt install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo apt update
sudo apt install ethereumVerify your installation by checking the Geth version:
geth versionTo install the Solidity compiler (solc), use:
sudo apt install solc -yInstalling on CentOS 7
For CentOS 7 systems, the installation process involves these steps:
yum update -y
yum install git wget bzip2 -y
yum install golang -y
cd /usr/local/src
git clone https://github.com/ethereum/go-ethereum.git
cd go-ethereum/
gmake all
mv build /srv/go-ethereum
echo "export PATH=$PATH:$PWD/build/bin" >> /etc/profile
source /etc/profileFor production environments, it is recommended to use a stable release version from the project's tags page rather than the latest unstable build from the repository.
Installing on Windows
Visit the official Geth download page, https://geth.ethereum.org/downloads/, to download and install Geth for Windows.
Installing on macOS
Using Homebrew, you can install the Ethereum packages on macOS:
brew update
brew upgrade
brew tap ethereum/ethereum
brew install ethereum
brew install solidityEthereum Wallet (Mist)
The Ethereum Wallet, previously known as Mist, can be downloaded from its GitHub releases page. Note that users in certain regions might experience slow download speeds or require a VPN to access the download.
Configuring the Genesis Block
The genesis block is the first block in any blockchain. To initialize a private chain, you must create and configure a genesis.json file.
Navigate to your working directory and create the file:
cd ~
mkdir -p ethereum
cd ethereumA basic genesis.json structure looks like this:
{
  "nonce": "0x0000000000000042",
  "difficulty": "0x020000",
  "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x0000000000000000000000000000000000000000",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
  "gasLimit": "0x4c4b40",
  "config": {
    "chainId": 15,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": { }
}Key parameters explained:
- mixhash & nonce: Used together for mining. Their values must meet specific conditions outlined in the Ethereum Yellow Paper.
 - difficulty: Sets the mining difficulty for the chain. A lower value makes CPU mining feasible on a private chain.
 - alloc: Pre-funds specific accounts with Ether at the genesis block. Often left empty for private chains where mining is easy.
 - gasLimit: Sets the total gas consumption limit per block, restricting the total transactions. Set to the maximum for private chains.
 
Initialize the genesis block with Geth:
geth init genesis.jsonBy default, data is stored in ~/.ethereum/. Use the --datadir flag to specify a custom data directory.
Starting Your Node
Launch your private Ethereum node with the following command:
geth --networkid 123456 --rpc --rpccorsdomain "*" --nodiscover consoleCommon flags explained:
--networkid: Sets a unique identifier for your private network.--rpc: Enables the HTTP-RPC server.--rpccorsdomain: Specifies which domains can access the RPC interface ("*"allows all).--nodiscover: Prevents your node from being discovered by the public Ethereum network.console: Opens the JavaScript console upon startup.
By default, the RPC server binds to 127.0.0.1. To allow external connections, use --rpcaddr="0.0.0.0".
Mining on Your Private Chain
Mining is the process of creating new blocks and securing the network. To start mining on your private chain, use the JavaScript console:
miner.start(1)The number 1 specifies the number of CPU threads to use for mining. The first time you run this, it will generate the DAG file needed for mining, which can take some time. Once complete, mining will begin. Due to the low difficulty set in the genesis block, blocks will be mined very quickly on a private chain.
To stop mining, execute:
miner.stop()You can check the balance of your miner's account (the first account created, by default) with:
eth.getBalance(eth.accounts[0])The returned value is in Wei. Use web3.fromWei() to convert it to Ether.
Essential Geth Commands and Console Usage
Account Management
List existing accounts:
geth account listCreate a new account:
geth account newYou will be prompted to set a password for the new account. The account keystore files are typically located in ~/.ethereum/keystore/ (Linux), ~/Library/Ethereum/keystore/ (macOS), or %APPDATA%/Ethereum/keystore/ (Windows).
Interacting with the JavaScript Console
You can attach a console to a running Geth instance:
geth attachThis connects to the default IPC endpoint. To connect to a specific data directory's IPC file or a remote node via RPC, use:
geth attach /path/to/geth.ipc
geth attach http://<node-ip>:8545Common console commands include:
personal.listAccounts: List all accounts.eth.coinbase: Check the current miner account.eth.blockNumber: Get the latest block number.miner.start()/miner.stop(): Control mining.admin.nodeInfo: Display information about the current node.admin.addPeer(enode_url): Manually add a peer to connect nodes.admin.peers: List connected peers.
Sending Transactions
To send a transaction between accounts on your private chain:
Unlock the sender account (replace with your actual password):
personal.unlockAccount(eth.accounts[0], "your_password", 300)Send the transaction (value is in Wei;
web3.toWei()is useful for conversion):eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(1, "ether")})- For the transaction to be confirmed and written to the blockchain, a block must be mined. If mining is not already running, start it (
miner.start(1)). After a block is mined, check the recipient's balance to confirm the transfer. 
Running Multiple Local Nodes
You can simulate a multi-node network on a single machine by running multiple Geth instances with different data directories and ports.
Create separate data directories:
mkdir -p ~/ethereum/data1 ~/ethereum/data2Initialize both directories with the same
genesis.jsonfile:geth --datadir ~/ethereum/data1 init genesis.json geth --datadir ~/ethereum/data2 init genesis.jsonStart each node with a unique port and RPC port:
# Terminal 1 - Node 1 geth --datadir ~/ethereum/data1 --networkid 123456 --port 30301 --rpc --rpcaddr "0.0.0.0" --rpcport 8541 --rpccorsdomain "*" # Terminal 2 - Node 2 geth --datadir ~/ethereum/data2 --networkid 123456 --port 30302 --rpc --rpcaddr "0.0.0.0" --rpcport 8542 --rpccorsdomain "*"- Find the 
enodeURL of the first node by attaching a console to it (geth attach ~/ethereum/data1/geth.ipc) and runningadmin.nodeInfo.enode. Replace the[::]IP section with your machine's actual IP (e.g.,127.0.0.1). From a console attached to the second node, add the first node as a peer:
admin.addPeer("enode://[email protected]:30301")- Verify the connection with 
admin.peers. You can now create accounts and send transactions between these connected nodes. 
👉 Explore advanced configuration strategies
Frequently Asked Questions
What is the main purpose of a private Ethereum chain?
A private Ethereum chain is used for development, testing, and private business networks. It allows you to experiment with smart contracts and blockchain applications without spending real Ether or exposing your data to the public mainnet. You have full control over the network, including mining difficulty and consensus rules.
Why are my transactions stuck as 'pending'?
Transactions remain pending until they are included in a mined block. If your transaction is stuck, it's likely because no blocks are being mined. Ensure a miner is running (miner.start(1)) to process transactions and add them to the blockchain. The txpool.status command can show pending transactions.
How do I resolve the 'authentication needed: password or unlock' error?
This error occurs when you try to send a transaction from an account that is currently locked. You must unlock the account first using the personal.unlockAccount(accountAddress, password, duration_in_sec) command in the console before initiating the transaction. The duration specifies how long the account remains unlocked.
Why can't my nodes discover each other?
If you used the --nodiscover flag, automatic peer discovery is disabled. You must manually add peers using admin.addPeer(). Ensure the nodes have the same networkid, that the ports are open and accessible, and that the enode URL uses the correct IP address (not [::]).
Where are my account files stored?
Account keystore files, which contain encrypted private keys, are stored in the keystore directory within your Geth data directory (e.g., ~/.ethereum/keystore/ on Linux). Always back up this directory securely.
What is the difference between Wei and Ether?
Wei is the smallest denomination of Ether, similar to cents to a dollar. There are 1 quintillion (10^18) Wei in one Ether. Geth often returns balances in Wei. Use web3.fromWei(balance, 'ether') to convert to a more readable Ether value. Common units include Gwei (10^9 Wei), which is often used for gas prices.