Build Your Own Ethereum Private Network from Scratch

·

Setting up a private Ethereum network is a critical step for developers looking to test smart contracts, decentralized applications (dApps), and blockchain configurations in an isolated, controlled environment. This guide walks you through the complete process of creating your own private Ethereum blockchain using geth, compiling and deploying smart contracts, and managing multi-node setups—all without relying on public networks.

Whether you're a beginner learning blockchain development or an experienced engineer building enterprise-grade solutions, this tutorial provides hands-on instructions with clear explanations.


Setting Up the Required Environment

Before launching your private Ethereum network, ensure your system meets the basic requirements.

Recommended Setup:

Using a Linux-based OS like Ubuntu simplifies dependency management and terminal operations, making it ideal for blockchain development.


Installing Geth Client

Open your terminal (Ctrl+Alt+T) and run the following commands to install geth:

sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository -y ppa:ethereum/ethereum
sudo add-apt-repository -y ppa:ethereum/ethereum-dev
sudo apt-get update
sudo apt-get install ethereum

After installation, verify success by typing:

geth -h

If help documentation appears, geth is correctly installed and ready for use.

👉 Learn how blockchain networks are secured and maintained on a decentralized infrastructure.


Creating Your Private Ethereum Chain

Step 1: Initialize Data Directory

Create a dedicated folder to store blockchain data:

mkdir privatechain
cd privatechain

Step 2: Launch the Private Network

Use this command to start your node:

geth --networkid 123 --dev --datadir data --rpc --rpcaddr 192.168.31.140 --rpcport 8545 --port 3000 console

Key Parameters Explained:

You’ll see logs indicating that IPC and HTTP endpoints are open—your node is now running.

To simplify future use, save this command in a script:

echo 'geth --networkid 123 --dev --datadir data --rpc --rpcaddr 192.168.31.140 --rpcport 8545 --port 3000 console' > init.sh
chmod 775 init.sh

Connecting to the Geth Console

Keep the first terminal running and open a new one to attach to the node:

geth attach ipc:data/geth.ipc

This opens an interactive JavaScript console with built-in objects:

Save this connection command as well:

echo 'geth attach ipc:data/geth.ipc' > connect.sh
chmod 775 connect.sh

Managing Accounts and Transactions

Create a New Account

personal.newAccount("your-password")
🔐 Use strong passwords during development to simulate real-world security practices.

Check Balance and Transfer Funds

List accounts:

eth.accounts

Check balance:

eth.getBalance(eth.accounts[0])

Unlock account for transaction:

personal.unlockAccount(eth.accounts[0])

Send funds:

amount = web3.toWei(5, 'ether');
eth.sendTransaction({
  from: eth.accounts[0],
  to: eth.accounts[1],
  value: amount
});

Start mining to confirm the transaction:

miner.start()
// Wait a few seconds
miner.stop()

Verify receipt:

eth.getBlock("pending", true)
eth.getBalance(eth.accounts[1])

Deploying Smart Contracts via Command Line

Write the Contract

Create a Solidity file:

nano DemeterContract.sol

Paste the following contract code:

pragma solidity ^0.5.4;

contract DemeterContract {
    mapping(address => uint) balances;
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    uint public ticketIndex;
    mapping(address => mapping(uint => Ticket)) stores;
    mapping(uint => address) ticketIdInStore;

    struct Ticket {
        uint id;
        string name;
        string content;
        address receiveraddr;
    }

    constructor() public {
        ticketIndex = 0;
        balances[tx.origin] = 10000;
    }

    function sendCoin(address receiver, uint amount) public returns(bool sufficient) {
        if (balances[msg.sender] < amount) return false;
        balances[msg.sender] -= amount;
        balances[receiver] += amount;
        emit Transfer(msg.sender, receiver, amount);
        return true;
    }

    function getBalance(address addr) public view returns(uint) {
        return balances[addr];
    }

    function addTicketToStore(string memory _name, string memory _content, address _receiveraddr) public {
        ticketIndex += 1;
        Ticket memory ticket = Ticket(ticketIndex, _name, _content, _receiveraddr);
        stores[msg.sender][ticketIndex] = ticket;
        ticketIdInStore[ticketIndex] = msg.sender;
    }

    function getTicket(uint _ticketId) public view returns(uint, string memory, string memory){
        Ticket memory ticket = stores[ticketIdInStore[_ticketId]][_ticketId];
        return (ticket.id, ticket.name, ticket.content);
    }
}

Compile the Contract

Install Solidity compiler:

npm install -g solc

Generate bytecode:

solcjs --bin DemeterContract.sol

Copy output from generated .bin file.

Generate ABI:

solcjs --abi DemeterContract.sol

Deploy the Contract

Back in the Geth console:

var bytecode = "0x<PASTE_BYTECODE_HERE>"
var abi = <PASTE_ABI_ARRAY>

var myContract = web3.eth.contract(abi);
var account1 = eth.coinbase;

personal.unlockAccount(account1);

myContract.new({
    data: bytecode,
    gas: 2000000,
    from: account1
}, function(e, contract) {
    if (!e) {
        if (!contract.address) {
            console.log("Transaction Hash:", contract.transactionHash);
        } else {
            console.log("Contract deployed at:", contract.address);
        }
    } else {
        console.log("Error:", e);
    }
});

Start mining to finalize deployment:

miner.start(1); sleep(3); miner.stop();

Confirm deployment:

eth.getCode(contractInstance.address)

FAQ: Common Questions About Private Ethereum Networks

Q: Why do I need a private Ethereum network?
A: A private network lets you test dApps, smart contracts, and consensus mechanisms safely without spending real Ether or exposing unfinished code to the public.

Q: Can multiple nodes connect across different computers?
A: Yes. As long as they share the same genesis file and network ID, nodes on different machines can peer using admin.addPeer() with valid enode URLs.

Q: What is the purpose of the genesis block?
A: The genesis block defines initial parameters like chain ID, difficulty, gas limit, and pre-funded addresses—ensuring all nodes start from the same state.

Q: How do I fix "invalid address" when calling contract functions?
A: Ensure addresses passed into functions are checksummed or properly formatted. Also, unlock sender accounts before sending transactions.

Q: Is Mist wallet still supported?
A: Mist has been deprecated. Modern alternatives include MetaMask (for browser interaction) or Hardhat + Ethers.js for development workflows.

Q: Can I automate contract deployment?
A: Yes. Tools like Truffle or Hardhat streamline compilation, migration, and deployment—especially useful for complex projects.


Running Multiple Nodes on One Machine

To simulate a distributed network:

Node 1:

geth --networkid 123 --datadir data2 --rpc --rpcaddr 192.168.1.23 --rpcport 9000 --port 3001 console

Node 2:

geth --networkid 123 --datadir data3 --rpc --rpcaddr 192.168.1.23 --rpcport 9001 --port 3002 console

Each node uses unique data directories and ports to avoid conflicts.

Connect them manually:

admin.addPeer("enode://<node2-enode-address>@127.0.0.1:3002")

Check connection status:

net.peerCount
admin.peers

👉 Discover how decentralized networks maintain consensus across global nodes.


Initializing Blockchain with a Custom Genesis Block

Create genesis.json:

{
  "config": {
    "chainId": 15,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
  },
  "alloc": {
    "bc9a3ece02d7cb31cf63dfdfc48db0b82770d014": { "balance": "300000" },
    "457e7d69fd3ac576aa744228e6b3319cde768473": { "balance": "400000" }
  },
  "difficulty": "4",
  "gasLimit": "2100000"
}

Initialize the chain:

geth init genesis.json --datadir data5

Launch node:

geth --networkid 123 --datadir data5 console

Verify pre-funded balances:

eth.getBalance("0xbc9a3ece02d7cb31cf63dfdfc48db0b82770d014")

Set coinbase for mining rewards:

miner.setEtherbase("0xbc9a3ece02d7cb31cf63dfdfc48db0b82770d014")
miner.start(1)

Core Keywords for SEO Optimization

ethereum private network, geth setup tutorial, smart contract deployment, genesis block configuration, run multiple geth nodes, compile solidity contract, blockchain development guide

With these foundational skills, you’re equipped to build robust decentralized applications in a secure testing environment—ready for real-world deployment.

👉 Explore advanced tools and platforms that support Ethereum development and Web3 innovation.