Private Ethereum By Example

John Tucker
Coinmonks
8 min readFeb 5, 2019

--

Private Ethereum example using the proof of authority consensus instead of the more familiar proof of work consensus.

First, a big shout-out to Adeyemi Toluhi for his article Ethereum: Setting Up A Private Blockchain as it was instrumental in me writing this article.

Private Ethereum

Private Ethereum is an example of a private blockchain; described by the founder of Ethereum.

Essentially, instead of having a fully public and uncontrolled network and state machine secured by cryptoeconomics (eg proof-of-work, proof-of-stake), it is also possible to create a system where access permissions are more tightly controlled, with rights to modify or even read the blockchain state restricted to a few users, while still maintaining many kinds of partial guarantees of authenticity and decentralization that blockchains provide.

— Vitalik Buterin — On Public and Private Blockchains

Also Read: The Best Ethereum Hardware wallet

Proof of Authority

For Ethereum, the Clique protocol is an example of a broader Proof of Authority consensus mechanism:

For those not aware of how PoA works, it’s a very simplistic protocol, where instead of miners racing to find a solution to a difficult problem, authorized signers can at any time at their own discretion create new blocks.

The challenges revolve around how to control minting frequency, how to distribute minting load (and opportunity) between the various signers and how to dynamically adapt the list of signers..

— Ethereum — Clique PoA protocol & Rinkeby PoA testnet

The Example

We will build a private Ethereum blockchain running on a network consisting of three nodes; each with a unique account. One of the accounts is designated as an authority, aka sealer.

We will then create and run the Ethereum Greeter smart contract example on the blockchain.

Prerequisites (Optional)

If you wish to follow along, you will need to install Docker; we will do everything using Docker containers.

Nodes

The first step is to create the three nodes as Docker containers using the ethereum/client-go:alltools-stable image (we use the larger image as we need additional tools to Geth). We run the following command in each of three terminals:

Observations:

  • The -it options make the Docker containers interactive
  • In order to help keep track of each of the nodes, I used different colors for each of the terminals.

Accounts

In each of the nodes, we execute the following command; copying the account’s address for later user:

Observations:

  • If you need to find the address later, it can be found in a file (one per account) in the datadir/keystore folder

Genesis Block

We next create the genesis block:

Every blockchain has to start somewhere, so there’s what’s called a genesis block at the beginning. This is the first block, and in it the creators of Ethereum were at liberty to say “To start, the following accounts all have X units of my cryptocurrency.” Any transfer of that ether on the blockchain will have originated from one of these initial accounts (or from mining).

— Brandon Arvanaghi— Explaining the Genesis Block in Ethereum

Here we use one of the additional tools in the Docker image; execute the following command on one of the nodes.

Observations:

  • This tool has an interactive wizard interface
  • While this tool has other functionality, we will only be using it to generate the genesis file

Steps:

  1. Provide a network name; this value is internal to this tool and is otherwise meaningless
  2. Select the Configure new genesis option
  3. Select the Create new genesis from scratch option
  4. Select the Clique — proof-of-authority option
  5. Leave the default (15) for the question How many seconds should blocks take?
  6. On the Which accounts are allowed to seal?, provide the address of one of the accounts (will be the authority); I used the account on the node in the black window
  7. On the Which accounts should be pre-funded?, provide all three account addresses
  8. Select the default (yes) to Should the precompile-addresses (0x1 .. 0xff) be pre-funded with 1 wei?
  9. Provide a random number (default) to Specify your chain/network ID…
  10. Select the Manage existing genesis option
  11. Select the Export genesis configurations option
  12. Select the default (empty) to the Which folder to save the genesis specs into?
  13. Exit puppeth by pressing Ctrl+c

Observations:

  • Do not know what the precompile-addresses are; could not find information on them
  • Don’t worry about the errors creating the Aleth and Parity chain specs; we don’t need them anyway
  • Go ahead and delete the generated file that ends in -harmony.json
  • For clarity, rename the other generated file to genesis.json

genesis.json

Observations:

  • For readability, I removed most of the allocations related to the precompile-addresses
  • The article Explaining the Genesis Block in Ethereum does a great job describing all the information in this file
  • We pre-allocated each of the accounts with huge (virtually infinite) balances as eth currency is not relevant to private networks (using proof of authority); although Ethereum still needs it to operate. At the same time, it is not clear how we are supposed to manage the balances of new accounts. Hmm?

We now copy this file into the two other nodes; in my case, I used cat to list the file, selecting the output I used my machine’s copy (cntl+c) command and pasted into an open vi editor on each of the other two other nodes.

note: IMHO, knowing how to use vi is a must; much like knowing how to type.

Finally, on each of the nodes we execute:

Starting the Clients

We start the clients on the nodes (without the authority account) using the following command:

Observations:

  • By default, the client attempts to determine a public IP address to communicate over (as Ethereum is a peer-to-peer network); we however are running a private network (thus the need to use the nat option)
  • The UNIX hostname -i command simply outputs the nodes IP address (and in UNIX back ticks evaluates a command inline)

As we want to login (aka unlock) the authority account on the client on the node (with the authority account), we first create a file, password.txt, with the account’s password and then execute:

Observations:

  • Accounts are maintained in a zero-indexed array; thus the 0 for the first and only account

Add Peers

As of the clients were started with the same genesis block (and thus same chain id) they can participate in the same blockchain. At the same time, as configured the clients cannot discover each other; we need to manually add their peering relationship.

note: Another approach, preferred, is setting up an another node to act as the boot node; described in Ethereum: Private network.

We run the following command on each client to obtain its address:

In the case of three nodes, we have three peering relationships; thus we need to execute the following command three times (will leave it to you to figure what clients and order):

note: This is why using a boot node is preferred.

We can use the following command to verify the peers:

Start Miner

While we are not technically mining, we are using proof of authority, we still need the client with the authority account logged in to be continuously generating blocks; otherwise transactions we create will not be added to the blockchain.

note: It feels weird to me to be continually creating blocks with no transactions in them. Hmm?

We execute the following command, on the client with the authority account, to start mining:

Observations:

  • The 1 parameter indicates that we are using a single thread
  • If all goes well, every 15 seconds, we will see a new block created; log output on each of the clients

Create Smart Contract

Follow the instructions at Ethereum: Create a Digital Greeter to create an example smart contract:

Smart contracts are account holding objects on the ethereum blockchain. They contain code functions and can interact with other contracts, make decisions, store data, and send ether to others. Contracts are defined by their creators, but their execution, and by extension the services they offer, is provided by the ethereum network itself. They will exist and be executable as long as the whole network exists, and will only disappear if they were programmed to self destruct.

— Ethereum — Create a Digital Greeter

The build artifact, from Remix, we need is the JavaScript WEB3DEPLOY code; copied into to a file, e.g., Greeter.js, on one of the two clients (without the authority account).

We also need to update the first line of the JavaScript WEB3DEPLOY code to supply the required _greeting parameter for the Greeter constructor.

The easiest way of accomplishing this is to use the exit command to terminate the client, create the file, restart the client (above), and add the two peering relationships back (above).

note: Starting to wish we setup the boot node.

Deploy Smart Contract

In order to deploy a smart contract we need to login (unlock) the account (with sufficient eth) in the client (on the node with the Greeter.js file):

Observation:

  • Again, accounts are maintained in a zero-indexed array; thus the 0 for the first and only account (on this node)
  • When accounts are unlocked inside the client, it will auto-logout (lock) in a minute or so

We can then deploy the smart contract using the command:

Once submitted, the miner client will add it to the blockchain in one of regular (every 15 seconds) update:

Run Smart Contract

From the client that deployed the smart contract, we can run the smart contract by simply using:

displaying Hello World!

While the other clients have access to the Greeter smart contract (in the blockchain), they do not have either a reference to or an interface for it.

From the client that deployed the smart contract, we can run the following to obtain the smart contract’s address (in the blockchain); this is the reference:

From where we compiled the smart contract, Remix, we copy the ABI; this is the interface:

Observations:

  • This is simply the interface and meta information for the smart contract; no implementation

With the interface and reference, we can then define the greeter variable:

and then call it as we did before:

Wrap Up

While it is still sinking into my brain, I can now see a glimmer of the power of blockchain (distributed ledger) technologies; in this case we able to share a common piece of immutable code between two disparate accounts (organizations).

Join Coinmonks Telegram Channel and Youtube Channel get daily Crypto News

Also, Read

--

--

John Tucker
Coinmonks

Broad infrastructure, development, and soft-skill background