Private Ethereum By ExampleJohn TuckerBlockedUnblockFollowFollowingFeb 5Private 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 EthereumPrivate 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 BlockchainsProof of AuthorityFor 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 testnetThe ExampleWe 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.
NodesThe 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:docker run -it ethereum/client-go:alltools-stableObservations:The -it options make the Docker containers interactiveIn order to help keep track of each of the nodes, I used different colors for each of the terminals.
AccountsIn each of the nodes, we execute the following command; copying the account’s address for later user:geth –datadir .
/datadir account newObservations:If you need to find the address later, it can be found in a file (one per account) in the datadir/keystore folderGenesis BlockWe 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 EthereumHere we use one of the additional tools in the Docker image; execute the following command on one of the nodes.
puppethObservations:This tool has an interactive wizard interfaceWhile this tool has other functionality, we will only be using it to generate the genesis fileSteps:Provide a network name; this value is internal to this tool and is otherwise meaninglessSelect the Configure new genesis optionSelect the Create new genesis from scratch optionSelect the Clique — proof-of-authority optionLeave the default (15) for the question How many seconds should blocks take?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 windowOn the Which accounts should be pre-funded?, provide all three account addressesSelect the default (yes) to Should the precompile-addresses (0x1 .
0xff) be pre-funded with 1 wei?Provide a random number (default) to Specify your chain/network ID…Select the Manage existing genesis optionSelect the Export genesis configurations optionSelect the default (empty) to the Which folder to save the genesis specs into?Exit puppeth by pressing Ctrl+cObservations:Do not know what the precompile-addresses are; could not find information on themDon’t worry about the errors creating the Aleth and Parity chain specs; we don’t need them anywayGo ahead and delete the generated file that ends in -harmony.
jsonFor clarity, rename the other generated file to genesis.
jsonObservations:For readability, I removed most of the allocations related to the precompile-addressesThe article Explaining the Genesis Block in Ethereum does a great job describing all the information in this fileWe 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:geth –datadir .
/datadir init genesis.
jsonStarting the ClientsWe start the clients on the nodes (without the authority account) using the following command:geth –datadir .
/datadir –nat extip:`hostname -i` consoleObservations: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:geth –datadir .
/datadir –nat extip:`hostname -i` –unlock 0 –password password.
txt consoleObservations:Accounts are maintained in a zero-indexed array; thus the 0 for the first and only accountAdd PeersAs 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:admin.
enodeIn 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):admin.
addPeer('[CLIENT-ADDRESS]')note: This is why using a boot node is preferred.
We can use the following command to verify the peers:admin.
peersStart MinerWhile 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:miner.
start(1)Observations:The 1 parameter indicates that we are using a single threadIf all goes well, every 15 seconds, we will see a new block created; log output on each of the clientsCreate Smart ContractFollow 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.
js, on one of the two clients (without the authority account).
var _greeting = "Hello World!";.
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 ContractIn 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.
accounts, '[PASSWORD]')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 soWe can then deploy the smart contract using the command:loadScript('Greeter.
js')Once submitted, the miner client will add it to the blockchain in one of regular (every 15 seconds) update:Run Smart ContractFrom the client that deployed the smart contract, we can run the smart contract by simply using:greeter.
greet();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:greeter.
addressFrom 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 implementationWith the interface and reference, we can then define the greeter variable:var greeter = eth.
at([REFERENCE]);and then call it as we did before:greeter.
greet();Wrap UpWhile 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).