Ethereum Private Chain Setup and Smart Contract Deployment

·

Setting up an Ethereum private chain and deploying smart contracts is a foundational skill for blockchain developers, researchers, and enterprises exploring decentralized applications (dApps). This comprehensive guide walks you through the entire process—from environment preparation to deploying and interacting with a smart contract—using industry-standard tools like Geth, Solidity, and Remix. Whether you're building a testnet for development or simulating a consortium blockchain, this tutorial provides practical, step-by-step instructions.

Prerequisites and Environment Setup

Before diving into blockchain creation, ensure your system meets the necessary requirements. This guide uses CentOS 7 in a VMware virtual machine with essential development tools.

Install Required Dependencies

To avoid installation errors later, pre-install commonly used packages:

yum update -y && yum install git wget bzip2 vim gcc-c++ ntp epel-release nodejs cmake -y

Each component serves a specific purpose:

👉 Get started with blockchain development tools today.

Installing and Configuring Ethereum (Geth)

Clone and Compile Geth

The Go implementation of Ethereum (Geth) powers your private network.

  1. Clone the official repository:

    git clone https://github.com/ethereum/go-ethereum.git
  2. Navigate into the directory and compile:

    cd go-ethereum && make all
  3. Add Geth to your system path:

    echo 'export PATH=$PATH:$GOPATH/bin:$HOME/go-ethereum/build/bin' >> ~/.profile
    source ~/.profile
  4. Verify installation:

    geth -h

    If help output appears, Geth is correctly installed.

Upgrade CMake for Smart Contract Compilation

The default CMake version via yum may be outdated. Download and compile the latest version:

cd && wget https://cmake.org/files/v3.12/cmake-3.12.3.tar.gz
tar -xzvf cmake-3.12.3.tar.gz
cd cmake-3.12.3
./bootstrap && make && sudo make install

Update your PATH:

echo 'export PATH=$PATH:$HOME/cmake/bin' >> ~/.profile
source ~/.profile

Verify with cmake --version.

Configure System Services

Enable NTP for accurate timekeeping—critical in blockchain consensus:

systemctl enable ntpd
systemctl start ntpd

For firewall settings, either disable it (for testing):

systemctl stop firewalld
systemctl disable firewalld

Or allow specific ports:

firewall-cmd --zone=public --add-port=8087/tcp --permanent
firewall-cmd --zone=public --add-port=30303/tcp --permanent
firewall-cmd --reload

Creating the Genesis Block

The genesis block defines your private blockchain’s initial state.

Create genesis.json:

{
  "nonce": "0x0000000000000042",
  "timestamp": "0x00",
  "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
  "extraData": "0x00",
  "gasLimit": "0x80000000",
  "difficulty": "0x400",
  "mixhash": "0x000000000000000000000000000000000000000000000000000000000000000",
  "coinbase": "0x2D356ee3F5b8718d8690AFCD31Fe2CB5E612677e",
  "alloc": {},
  "config": {
    "chainId": 15,
    "homesteadBlock": 1,
    "eip155Block": 2,
    "eip158Block": 3
  }
}

Initialize the first node:

geth --datadir node1 init genesis.json

Start the node console:

geth --datadir node1 console 2>> geth.log

Monitor logs in another terminal:

tail -f geth.log

Adding Multiple Nodes to the Network

To simulate a distributed network, add a second node.

Initialize a new node:

geth --datadir node2 init genesis.json

Launch the first node with RPC enabled:

geth --datadir node1 --networkid 23456 --rpc --rpcaddr "127.68.1.1" console 2>> geth.log

Launch the second node with unique ports:

geth --datadir node2 --networkid 23456 --rpc --rpcport 8546 --port 31314 console 2>> geth.log

In the second node’s console, retrieve its enode URL:

admin.nodeInfo.enode

Add it to the first node:

admin.addPeer("enode://<your-enode-url-here>@127.68.1.1:31314")

You’ll see peer connection logs confirming successful integration.

👉 Explore secure blockchain deployment practices now.

Understanding Block and Transaction Fields

Key Block Attributes

Each block contains metadata crucial for network integrity:

The mixHash proves computational effort, while the extraData field can store arbitrary information.

Transaction Breakdown

Every transaction includes:

Note: Actual fee = gasUsed * gasPrice. Unused gas is refunded.

Deploying a Smart Contract

Write a Simple Solidity Contract

Using Remix IDE, create a basic contract:

pragma solidity ^v.4.18;

contract Test {
    string public name;

    function Test() public {
        name = "xietao";
    }

    function getName() public view returns (string) {
        return name;
    }

    function setName(string _name) public {
        name = _name;
    }
}

Compile and Deploy via Geth Console

After compiling in Remix, copy the Web3 deploy snippet into your Geth console.

Unlock your account first:

personal.unlockAccount(eth.accounts[9])

Deploy using:

var test = testContract.new({from: eth.accounts[9], data: '...', gas: '476543'}, function(e, contract) {
    if (typeof contract.address !== 'undefined') {
        console.log("Contract mined at:", contract.address);
    }
});

Start mining to confirm deployment:

miner.start(); admin.sleepBlocks(1); miner.stop();

Upon success, you’ll see:

Contract mined! address: 6x7e8169387a54814fcc61a48729b7a891f24cd291 ...

Interacting With Your Contract

Read operations are free:

test.getName()
// Returns: "xietao"

Write operations require gas:

eth.defaultAccount = eth.accounts[9]
test.setName("newName")

Or specify sender explicitly:

test.setName("updated", {from: eth.accounts[9]})

Always mine after write transactions:

miner.start(1); miner.stop()
Reading doesn’t alter state; writing does—and costs gas due to network computation and storage.

Frequently Asked Questions

What is a genesis block?

The genesis block is the first block in a blockchain, defining initial parameters like difficulty, gas limits, and chain ID. It anchors the entire network and must be identical across all nodes.

Why do I need to mine after deploying a contract?

Mining confirms transactions on Proof-of-Work chains. Without mining, contract deployment remains pending and unconfirmed in the mempool.

How do I prevent my private chain from connecting to public nodes?

Use the --nodiscover flag when launching Geth. Otherwise, nodes may sync with the mainnet if they share common network IDs like 1.

Can I change the gas limit of a block?

Yes—modify the "gasLimit" field in genesis.json. For example, "gasLimit": "6B2F" sets a higher cap suitable for complex contracts.

What happens if I run out of gas during a transaction?

The transaction fails, changes are reverted, but gas used is not refunded since miners performed computational work.

Is it safe to expose RPC ports?

Only in trusted environments. In production, restrict access via firewalls or use secure tunneling (e.g., HTTPS + authentication).

👉 Secure your blockchain infrastructure with trusted tools.