Raspberry Pi and Ethereum: The Epilogue

This tutorial is part of a series of articles introduced here.

In part 6, we finalized the configuration of the private blockchain. We sent ether between our nodes and verified that the database is properly synchronised.

NB: It is important that what we mean by “private Ethereum blockchain” in this context has absolutely nothing to do with the “private blockchain” championed by Hyperledger, Eris/Monax, or the recently announced Enterprise Ethereum Alliance. These are different codebases with different client applications, so they correspond to different implementations of a different set of concepts. They are private in the sense that they limit who has access to their chain. They are also called permissioned blockchains, and to be perfectly transparent, we wish they were not even called blockchains at all. In this series of articles, what we call “private blockchain” is a private instance of the Ethereum implementation. Same code base, same client application, different network identifier and genesis block. In other words, what we will come to create in this series is a chain with the same rules as the main chain, the same consensus algorithm too, but a different root block. This will become clearer in part 3. For more information about the 3-layer model and differences between concepts, implementations and instances, you can also watch our Devoxx talk and read this article.

So far, we only worked with pure software. In this final part, we will connect our blockchain with the physical world and connect some wires.

The goal of this tutorial is to check whether you are allowed to use a service. By using a button and two LEDs (green and red), we will be able to check the Smart Contract (SmartToken) to retrieve the number of tokens assigned to the user account (identified by its address).

To complete this tutorial, we will use the following solutions:

  • Hardware: A breadboard, 2 LEDs (green and red), a button, 4 resistors (2 x 220Ω, 1kΩ, 10kΩ), some wires
  • Software: Node.js and two packages (Web3 and OnOff)

The sample was inspired by the post available here.

It’s time to build some electronics.

Step 1 – Start with some electronics

Before you proceed, ensure your RPi is turned off.

The goal is to connect a LED to the GPIO17 port of the RPi.

The schematic is the following:

Here below you can see the breadboard that shows how to physically connect the electronic parts:

The GPIO17 port (port 11) is linked to the anode pin (positive) of the led.

The cathode pin (negative) of the led is connected to the resistor which is linked to the GND port (port 6) of the RPi.

Ensure to respect the polarity of the LED (check here).

When you have finished, you can power on the RPi.

Step 2 – Connect to your RPi

Use the SSH command to connect to your RPi as illustrated here below:

computer$ ssh pi@192.168.1.31

Step 3 – Start nodes

Before deploying the Smart Contract, let’s start our nodes.

Start the miner #1:

computer$ cd ~/ChainSkills/miner1
computer$ ./startminer1.sh

Start the miner #2:

computer$ cd ~/ChainSkills/miner2
computer$ ./startminer2.sh

Start the RPi node:

pi$ cd ~/ChainSkills/node
pi$ ./starnode.sh

Step 4 – Prepare the RPi

This step describes all the operations to perform on your RPi in order to set up all the pieces of software.

Step 4.1 – Install Node.js

We will use Node.js to run the script that interacts with the Smart Contract.

To install Node.js 7.x on your RPi, please follow the instructions illustrated here below:

pi$ curl -sL https://deb.nodesource.com/setup_7.x | sudo -E bash -
pi$ sudo apt-get install nodejs

pi$ node -v
v7.4.0

pi$ npm -v
4.0.5

Step 4.2 – Install Git

Git will be required for the installation of Web3:

pi$ sudo apt-get install git

Step 4.3 – Prepare the project folder

Let’s create the folder for our project:
pi$ mkdir -p ~/Projects/ChainSkills/SmartToken

Step 4.4 – Install Web3 module

The Ethereum Web3 package is a node module that provides a JavaScript API to interact with the Ethereum blockchain.
This module will be required to allow the JS script to fetch the status of the Smart Contract.
Install the Web3 module:
pi$ cd ~/Projects/ChainSkills/SmartToken
pi$ npm install web3

Step 4.5 – Install OnOff module

The OnOff module is used to easily interact with GPIO pins of the RPi and set them On or Off.

Install the OnOff module:
pi$ cd ~/Projects/ChainSkills/SmartToken
pi$ npm install onoff

Step 5 – Create the client application

Let’s create a JS script the called “smart_token.js“.

This script will be used to:

  1. Interact with the Smart Contract
  2. Interact with RPi

Create the file “smart_token.js”:

pi$ cd ~/Projects/ChainSkills/SmartToken
pi$ nano smart_token.js

Copy and paste the following code:

// Interaction with GPIO
var Gpio = require('onoff').Gpio

// Interaction with Ethereum
var Web3 = require('web3')
var web3 = new Web3()

// connect to the local node
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8042'))

// The contract that we are going to interact with
var contractAddress = '0xe1d76d2bffc600333248343f7a1d144edaef29a2'

// Define the ABI (Application Binary Interface)
var ABI = JSON.parse('[{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"value","type":"uint256"}],"name":"depositToken","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"recipient","type":"address"}],"name":"getTokens","outputs":[{"name":"value","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"value","type":"uint256"}],"name":"withdrawToken","outputs":[{"name":"success","type":"bool"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"status","type":"uint256"}],"name":"OnStatusChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"OnValueChanged","type":"event"}]')

// contract object
var contract = web3.eth.contract(ABI).at(contractAddress)

// components connected to the RPi
var greenLed = new Gpio(14, 'out')
var redLed = new Gpio(15, 'out')
var button = new Gpio(18, 'in', 'rising')


// display initial state
showStatus()


// watch event on the button
button.watch(function (err, value) {
 if (err) {
 throw err
 }

 showStatus()
})


// wait for an event triggered on the Smart Contract
var onValueChanged = contract.OnValueChanged({_from: web3.eth.coinbase});

onValueChanged.watch(function(error, result) {
 if (!error) {
 showStatus()
 }
})


// power the LED according the value of the token
function showStatus() {
 
 // retrieve the value of the token
 var token = contract.getTokens(web3.eth.coinbase)

 // display the LED according the value of the token
 if (token > 0) {
 // Green: you have enough token
 redLed.writeSync(0)
 greenLed.writeSync(1)
 } else {
 // Red: not enough token
 greenLed.writeSync(0)
 redLed.writeSync(1)
 }

}


// release process
process.on('SIGINT', function () {
 greenLed.unexport()
 redLed.unexport()
 button.unexport()
})

This script has to be changed according to your environment.

First, change the value of the variable “contractAddress” with the address of the contract deployed on your private blockchain (see part 6).

Then, provide the ABI of your SmartContract (see part 6) by replacing the content of the variable “ABI“.

Step 6 – Run the client application

Run the client application:

pi$ node smart_token.js

The client application will wait for a change to occur on the Smart Contract.

Step 7 – Test the application

Test your application using Mist by depositing tokens to the coinbase address of the Pi node.

You should see the appropriate LED displayed according the remaining amount of token.

You can also press the button to get the number of tokens.

Summary

Congratulations!

You have successfully completed this series of tutorials.

Of course, this is just a glimpse of what you can do with Ethereum but you had the opportunity to experiment some part of this technology.

Now, it’s up to you to move forward with the journey and to imagine other kinds of Smart Contracts and how to link them with IoT devices.

Shameless plug

Now that you are done with this series, we just wanted to let you know that we are currently preparing a full-blown online training about the development of distributed applications on Ethereum and we are looking for your feedback to figure out what you would like to see in this training. If you want to help us, you can take a few minutes to answer a survey here.

And if you just want us to keep you informed when the full online training program will be available, you can register to our mailing list on beta.chainskills.com.

Create and deploy a Smart Contract (6/6)

This tutorial is part of a series of articles introduced here.

In part 5, we finalized the configuration of the private blockchain. We sent ethers between our nodes and verified that the database is properly synchronised.

In this part, we will describe how to create and deploy a Smart Contract on the private blockchain.

NB: It is important that what we mean by “private Ethereum blockchain” in this context has absolutely nothing to do with the “private blockchain” championed by Hyperledger, Eris/Monax, or the recently announced Enterprise Ethereum Alliance. These are different codebases with different client applications, so they correspond to different implementations of a different set of concepts. They are private in the sense that they limit who has access to their chain. They are also called permissioned blockchains, and to be perfectly transparent, we wish they were not even called blockchains at all. In this series of articles, what we call “private blockchain” is a private instance of the Ethereum implementation. Same code base, same client application, different network identifier and genesis block. In other words, what we will come to create in this series is a chain with the same rules as the main chain, the same consensus algorithm too, but a different root block. This will become clearer in part 3. For more information about the 3-layer model and differences between concepts, implementations and instances, you can also watch our Devoxx talk and read this article.

Introduction

We are going to create a Smart Contract called SmartToken.

This contract will hold an associative array of addresses and integers. Each address will be associated with a number of tokens that expresses if the user identified by this address is able to use a specific service (tokens > 0) or not (tokens == 0).

As you can see, this example is simplistic. But it will be useful to understand the basic principles of Smart Contracts.

Step 1 – Install Truffle

Truffle is a development framework for Ethereum. There are many others, but we will use Truffle in this tutorial, to develop and deploy our smart contract.

To install Truffle, run the following command:

$ npm install -g truffle

Step 2 – Create the project

From your computer, create the folder that will host your project:

computer$ mkdir -p ~/ChainSkills/Projects/SmartToken

Then, use Truffle to initiate your project:

computer$ cd ~/ChainSkills/Projects/SmartToken
computer$ truffle init

You should obtain the following tree structure:

|____contracts
| |____ConvertLib.sol
| |____MetaCoin.sol
| |____Migrations.sol
|____migrations
| |____1_initial_migration.js
| |____2_deploy_contracts.js
|____test
| |____metacoin.js
| |____TestMetacoin.sol
|____truffle.js

This initial project comes with a sample project (MetaCoin).

Open the project with your favorite text editor (Atom, Sublime, etc.).

Step 3 – Create the contract

In the “contracts” directory, create a file named “SmartToken.sol” and paste the following code:

pragma solidity ^0.4.0;

contract SmartToken {
    mapping(address => uint) tokens;

    event OnValueChanged(address indexed _from, uint _value);

    function depositToken(address recipient, uint value) returns (bool success) {
        tokens[recipient] += value;

        OnValueChanged(recipient, tokens[recipient]);
        return true;
    }

    function withdrawToken(address recipient, uint value) returns (bool success) {
        if ((tokens[recipient] - value) < 0) {
            tokens[recipient] = 0;
        } else {
            tokens[recipient] -= value;
        }

        OnValueChanged(recipient, tokens[recipient]);
        return true;
    }

    function getTokens(address recipient) constant returns (uint value) {
        return tokens[recipient];
    }
}

This contract has three functions:

  • depositToken: add some tokens to a specific address
  • withdrawToken: withdraw some token from a specific address
  • getTokens: retrieve the number of tokens available for a specific address

Step 4 – Prepare for deployment

Before deploying the Smart Contract, you have to adjust several files in your project.

Step 4.1 – Adapt deployment file

Replace the content of “migrations/2_deploy_contracts.js” with the following content in order to deploy our “SmartToken” Smart Contract:

var SmartToken = artifacts.require("./SmartToken.sol");

module.exports = function(deployer) {
    deployer.deploy(SmartToken);
};

Step 4.2 – Adapt network settings

The file named “truffle.js” contains network settings used to identify your deployment platform.

We will deploy the Smart Contract onto one of our miners.

Let’s change the file to adjust the port number to fit our environment:

module.exports = {
  networks: {
    development: {
      host: "localhost",
      port: 8042,
      network_id: "*" // Match any network id
    }
  }
};

Step 5 – Deploy the contract

Before proceeding, start your miners to ensure that your Smart Contract will be properly mined and deployed on your private blockchain.

Step 5.1 – Start your miners in 2 different tabs

computer$ ~/ChainSkills/miner1/startminer1.sh
computer$ ~/ChainSkills/miner2/startminer2.sh

 Step 5.2 – Compile and deploy your contract

Run the command “truffle migrate” to compile and deploy your contract to your blockchain:

computer$ cd ~/ChainSkills/Projects/SmartToken

computer$ truffle compile
...
computer$ truffle migrate --reset
...
Running migration: 2_deploy_contracts.js
 Deploying SmartToken...
 SmartToken: 0xce96374a544729a7dedf133659709d6cb0e1aa0e
Saving successful migration to network...
Saving artifacts...
The “–reset” command line argument is used here to force truffle to deploy the contract, even if has already been deployed before, for repeatability’s sake.
And that’s it. Now our SmartToken contract is deployed onto our private Ethereum chain and it is ready to receive calls.

Step 6 – Interact with the contract

You can interact with your contract through the Geth console, the Mist browser or a client application.

In this tutorial, we will show how to use Mist to “watch” the contract and interact with it.

Step 6.1 – Identify the contract

Before using Mist, you have to retrieve two elements about your deployed contract:

  • its address
  • its ABI (Application Binary Interface)

This information can be retrieved through the Truffle console in this way:

computer$ truffle console

truffle(development)> SmartToken.address
'0xe1d76d2bffc600333248343f7a1d144edaef29a2'

truffle(development)> JSON.stringify(SmartToken.abi)
'[{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"value","type":"uint256"}],"name":"depositToken","outputs":[{"name":"success","type":"bool"}],"payab
le":false,"type":"function"},{"constant":true,"inputs":[{"name":"recipient","type":"address"}],"name":"getTokens","outputs":[{"name":"value","type":"uint256"}],"payable":false,
"type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"value","type":"uint256"}],"name":"withdrawToken","outputs":[{"name":"success","typ
e":"bool"}],"payable":false,"type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"status","type":"uint256"}],"name":"OnStatusChanged","type":"event"},{"anony
mous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"OnValueChanged","type":"event"}]'

Step 6.2 – Watch the contract on Mist

You can download the latest version of Mist for your system there. Mist is a special kind of browser, a distributed application browser, with a built in Ethereum wallet system that can connect to any network.

Start Mist. As it detects that an IPC file in the default location is being used, it connects to your private network. Once the user interface appears, click the Ethereum Wallet tab on the left, and click the CONTRACTS button in the upper right corner:

Select “WATCH CONTRACT” and fill the form:

  • Give an arbitrary name for the contract, like “SmartToken”
  • Enter the contract address retrieved from the Truffle console (SmartToken.address)
  • Enter the ABI (without enclosing quotes) retrieved from the Truffle console (JSON.stringify(SmartToken.abi))

The contract is now visible on Mist:

And you can interact with it:

Step 6.3 – Test the contract

To test the contract, pick the default address created on the RPi (you will understand why in the next part).

In our tutorial, this address (eth.coinbase) is: “0xb312d49ee143e803e07814ce0213e6327ab19250”

To check your contract, get the number of tokens of this contract:

The function “getTokens” is a constant. You can use it without paying any fees.

Now, deposit some tokens to this address. Choose the account that will execute the function and pay the fees:

When the block is mined, you should see that the value has changed:

Proceed with the withdraw function to ensure that your contract works as expected.

You can also watch the events triggered by the contract:

Summary

You have created, compiled and deployed a Smart Contract. We have also used this Smart Contract through Mist.

And that concludes this 6-part tutorial. To sum it up:

  • We installed the Go Ethereum client on both our laptop and our Raspberry Pi
  • We created our very own private Ethereum instance
  • We installed 2 mining nodes on the laptop, and a user node on the Raspberry Pi
  • We made sure all nodes were synchronized
  • And finally we deployed a smart contract to our private instance.

Now, we didn’t want to leave you like that, so we have one more thing… So stay tuned for the epilogue of this series.

Shameless plug

While you are waiting for the next part of this series, we just wanted to let you know that we are currently preparing a full-blown online training about the development of distributed applications on Ethereum and we are looking for your feedback to figure out what you would like to see in this training. If you want to help us, you can take a few minutes to answer a survey here.

And if you just want us to keep you informed when the full online training program will be available, you can register to our mailing list on beta.chainskills.com.

Synchronize the Raspberry PI with the Private Blockchain (5/6)

This tutorial is part of a series of articles introduced here.

In part 4, we paired the miners and ensured that the private blockchain is properly synchronised.

NB: It is important that what we mean by “private Ethereum blockchain” in this context has absolutely nothing to do with the “private blockchain” championed by Hyperledger, Eris/Monax, or the recently announced Enterprise Ethereum Alliance. These are different codebases with different client applications, so they correspond to different implementations of a different set of concepts. They are private in the sense that they limit who has access to their chain. They are also called permissioned blockchains, and to be perfectly transparent, we wish they were not even called blockchains at all. In this series of articles, what we call “private blockchain” is a private instance of the Ethereum implementation. Same code base, same client application, different network identifier and genesis block. In other words, what we will come to create in this series is a chain with the same rules as the main chain, the same consensus algorithm too, but a different root block. This will become clearer in part 3. For more information about the 3-layer model and differences between concepts, implementations and instances, you can also watch our Devoxx talk and read this article.

In this part, we are going to move forward with the setup of the Rapsberry PI and pair it with the miners.

All the commands ran from the computer are prefixed by “computer$“. Those ran from the RPi are identified with the prefix “pi$“.

Step 1 – Create the datadir folder

As already done for the miners, we have to use a specific folder that will host the data of the private blockchain.

Create this folder with the following command:

pi$ mkdir -p ~/ChainSkills/node

Step 2 – Transfer the genesis file

From your computer, upload the genesis.json file to the RPi:

computer$ cd ~/ChainSkills

computer$ sftp pi@192.168.1.31
pi@192.168.1.31's password: 
Connected to 192.168.1.31.

sftp> cd ChainSkills

sftp> put genesis.json
Uploading genesis.json to /home/pi/ChainSkills/genesis.json
genesis.json 100% 420 83.8KB/s 00:00 

sftp> exit

Step 3 – Initialize the node

It’s time to initialize the private blockchain on the RPi with the genesis block.
The private blochain data will reside in the folder “node”.
pi$ cd ~/ChainSkills
pi$ geth --datadir ~/ChainSkills/node init ../genesis.json

I0105 00:13:28.961585 cmd/utils/flags.go:615] WARNING: No etherbase set and no accounts found as default
...
I0105 00:13:29.441262 cmd/geth/chaincmd.go:131] successfully wrote genesis block and/or chain rule set: 6e92f8b23bcdfdf34dc813cfaf1d84b71beac80530506b5d63a2df10fe23a660
The log provides the following information:
  • you need a default account
  • the blockchain has been successfully created

Step 4 – Create accounts

Create an initial account that will be used to run the node.

To create the default account, type the following command. Keep the password in a safe place:

pi$ geth --datadir ~/ChainSkills/node account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 
Repeat passphrase: 
Address: {b312d49ee143e803e07814ce0213e6327ab19250}
The account creation might take a few seconds, don’t worry.
Add an additional account for testing purposes:
pi$ geth --datadir ~/ChainSkills/node account new 
Your new account is locked with a password. Please give a password. Do not forget this password. 
Passphrase: 
Repeat passphrase: 
Address: {6af547b83493fd59bf5a2e67546b65191392f45a}
The wallet for these accounts is located right here:
pi$ ls -l ~/ChainSkills/node/keystore 
-rw------- 1 pi pi 491 Jan 5 00:16 UTC--2017-01-04T23-15-54.907864384Z--b312d49ee143e803e07814ce0213e6327ab19250
-rw------- 1 pi pi 491 Jan 5 00:16 UTC--2017-01-04T23-16-32.920742236Z--6af547b83493fd59bf5a2e67546b65191392f45a
To list all accounts available on your node, use the following command:
pi$ geth --datadir ~/ChainSkills/node account list 

Account #0: {b312d49ee143e803e07814ce0213e6327ab19250} /home/pi/ChainSkills/node/keystore/UTC--2017-01-04T23-15-54.907864384Z--b312d49ee143e803e07814ce0213e6327ab19250

Account #1: {6af547b83493fd59bf5a2e67546b65191392f45a} /home/pi/ChainSkills/node/keystore/UTC--2017-01-04T23-16-32.920742236Z--6af547b83493fd59bf5a2e67546b65191392f45a

Step 5 – Prepare the node

We are ready to start the node from our RPi.

To start the node, we will require to run the following command:
geth --identity "node1" --fast --networkid 42 --datadir /home/pi/ChainSkills/node --nodiscover --rpc --rpcport "8042" --port "30303" --unlock 0 --password "/home/pi/ChainSkills/node/password.sec" --ipcpath /home/pi/.ethereum/geth.ipc

The meaning of the main parameters is the following:

  • identity: name of our node
  • fast: fast syncing of the database (more details here)
  • networkid: this network contains an arbitrary value that will be used to identify all nodes of the network. This value must be different from 0 to 3 (used by the live chains)
  • datadir: folder where is stored in our private blockchain
  • rpc and rpcport: enabling HTTP-RPC server and giving its listening port number
  • port: network listening port number
  • nodiscover: disable the discovery mechanism (we will pair our nodes later)
  • unlock: id of the default account
  • password: path to the file containing the password of the default account
  • ipcpath: path where to store the filename for IPC socket/pipe
You can find more information about Geth parameters right here.
We recommend you to store the Geth command into a runnable script. In our example, this script is called “startnode.sh” and is located here: ~/ChainSkills/node
#!/bin/bash

geth --identity "node1" --fast --networkid 42 --datadir /home/pi/ChainSkills/node --nodiscover --rpc --rpcport "8042" --port "30303" --unlock 0 --password "/home/pi/ChainSkills/node/password.sec" --ipcpath /home/pi/.ethereum/geth.ipc
You should then create the password file in the datadir folder of your node, and this file should just contain the password of the default account. In our example, this file is called “password.sec” and is located here: ~/ChainSkills/node

Step 6 – Start the node

Make the script runnable:

pi$ cd ~/ChainSkills/node 

pi$ chmod +x startnode.sh

Let’s start the node:

pi$ ./startnode.sh
...
You will notice that the server starts.

Step 7 – JavaScript console

You can manage your node using the Geth Javascript console.
To use this console from your RPi, open a second SSH session attached to your running instance of Geth.
Open a new terminal session and type “geth attach“.
pi$ geth attach
...
> 

Step 8 – Stop the mining nodes

If your miners are still running on your computer, go to their console window and press CTRL-C.

Another option is to kill the Geth running process as illustrated here below:

computer$ ps aux | grep geth

eloudsa 43872 0.0 2.2 556717632 363492 s001 S+ 3:49PM 1:58.01 geth --identity miner1 --dev

computer$ kill -INT 43872

 

Step 9 – Synchronise the blockhain

In this step, we are going to link the RPi to the private blockchain already synchronised on our miners.

Step 9.1 – Get Node info

Let’s start the node:
pi$ cd ~/ChainSkills/node

pi$ ./startnode.sh
...
 From your second terminal session, start the Geth console:
pi$ geth attach
...
>

Retrieve the node information:

> admin.nodeInfo.enode

"enode://c52b3349d899e1f8ea67c2d01df35c3a40532dec41174460b777bab020079e1a546313552b91d5f61adb86ed4e74dd80c0ced70c91d658ef0e4f05969a1cf78e@[::]:30303?discport=0"

Step 9.2 – Update the file “static-nodes.json”

The file “static-nodes.json” created in part 4 has to be updated by adding the information of the node deployed on the RPi.

This file is on your computer under one of the following locations:

  • ~/ChainSkills/miner1
  • ~/ChainSkills/miner2

Based on our environment, we will have the following content (adjust the values according to your environment):

[
"enode://b8863bf7c8bb13c3afc459d5bf6e664ed4200f50b86aebf5c70d205d32dd77cf2a888b8adf4a8e55ab13e8ab5ad7ec93b7027e73ca70f87af5b425197712d272@192.168.1.39:30303",
"enode://41be9d79ebe23b59f21cbaf5b584bec5760d448ff6f57ca65ada89c36e7a05f20d9cfdd091b81464b9c2f0601555c29c3d2d88c9b8ab39b05c0e505dc297ebb7@192.168.1.39:30304",
"enode://c52b3349d899e1f8ea67c2d01df35c3a40532dec41174460b777bab020079e1a546313552b91d5f61adb86ed4e74dd80c0ced70c91d658ef0e4f05969a1cf78e@192.168.1.31:30303"
]

The first two entries are related to miner #1 and miner #2. The last row identified the node deployed on the RPi (with its IP address and port number).

Make sure your IP addresses are still up-to-date as they tend to change on a local network.

This new version of “static-nodes.json” must be stored under the following locations:

  • [miner #1] ~/ChainSkills/miner1
  • [miner #2] ~/ChainSkills/miner2
  • [RPi] ~/ChainSkills/node

You can transfer this file to the RPi using the SFTP command:

computer$ cd ~/ChainSkills/miner1

computer$ sftp pi@192.168.1.31
pi@192.168.1.31's password: 
Connected to 192.168.1.31.

sftp> cd ChainSkills/node

sftp> put static-nodes.json
Uploading static-nodes.json to /home/pi/ChainSkills/node/static-nodes.json
static-nodes.json 100% 480 44.8KB/s 00:00 

sftp> exit

Step 9.3 – Restart your blockchain

Stop and start each node of your blockchain:

  • miner #1
  • miner #2
  • RPi

Step 10 – Check the synchronisation process

Open the Geth console linked to the miner #1:

computer$ geth attach
...
>

Check which nodes is paired to the miner #1:

> admin.peers[{
 caps: ["eth/62", "eth/63"],
 id: "41be9d79ebe23b59f21cbaf5b584bec5760d448ff6f57ca65ada89c36e7a05f20d9cfdd091b81464b9c2f0601555c29c3d2d88c9b8ab39b05c0e505dc297ebb7",
 name: "Geth/miner2/v1.5.5-stable-ff07d548/darwin/go1.7.4",
 network: {
 localAddress: "192.168.1.39:30303",
remoteAddress: "192.168.1.39:63533"
 },
 protocols: {
 eth: {
 difficulty: 892873381,
 head: "0x263550838a2c63ffe70f91a5bf1851dce951d28d90e7863d19805711bac578e3",
 version: 63
 }
 }
}, {
 caps: ["eth/63"],
 id: "c52b3349d899e1f8ea67c2d01df35c3a40532dec41174460b777bab020079e1a546313552b91d5f61adb86ed4e74dd80c0ced70c91d658ef0e4f05969a1cf78e",
 name: "Geth/node1/v1.5.5-stable-ff07d548/linux/go1.7.4",
 network: {
 localAddress: "192.168.1.39:30303",
remoteAddress: "192.168.1.31:50142"
 },
 protocols: {
 eth: {
 difficulty: 891744952,
 head: "0x6ae07a4c2636835445a68d68219e1bb41c04a9519559a9cc899687218c00253d",
 version: 63
 }
 }
}]

We can see that two nodes are paired with the miner #1: miner #2 and the RPi.

You can repeat this process on each node to ensure that they are paired with each other.

Step 11 -Validate the synchronisation

Let’s validate the synchronisation process by sending some ethers between accounts defined on each node (miners and RPi).

Before you proceed, ensure that the mining process is running on both miners.

Step 11.1 – Send ethers from Miner #1 to RPI

We are going to send 10 ethers between the following accounts:

  • miner #1(eth.coinbase) -> RPI(eth.accounts[1])

From the Geth console linked to the RPi, check the initial balance of the account[1] that will receive ethers:

pi$ geth attach 
...
> eth.accounts[1]
"0x6af547b83493fd59bf5a2e67546b65191392f45a"

>  web3.fromWei(eth.getBalance(eth.accounts[1]))
0

The account #1 has 0 ether.

From the Geth console linked to the miner #1, send 10 ethers from the default account to the address of the account[1] created in the RPi:

computer$ geth attach
...
> eth.sendTransaction({from: eth.coinbase, to: "0x6af547b83493fd59bf5a2e67546b65191392f45a", value: web3.toWei(10, "ether")})

From the miner #1 (or the miner #2), check if the recipient has received the ethers:

> web3.fromWei( eth.getBalance("0x6af547b83493fd59bf5a2e67546b65191392f45a"))
10

From the RPI, check that you have the same balance:

> web3.fromWei( eth.getBalance(eth.accounts[1]))
10

Of course, the transaction will be processed ONLY if the mining process is started from at least one miner. 

Step 7.1 – Send ethers from RPI to Miner #2

We are going to send 2 ethers between the following accounts:

  • RPI(eth.accounts[1]) -> miner #2(eth.accounts[1])

From the Geth console linked to the miner #2, check the initial balance of the account that will receive ethers:

computer$ geth attach ipc:/Users/eloudsa/ChainSkills/miner2/geth.ipc
...
> eth.accounts[1]
"0xfa919b49ef34a821fb4cadfdfa5cc6593cb46fe1"

>  web3.fromWei(eth.getBalance(eth.accounts[1]))
7.99958

From the Geth console linked to the RPI, send 2 ethers from the account #1 to the address of the account[1] created on the miner #2:

pi$ geth attach 
...
> eth.sendTransaction({from: eth.accounts[1], to: "0xfa919b49ef34a821fb4cadfdfa5cc6593cb46fe1", value: web3.toWei(2, "ether")})
Error: account is locked
 at web3.js:3119:20
 at web3.js:6023:15
 at web3.js:4995:36
 at <anonymous>:1:1
From the RPi, unlock the account #1 with its password:
> personal.unlockAccount(eth.accounts[1], 'type your password')
true

From the RPi, we are ready to send our transaction:

> eth.sendTransaction({from: eth.accounts[1], to: "0xfa919b49ef34a821fb4cadfdfa5cc6593cb46fe1", value: web3.toWei(2, "ether")})
"0x8324e6534d37e250e9d757d3fe867ef3b741cf1b54daa083bf64a24c25a34978"

From the RPi, check the balance:

> web3.fromWei( eth.getBalance(eth.accounts[1]))
7.99958

From the miner #2, check that the recipient has received the ethers:

> web3.fromWei( eth.getBalance(eth.accounts[1]))
9.99958

Summary

Congratulations! You have synchronised your miners and the RPi.

In part 6, we create and deploy a Smart Contract.

Shameless plug

While you are waiting for the next part of this series, we just wanted to let you know that we are currently preparing a full-blown online training about the development of distributed applications on Ethereum and we are looking for your feedback to figure out what you would like to see in this training. If you want to help us, you can take a few minutes to answer a survey here.

And if you just want us to keep you informed when the full online training program will be available, you can register to our mailing list on beta.chainskills.com.

Pair the miners (4/6)

This tutorial is part of a series of articles introduced here.

In part 3, we configured the miners of our private blockchain.

NB: It is important that what we mean by “private Ethereum blockchain” in this context has absolutely nothing to do with the “private blockchain” championed by Hyperledger, Eris/Monax, or the recently announced Enterprise Ethereum Alliance. These are different codebases with different client applications, so they correspond to different implementations of a different set of concepts. They are private in the sense that they limit who has access to their chain. They are also called permissioned blockchains, and to be perfectly transparent, we wish they were not even called blockchains at all. In this series of articles, what we call “private blockchain” is a private instance of the Ethereum implementation. Same code base, same client application, different network identifier and genesis block. In other words, what we will come to create in this series is a chain with the same rules as the main chain, the same consensus algorithm too, but a different root block. This will become clearer in part 3. For more information about the 3-layer model and differences between concepts, implementations and instances, you can also watch our Devoxx talk and read this article.

We saw that transactions are not propagated from miner #1 to miner #2.

Remember that a blockchain is a peer-to-peer network. This means that our miners need to see each other in order to propagate transactions.

In addition, the discovery protocol is not working on a private blockchain. This means that we have to configure each node to specify the identity and the location of its peers.

This part describes how to pair our miners.

Let’s start by retrieving the node information that uniquely identify each node deployed in the blockchain.

Step 1 Clean your miners

We noticed some issues when we tried to synchronise our miners having several thousand blocks. Sometimes, miners were not able to pair or the synchronization process became too slow.

The easiest way is to reset the chaindata of the private blockchain installed on each miner.

Step 1.1 – Stop miners

First ensure that your miners are stopped.

As a reminder, you can either press ^C on the miner’s console, or search and kill the “geth” process:

computer$ ps aux | grep geth

eloudsa 43872 0.0 2.2 556717632 363492 s001 S+ 3:49PM 1:58.01 geth --identity miner1 --dev

computer$ kill -INT 43872

Step 1.2 – Delete the chaindata

Delete chain data for miners:

computer$ rm -rf ~/ChainSkills/miner1/geth
computer$ rm -rf ~/ChainSkills/miner2/geth

 

 Step 1.3 – Initialize miners

We initialize our miners with the genesis block.

Start with the miner #1:

computer$ cd ~/ChainSkills
computer$ geth --datadir ~/ChainSkills/miner1 init genesis.json

Then the miner #2:

computer$ cd ~/ChainSkills
computer$ geth --datadir ~/ChainSkills/miner2 init genesis.json

Step 2 Get IP address

Get the IP address of your computer running miners.

computer$ ipconfig getifaddr en0
192.168.1.39

Replace the interface according to your network settings:

  • en0: wired/ethernet
  • en1: wireless

Step 3 Get Node info from miner #1

Step 3.1 Node info for miner #1

Let’s start the miner #1:

computer$ cd ~/ChainSkills/miner1

computer$ ./startminer1.sh
...
 Open a second terminal and start the Geth console:
computer$ geth attach
...
>

Stop the mining to avoid generating too much blocks before the synchronisation process:

> miner.stop()
true

Retrieve the node information:

> admin.nodeInfo.enode

"enode://b8863bf7c8bb13c3afc459d5bf6e664ed4200f50b86aebf5c70d205d32dd77cf2a888b8adf4a8e55ab13e8ab5ad7ec93b7027e73ca70f87af5b425197712d272@[::]:30303?discport=0"

Step 3.2 Get Node info from miner #2

Repeat the process to retrieve the node information from the second miner.
Start the miner #2:
computer$ cd ~/ChainSkills/miner2

computer$ ./startminer2.sh
...
 Open a second terminal and start the Geth console:
computer$ geth attach ipc:./miner2/geth.ipc 
...
>

Stop the mining to avoid generating too much blocks before the synchronisation process:

> miner.stop()
true

Retrieve the node information:

> admin.nodeInfo.enode

"enode://41be9d79ebe23b59f21cbaf5b584bec5760d448ff6f57ca65ada89c36e7a05f20d9cfdd091b81464b9c2f0601555c29c3d2d88c9b8ab39b05c0e505dc297ebb7@[::]:30304?discport=0"

Step 4 – Pair the nodes

There are different ways to pair nodes.

Here, we illustrate how to define permanent static nodes stored in a file called “static-nodes.json“. This file will contain the node information of our miners.

Based on our environment, we will have the following content:

[
"enode://b8863bf7c8bb13c3afc459d5bf6e664ed4200f50b86aebf5c70d205d32dd77cf2a888b8adf4a8e55ab13e8ab5ad7ec93b7027e73ca70f87af5b425197712d272@192.168.1.39:30303",
"enode://41be9d79ebe23b59f21cbaf5b584bec5760d448ff6f57ca65ada89c36e7a05f20d9cfdd091b81464b9c2f0601555c29c3d2d88c9b8ab39b05c0e505dc297ebb7@192.168.1.39:30304"
]

You will notice that we have replaced the placeholder [::] with the IP address of our computer. The last part (?discport=0) has been removed.

Each node information is separated by a comma character.

Based on our example, the file “static-nodes.json” must be stored under the following location:

  • ~/ChainSkills/miner1
  • ~/ChainSkills/miner2

When the miner starts, the Geth process will process the file automatically.

Step 5 – Restart your miners

Stop and start the miners to ensure that they will properly reload the “static-nodes.json” file.

If you check the console of your miners, you should see a line mentioning the synchronisation process (“Block synchronisation started”):

...
I1219 01:12:03.223537 eth/downloader/downloader.go:326] Block synchronisation started
...

Step 6 – Check the synchronisation process

We check if the miners are properly paired.

Step 6.1 – Check from miner #1

Open the Geth console linked to the miner #1:

computer$ geth attach
...
>

Check which nodes are paired to miner #1:

> admin.peers
[{
 caps: ["eth/62", "eth/63"],
 id: "41be9d79ebe23b59f21cbaf5b584bec5760d448ff6f57ca65ada89c36e7a05f20d9cfdd091b81464b9c2f0601555c29c3d2d88c9b8ab39b05c0e505dc297ebb7",
 name: "Geth/miner2/v1.5.5-stable-ff07d548/darwin/go1.7.4",
 network: {
 localAddress: "192.168.1.39:59153",
remoteAddress: "192.168.1.39:30304"
 },
 protocols: {
 eth: {
 difficulty: 96831214,
 head: "0x0f8a3318a47429aee7a442cd1c3258eab7427b7fa1cb3c2a3e4bdf70ed6d8cf8",
 version: 63
 }
 }
}]

We can see that our node is paired to miner #2 identified by its IP address and its port number (30304).

Step 6.2 – Check from miner #2

Open the Geth console linked to the miner #2:

computer$ geth attach ipc:./miner2/geth.ipc 
...
>

Check which nodes are paired to miner #2:

> admin.peers
[{
 caps: ["eth/62", "eth/63"],
 id: "b8863bf7c8bb13c3afc459d5bf6e664ed4200f50b86aebf5c70d205d32dd77cf2a888b8adf4a8e55ab13e8ab5ad7ec93b7027e73ca70f87af5b425197712d272",
 name: "Geth/miner1/v1.5.5-stable-ff07d548/darwin/go1.7.4",
 network: {
 localAddress: "192.168.1.39:30304",
 remoteAddress: "192.168.1.39:59153"
 },
 protocols: {
 eth: {
 difficulty: 88045328,
 head: "0xa084d0c7f1a18120780c44bd4ba6c3ec237eb3feb0912bffd74ac1030246a723",
 version: 63
 }
 }
}]

We can see that our node is paired to miner #1 identified by its IP address and its port number (59153).

Step 7 -Validate the synchronisation

Let’s validate the synchronisation process by sending some ethers between accounts defined on each miner.

We are going to send 10 ethers between the following accounts:

  • miner #1(eth.coinbase) -> miner #2(eth.accounts[1])

eth.coinbase is the default account that receive the rewards for the mining process. In the miner #1, eth.coinbase is the same as eth.accounts[0].

First, make sure that the mining process is running on both miners.

Step 7.1 – Send ethers from Miner #1 to Miner #2

Start a Geth console linked to the miner #2, retrieve the address of the account[1] and check its initial balance:

computer$ geth attach ipc:./miner2/geth.ipc 
...
> eth.accounts[1]
"0xfa919b49ef34a821fb4cadfdfa5cc6593cb46fe1"

>  web3.fromWei(eth.getBalance(eth.accounts[1]))
0

The account #1 has no ether.

From the Geth console linked to the miner #1, send 10 ethers from the default account to the address of the account[1]:

computer$ geth attach
...
> eth.sendTransaction({from: eth.coinbase, to: "0xfa919b49ef34a821fb4cadfdfa5cc6593cb46fe1", value: web3.toWei(10, "ether")})

From the miner #1, check if the recipient has received the ethers:

> web3.fromWei( eth.getBalance("0xfa919b49ef34a821fb4cadfdfa5cc6593cb46fe1"))
10

From the miner #2, check that you have the same balance:

> web3.fromWei( eth.getBalance(eth.accounts[1]))
10

Step 7.2 – Send ethers from Miner #2 to Miner #1

We are going to send 2 ethers between the following accounts:

  • miner #2(eth.accounts[1]) -> miner #1(eth.accounts[1])

From the Geth console linked to the miner #1, check the initial balance of the account that will receive ethers:

computer$ geth attach 
...
> eth.accounts[1]
"0xae3ab39b3ebc425289dad620aece197a4a3f8940"

>  web3.fromWei(eth.getBalance(eth.accounts[1]))
0

The account #1 has 0 ether.

From the Geth console linked to the miner #2, send 2 ethers from the account #1:

computer$ geth attach ipc:./miner2/geth.ipc 
...
> eth.sendTransaction({from: eth.accounts[1], to: "0xae3ab39b3ebc425289dad620aece197a4a3f8940", value: web3.toWei(2, "ether")})

Error: account is locked
 at web3.js:3119:20
 at web3.js:6023:15
 at web3.js:4995:36
 at <anonymous>:1:1
Oops! We cannot send the transaction because the account #1 is locked.
To send transactions from an account, Ethereum requires that you unlock this account. The coinbase account is unlocked by our startminer.sh script thanks to the password file. But all other accounts are locked.
From the miner #2, unlock the account #1 with its password:
> personal.unlockAccount(eth.accounts[1], 'type your password')
true

From the miner #2, we are ready to send our transaction:

> eth.sendTransaction({from: eth.accounts[1], to: "0xae3ab39b3ebc425289dad620aece197a4a3f8940", value: web3.toWei(2, "ether")})
"0x02b1c360e3b094e8c7faac3d3f8def8eec6350a3d68a1b7e071827d1026221f0"

From the miner #2, check that our balance has changed (2 ethers plus some transaction fees):

> web3.fromWei( eth.getBalance(eth.accounts[1]))
7.99958

From the miner #1, check that the recipient has received the ethers:

> web3.fromWei( eth.getBalance(eth.accounts[1]))
2

Summary

Congratulations! You have synchronised your miners.

In part 5, we will synchronise the RPi node with these miners.

Shameless plug

While you are waiting for the next part of this series, we just wanted to let you know that we are currently preparing a full-blown online training about the development of distributed applications on Ethereum and we are looking for your feedback to figure out what you would like to see in this training. If you want to help us, you can take a few minutes to answer a survey here.

And if you just want us to keep you informed when the full online training program will be available, you can register to our mailing list on beta.chainskills.com.

Set up the private chain – miners (3/6)

This tutorial is part of a series of articles introduced here.

Part 2 described how to install Ethereum on your computer.

Our development environment requires the setup of a private Ethereum chain.

NB: It is important that what we mean by “private Ethereum blockchain” in this context has absolutely nothing to do with the “private blockchain” championed by Hyperledger, Eris/Monax, or the recently announced Enterprise Ethereum Alliance. These are different codebases with different client applications, so they correspond to different implementations of a different set of concepts. They are private in the sense that they limit who has access to their chain. They are also called permissioned blockchains, and to be perfectly transparent, we wish they were not even called blockchains at all. In this series of articles, what we call “private blockchain” is a private instance of the Ethereum implementation. Same code base, same client application, different network identifier and genesis block. In other words, what we will come to create in this series is a chain with the same rules as the main chain, the same consensus algorithm too, but a different root block. This will become clearer in part 3. For more information about the 3-layer model and differences between concepts, implementations and instances, you can also watch our Devoxx talk and read this article.

Our private chain needs miners in order to validate and propagate blocks of transactions within the blockchain. Miners will also be used to generate ether to pay for the gas required to process transactions on the Ethereum blockchain. Note that this ether will only be usable within our private blockchain.

Unfortunately, the Raspberry pi is not powerful enough to be used as a miner. The mining process is just too intense. This is why we will deploy at least two miners on our computer.

Why two miners and not only one?

At the time of writing this tutorial, Geth has an issue when it is deployed in a private chain. If you have only one miner, some transactions will not be processed and will remain pending. Having two miners solves this issue (check here for more information about the issue). By the way, two miners make sense to apply the notion of consensus within the blockchain.

Let’s start by describing how to create the first miner.

Introduction

Before we describe the steps to start the miners, it is important to understand the requirements for each node to join the same private blockchain:

  • Each node will use a distinct data directory to store the database and the wallet.
  • Each node must initialize a blockchain based on the same genesis file.
  • Each node must join the same network id different from the one reserved by Ethereum (0 to 3 are already reserved).
  • The port numbers must be different if different nodes are installed on the same computer.

All the operations must be performed from your computer.

Step 1 – Create the datadir folder

When running a private blockchain, it is highly recommended to use a specific folder to store the data (database and wallet) of the private blockchain without impacting the folders used to store the data coming from the public blockchain.

From your computer, create the folder that will host your first miner:

computer$ mkdir -p ~/ChainSkills/miner1

Repeat the operation for the second miner:

computer$ mkdir -p ~/ChainSkills/miner2

Step 2 – Create the Genesis file

Each blockchain starts with a genesis block that is used to initialize the blockchain and defines the terms and conditions to join the network.

Our genesis block is called “genesis.json” and is stored under “~/ChainSkills” folder.

Create a text file under ~/ChainSkills, called genesis.json, with the following content:

{
 "nonce": "0x0000000000000042",
 "mixhash": "0x0000000000000000000000000000000000000000000000000000000000000000",
 "difficulty": "0x400",
 "alloc": {}, 
 "coinbase": "0x0000000000000000000000000000000000000000",
 "timestamp": "0x00",
 "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
 "extraData": "ChainSkills Genesis Block",
 "gasLimit": "0xffffffff"
 "config": {
    "chainId": 42,
    "homesteadBlock": 0,
    "eip155Block": 0,
    "eip158Block": 0
 }
}

Update (24-May-2017):  Since Geth 1.6, the genesis.json file has to provide a section “config” identifying the network id (chainId) of your private network. Based on our tutorial, we will use the network Id “42”.

Among the parameters, we have the following ones:

  • difficulty: if the value is low, the transactions will be quickly processed within our private blockchain.
  • gasLimit: define the limit of Gas expenditure per block. The gasLimit is set to the maximum to avoid being limited to our tests.

Step 3 – Initialize the private blockchain

It’s time to initialize the private blockchain with the genesis block.
This operation will create the initial database stored under the data directory dedicated to each miner.

Step 3.1 – Initialize miner #1

Type the following command to create the blockchain for the first miner:
computer$ cd ~/ChainSkills
computer$ geth --datadir ~/ChainSkills/miner1 init genesis.json

I1226 00:44:16.572007 cmd/utils/flags.go:615] WARNING: No etherbase set and no accounts found as default
...
I1226 00:44:16.604262 cmd/geth/chaincmd.go:131] successfully wrote genesis block and/or chain rule set: 6e92f8b23bcdfdf34dc813cfaf1d84b71beac80530506b5d63a2df10fe23a660
The logs provide the following information:
  • you need a default account
  • the blockchain has been successfully created

If you list the content of the miner1 folder, you will notice the following subfolders:

  • geth: contains the database of your private blockchain (chaindata).
  • keystore: location of your wallet used to store the accounts that you will create on this node.

Step 3.2 – Initialize miner #2

Repeat the same operation to initialize the second miner by specifying its own target folder (~/ChainSkills/miner2):
computer$ cd ~/ChainSkills
computer$ geth --datadir ~/ChainSkills/miner2 init genesis.json

I1226 00:47:14.867704 cmd/utils/flags.go:615] WARNING: No etherbase set and no accounts found as default
...
I1226 00:47:14.890635 cmd/geth/chaincmd.go:131] successfully wrote genesis block and/or chain rule set: 6e92f8b23bcdfdf34dc813cfaf1d84b71beac80530506b5d63a2df10fe23a660

Step 4 – Create accounts

Let’s create some accounts for our miners.

Step 4.1 – Accounts for miner #1

Create the default account that will be used to run the node.

This account will receive all ethers created by the miner in the private blockchain. These ethers will serve to test our solutions by paying the gas required to process each transaction.

To create the default account for the miner #1, type the following command. Keep the password in a safe place:

computer$ geth --datadir ~/ChainSkills/miner1 account new
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase: 
Repeat passphrase: 
Address: {3e3753727dd6d965c0c696ea5619b8050ca89a49}
Add an additional account for testing purpose:
computer$ geth --datadir ~/ChainSkills/miner1 account new 
Your new account is locked with a password. Please give a password. Do not forget this password. 
Passphrase: 
Repeat passphrase: 
Address: {ae3ab39b3ebc425289dad620aece197a4a3f8940}
The wallet for these accounts is located right here:
computer$ ls -al ~/ChainSkills/miner1/keystore 
-rw------- 1 eloudsa staff 491 Dec 26 00:55 UTC--2016-12-25T23-55-58.526082355Z--3e3753727dd6d965c0c696ea5619b8050ca89a49
-rw------- 1 eloudsa staff 491 Dec 29 17:53 UTC--2016-12-29T16-53-48.822735465Z--ae3ab39b3ebc425289dad620aece197a4a3f8940
To list all accounts of your node, use the following command:
computer$ geth --datadir ~/ChainSkills/miner1 account list

Account #0: {3e3753727dd6d965c0c696ea5619b8050ca89a49} /Users/eloudsa/ChainSkills/miner1/keystore/UTC--2016-12-25T23-55-58.526082355Z--3e3753727dd6d965c0c696ea5619b8050ca89a49

Account #1: {ae3ab39b3ebc425289dad620aece197a4a3f8940} /Users/eloudsa/ChainSkills/miner1/keystore/UTC--2016-12-29T16-53-48.822735465Z--ae3ab39b3ebc425289dad620aece197a4a3f8940

Step 4.2 – Accounts for miner #2

Repeat the same operation to create the default account for the second miner. The difference lies in the target folder (~/ChainSkills/miner2).

The default account of miner #2:

computer$ geth --datadir ~/ChainSkills/miner2 account new 
Your new account is locked with a password. Please give a password. Do not forget this password. 
Passphrase: 
Repeat passphrase: 
Address: {22b2f81b46146aa3e1036fd3dc5cbcf12551b2db}

An additional account of miner #2:

computer$ geth --datadir ~/ChainSkills/miner2 account new 
Your new account is locked with a password. Please give a password. Do not forget this password. 
Passphrase: 
Repeat passphrase: 
Address: {fa919b49ef34a821fb4cadfdfa5cc6593cb46fe1}
To list all accounts of your node, use the following command:
computer$ geth --datadir ~/ChainSkills/miner2 account list

Account #0: {22b2f81b46146aa3e1036fd3dc5cbcf12551b2db} /Users/eloudsa/ChainSkills/miner2/keystore/UTC--2016-12-26T00-00-12.726226915Z--22b2f81b46146aa3e1036fd3dc5cbcf12551b2db

Account #1: {fa919b49ef34a821fb4cadfdfa5cc6593cb46fe1} /Users/eloudsa/ChainSkills/miner2/keystore/UTC--2016-12-29T16-59-28.053461367Z--fa919b49ef34a821fb4cadfdfa5cc6593cb46fe1

Step 5 – Prepare the miners

We are ready to start the miners from our computer and to mine some ethers that will reward our default accounts.

Step 5.1 – Miner #1: setup

Let’s start by creating a file that will contain the password for our default account, which is the first account we created for each miner. Create a password.sec file under ~/ChainSkills/miner1/ that contains the password you configured for the first account on miner1, in plain text.
To start the miner #1, we will require to run the following command:
computer$ geth --identity "miner1" --networkid 42 --datadir "~/ChainSkills/miner1" --nodiscover --mine --rpc --rpcport "8042" --port "30303" --unlock 0 --password ~/ChainSkills/miner1/password.sec --ipcpath "~/Library/Ethereum/geth.ipc"

The meaning of the main parameters is the following:

  • identity: name of our node
  • networkid: this network identifier is an arbitrary value that will be used to pair all nodes of the same network. This value must be different from 0 to 3 (already used by the live chains)
  • datadir: folder where our private blockchain stores its data
  • rpc and rpcport: enabling HTTP-RPC server and giving its listening port number
  • port: network listening port number, on which nodes connect to one another to spread new transactions and blocks
  • nodiscover: disable the discovery mechanism (we will pair our nodes later)
  • mine: mine ethers and transactions
  • unlock: id of the default account
  • password: path to the file containing the password of the default account
  • ipcpath: path where to store the filename for IPC socket/pipe
You can find more information about Geth parameters right here.
We recommend that you store the Geth command into a runnable script. In our example, this script is called “startminer1.sh” and is located here: ~/ChainSkills/miner1
#!/bin/bash

geth --identity "miner1" --networkid 42 --datadir "~/ChainSkills/miner1" --nodiscover --mine --rpc --rpcport "8042" --port "30303" --unlock 0 --password ~/ChainSkills/miner1/password.sec --ipcpath "~/Library/Ethereum/geth.ipc"
What’s the meaning of the parameter “ipcpath“?
If you want to manage your private blockchain via the Mist browser, you will need to create the “geth.ipc” file in the default Ethereum folder. Mist will detect that your private network is running and will connect to it rather than starting its own instance of Geth.

 Step 5.2 – Miner #1: start

Make the script runnable:

computer$ cd ~/ChainSkills/miner1 

computer$ chmod +x startminer1.sh

Let’s start the miner #1:

computer$ ./startminer1.sh
...
You will notice that the server and the mining process start.
You default account will receive ethers mined by the node.
If you start Mist, you will see that the default account is rewarded by ethers.
Remember that these ethers are fake money only available in your private blockchain and not on the live main chain. So, you are not (yet) rich 😉

Step 5.3 – Miner #1: JavaScript console

You can manage your miner using the Geth Javascript console.
For example, you can start and stop mining from the console or send transactions.
This console needs to be attached to a running instance of Geth.
Open a new terminal session and type “geth attach“.
If you want to start or stop the mining process, proceed as below:
computer$ geth attach
...
> miner.start()
...
> miner.stop()
...
You will notice that “geth attach” didn’t need any additional parameters. The reason is that the “geth.ipc” file is generated into the Ethereum default directory.
More commands for the JavaScript console are described right there.
To quit the attached console, simply use the exit command.

Step 5.4 – Miner #1: stop

To stop your miner, go to its console window and press CTRL-C.

Another option is to kill the Geth running process as illustrated here below:

computer$ ps aux | grep geth

eloudsa 43872 0.0 2.2 556717632 363492 s001 S+ 3:49PM 1:58.01 geth --identity miner1 --dev

computer$ kill -INT 43872

Thanks to the identity parameter, we are able to easily identify the miner instance we want to stop.

Now let’s continue with the second miner.

Step 5.5 – Miner #2: setup

To prepare the second miner, the instructions are similar to those described for the miner #1 with some minor changes.
First, create the “password.sec” file under ~/ChainSkills/miner2 that will contain the password of the default account of your miner #2:
Create the script “startminer2.sh“that will be stored at the following location: ~/ChainSkills/miner2
#!/bin/bash

geth --identity "miner2" --networkid 42 --datadir "~/ChainSkills/miner2" --nodiscover --mine --rpc --rpcport "8043" --port "30304" --unlock 0 --password ~/ChainSkills/miner2/password.sec
The difference from the first miner is about the following parameters:
  • identity: a specific name used to identify our miner
  • datadir: the folder related to the second miner
  • rpcport: a specific HTTP-RPC port number used to reach the miner #2
  • port: a specific network port number used to reach the miner #2
  • password: path of the file containing the password of the default account on the miner #2
You will notice that we have the same networkid (42). This will be useful later.
We are not providing the “ipcpath” parameter. This means that the “geth.ipc” will be created in the data directory of the miner.

Let’s start the miner #2:

computer$ cd ~/ChainSkills/miner2

computer$ chmod +x startminer2.sh

computer$ ./startminer2.sh
...

Step 5.6 – Miner #2: JavaScript console

As for miner #1, we can manage our node through the JavaScript console.
Unlike miner #1, we will have to attach the console to the running instance of Geth because its “geth.ipc” file has been generated in the “datadir” folder and not in the default Ethereum folder.
To attach the console, you can attach it by mentioning the path to the IPC-RPC interface (geth.ipc):
computer$ cd ~/ChainSkills

computer$ geth attach ipc:./miner2/geth.ipc
Another option is to attach the console to the HTTP-RPC interface:
computer$ geth attach http://127.0.0.1:8043
...

Be aware that these commands may have some limitations such as starting or stopping the mining process:

computer $ geth attach http://127.0.0.1:8043
Welcome to the Geth JavaScript console!

instance: Geth/miner2/v1.5.5-stable-ff07d548/darwin/go1.7.4
coinbase: 0x22b2f81b46146aa3e1036fd3dc5cbcf12551b2db
at block: 1294 (Sat, 31 Dec 2016 16:08:22 CET)
 modules: eth:1.0 net:1.0 rpc:1.0 web3:1.0

> miner.stop()
ReferenceError: 'miner' is not defined
 at <anonymous>:1:1

First, you can see that the “miner” module is not specified in the list of modules: eth:1.0 net:1.0 rpc:1.0 web3:1.0

This is the reason why we have an error when we try to stop the mining process.

The following command is more useful:

computer $ geth attach ipc:./miner2/geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/miner2/v1.5.5-stable-ff07d548/darwin/go1.7.4
coinbase: 0x22b2f81b46146aa3e1036fd3dc5cbcf12551b2db
at block: 1417 (Sat, 31 Dec 2016 16:12:25 CET)
 datadir: /Users/eloudsa/ChainSkills/miner2
 modules: admin:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0

> miner.stop()
true

Here the miner can be managed through the console because the miner module is available from the IPC interface.

Keep this in mind if you have any trouble running a command from the Geth console.

Of course, you can define the modules available for the Geth console by mentioning them from the command line (ipcapi and rpcapi parameters).

For example, let’s change the Geth command by mentioning the “miner” module:

#!/bin/bash

geth --identity "miner2" --dev --networkid 42 --datadir "~/ChainSkills/miner2" --nodiscover --mine --rpc --rpcport "8043" --rpcapi "db,eth,net,web3,miner" --port "30304" --unlock 0 --password ~/ChainSkills/miner2/password.sec

Start the miner and open the console with the following command:

computer $ geth attach http://127.0.0.1:8043
Welcome to the Geth JavaScript console!

instance: Geth/miner2/v1.5.5-stable-ff07d548/darwin/go1.7.4
coinbase: 0x22b2f81b46146aa3e1036fd3dc5cbcf12551b2db
at block: 1473 (Sat, 31 Dec 2016 16:21:22 CET)
 modules: eth:1.0 miner:1.0 net:1.0 rpc:1.0 web3:1.0

Now the miner module is available from the Geth console!

You can manage the mining process:

> miner.stop()

true

This shows that by changing the Geth command, you can allow or restrict the usage of some APIs available from the HTTP-RPC or IPC-RPC interfaces.

Step 5.7 – Miner #2: stop

The principle is the same as described for the miner #1.

Step 6 – Send ethers within miner #1

To ensure that our mining node is properly installed, let’s try to send some ethers between accounts created on each miner.

Step 6.1 – Start the miner and its console

Let’s begin to start the miner #1:
computer$ cd ~/ChainSkills/miner1

computer$ ./startminer1.sh
...
 Open a second terminal and start the Geth console:
computer$ geth attach
...
>

Step 6.2 – Check balances

Get the default account with “eth.coinbase”:
> eth.coinbase
"0x3e3753727dd6d965c0c696ea5619b8050ca89a49"
List the accounts with “eth.accounts”:
> eth.accounts
["0x3e3753727dd6d965c0c696ea5619b8050ca89a49", "0xae3ab39b3ebc425289dad620aece197a4a3f8940"]
Of course, you will find addresses related to your environment.
Check balances with “eth.getBalance(<account id>)”:
> eth.getBalance(eth.coinbase)
2.48859375e+21

> eth.getBalance(eth.accounts[1])
0
The default account has plenty of ethers obtained during the mining process. We will use them to test our solutions.
Use the following command to get the balance in ether:
> web3.fromWei(eth.getBalance(eth.coinbase))
3008.125
By default, the balance is expressed in Wei that is the base unit of ether.

Step 6.3 – Stop mining

We stop the mining process to let us review the content of a transaction:

> miner.stop()
true

Step 6.4 – Send ethers

Through the Geth console, we send 10 ethers from account #0 to account #1:

> eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], value: web3.toWei(10, "ether")})
"0x4ed5ef14cb5df5069059ac201a7294d810b89dcc05c0f60f970b87bff7faa5b6"
The command returns a transaction hash.
As the mining process has been stopped, we can review the list of pending transactions:
> eth.pendingTransactions
[{
 blockHash: null,
 blockNumber: null,
 from: "0x3e3753727dd6d965c0c696ea5619b8050ca89a49",
 gas: 90000,
 gasPrice: 20000000000,
 hash: "0x4ed5ef14cb5df5069059ac201a7294d810b89dcc05c0f60f970b87bff7faa5b6",
 input: "0x",
 nonce: 0,
 r: "0xdfd5465e315207e41d10a01189c41a1e9b42e7577cd256a100b3fa2157e9b0",
 s: "0x39b10c973c1e9764e9b3cfd98339164d65e78971c917ae24fe880a2a7c775cf6",
 to: "0xae3ab39b3ebc425289dad620aece197a4a3f8940",
 transactionIndex: null,
 v: "0x1c",
 value: 10000000000000000000
}]
We can easily identify the following information:
  • The sender address
  • The recipient address
  • The value to transfer (expressed in Wei)
  • The hash of the transaction
  • The cost of the transaction (gas x gasPrice) in Wei

Let the miner process the transaction:

> miner.start()
true

The transaction is processed:

> eth.pendingTransactions
[]

Check the balance of the recipient:

> web3.fromWei( eth.getBalance(eth.accounts[1]))

10

The recipient address has received 10 ethers.

Congratulations your miner # 1 is properly installed!
Let’s do the same for miner #2.

Step 7 – Send ethers within miner #2

Test your miner #2 by following the steps described for miner #1.
Keep in mind that the Geth console will have to be started using one of the following commands (change the port id according to your settings):
computer$ geth attach ipc:/Users/eloudsa/ChainSkills/miner2/geth.ipc

OR

computer$ geth attach http://127.0.0.1:8043

Step 8 – Send ethers between nodes of the private blockchain

Now, let’s try to send ethers between accounts of our miners.

We will send 5 ethers from the default account of the miner #1 to the account #1 of the miner #2.

Step 8.1 – Start miners

First, start both miners (miner #1 and miner #2).

Step 8.2 – Check balance from miner #2

From the Geth console attached to the miner 2, check the initial balance of the account 1:

> web3.fromWei(eth.getBalance(eth.accounts[1]))
10

Step 8.3 – Send Ethers from miner #1

From the console of the first miner, send 5 ethers from the default account (eth.coinbase) to the address of the account 1 in miner #2:

> eth.sendTransaction({from: eth.coinbase, to: '[REPLACE WITH ADDRESS OF ACCOUNT 1 IN MINER #2]', value: web3.toWei(5, "ether")})
"0x866db90bade948dbec0679b0a673807a74d6b3d94b3a7616dd86d72eb8a72e9b"

Step 8.4 – Check balance from miner #1

Check the balance from the Geth console attached to the miner #1:

> web3.fromWei( eth.getBalance("[REPLACE WITH ADDRESS OF ACCOUNT 1 IN MINER #2]"))
5

We have 5 ethers while we should expect 15 ethers.

Step 8.5 – Check balance from miner #2

Check the balance from the Geth console attached to the miner #2:

> web3.fromWei( eth.getBalance(eth.accounts[1]))
10

We have 10 ethers while we should expect 15 ethers.

Why?

Because our miners are not connected to the same blockchain.

Each miner is running its own version of the private blockchain. The transactions are not distributed within the same private blockchain.

To synchronise the blockchain, we have to pair the nodes with each other.

Summary

We have installed our miners but they are not synchronised with each other.

We will do that in Part 4 (what a teaser, man!).

 

Install an Ethereum node on a computer (2/6)

This tutorial is part of a series of articles introduced here.

In part 1, we have installed Ethereum on the RPi.

In this tutorial, we will describe the steps to install Ethereum on your computer.

Installing Geth on a computer is quite straightforward. The installation instructions are available for different target platforms, including Linux, Windows and Mac. You can find them right here.

Here below, we describe all the steps to set up Geth on a Mac, as it is the most common configuration amongst developers.

NB: It is important that what we mean by “private Ethereum blockchain” in this context has absolutely nothing to do with the “private blockchain” championed by Hyperledger, Eris/Monax, or the recently announced Enterprise Ethereum Alliance. These are different codebases with different client applications, so they correspond to different implementations of a different set of concepts. They are private in the sense that they limit who has access to their chain. They are also called permissioned blockchains, and to be perfectly transparent, we wish they were not even called blockchains at all. In this series of articles, what we call “private blockchain” is a private instance of the Ethereum implementation. Same code base, same client application, different network identifier and genesis block. In other words, what we will come to create in this series is a chain with the same rules as the main chain, the same consensus algorithm too, but a different root block. This will become clearer in part 3. For more information about the 3-layer model and differences between concepts, implementations and instances, you can also watch our Devoxx talk and read this article.

Step 1 – Homebrew

Homebrew is a package manager that you should install on your computer:

computer$ brew --version

If Homebrew is not installed on your computer, install it using the following command:

computer$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Step 2 – Install Geth

In this step, we install the Go implementation of Ethereum protocol (Geth).

Geth can be installed with the following commands:

computer$ brew update
computer$ brew tap ethereum/ethereum
computer$ brew install ethereum

Check the version of Geth using:

computer$ geth version
Geth
Version: 1.5.7-stable
Git Commit: da2a22c384a9b621ec853fe4b1aa651d606cf42b
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.7.5
OS: darwin
GOPATH=
GOROOT=/usr/local/Cellar/go/1.7.5/libexec

Ensure that the version of Geth is the same as the one installed on your RPi. If not, upgrade your nodes.

Step 2.1 – Update Geth

If Geth was already installed on your computer, update it to the latest version:

computer$ brew update
computer$ brew upgrade ethereum

If you have trouble to update Geth, use the following commands to force the update:

computer$ brew tap ethereum/ethereum
computer$ brew unlink ethereum
computer$ brew install ethereum

Check the version of Geth:

computer$ geth version
Geth
Version: 1.5.7-stable
Git Commit: da2a22c384a9b621ec853fe4b1aa651d606cf42b
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.7.5
OS: darwin
GOPATH=
GOROOT=/usr/local/Cellar/go/1.7.5/libexec

Step 3 – Run Geth

Start Geth using the following command:

computer$ geth
I1217 19:38:35.080348 ethdb/database.go:83] Allotted 128MB cache and 1024 file handles to /Users/eloudsa/Library/Ethereum/chaindata
...
I1217 19:38:35.492125 p2p/server.go:342] Starting Server
...
I1217 19:38:47.719187 eth/downloader/downloader.go:326] Block synchronisation started
...

When you start Geth like that, without any command line argument, it immediately starts synchronizing with the main chain, which takes several days.

Press CTRL-C to stop the Ethereum server.

Summary

At this stage, Ethereum is installed on your computer and able to synchronise with the live chain (mainnet).

The blockchain (chaindata) is located right here:

  • Mac: ~/Library/Ethereum/chaindata
  • Windows: %APPDATA%\Ethereum
  • Linux: ~/.ethereum

Your accounts will be stored in a wallet located in this folder:

  • Mac: ~/Library/Ethereum/chaindata/keystore
  • Windows: %APPDATA%\Ethereum\keystore
  • Linux: ~/.ethereum/keystore

Congratulations! Your computer is an Ethereum node.

Part 3 describes how to setup a private chain and a miner node.

Create a private Ethereum blockchain with IoT devices (1/6)

Introduction

This series of tutorials will describe how to set up a private Ethereum blockchain that will be composed of a computer (miner) and one or several Raspberry PI 3 devices (nodes).

The objective is to build a development environment to learn about blockchain principles, to develop and test your own smart contracts before releasing them to the live chain (mainnet).

To make this project fun, we will integrate a RPi with a Smart Contract deployed on a private chain. The Smart Contract will be used to check if a user has enough tokens to use a service. The RPi will be used to visualize the status of the contract.

NB: It is important that what we mean by “private Ethereum blockchain” in this context has absolutely nothing to do with the “private blockchain” championed by Hyperledger, Eris/Monax, or the recently announced Enterprise Ethereum Alliance. These are different codebases with different client applications, so they correspond to different implementations of a different set of concepts. They are private in the sense that they limit who has access to their chain. They are also called permissioned blockchains, and to be perfectly transparent, we wish they were not even called blockchains at all. In this series of articles, what we call “private blockchain” is a private instance of the Ethereum implementation. Same code base, same client application, different network identifier and genesis block. In other words, what we will come to create in this series is a chain with the same rules as the main chain, the same consensus algorithm too, but a different root block. This will become clearer in part 3. For more information about the 3-layer model and differences between concepts, implementations and instances, you can also watch our Devoxx talk and read this article.

Conventions

We will use the following naming conventions to identify the devices on which the commands are entered:

computer$ A computer requires to perform initial configuration

pi$ Shell of the node running on the Raspberry PI device

Disclaimer

This series of tutorials doesn’t pretend to be comprehensive neither to give you a full introduction to Ethereum.

There are many ways to set up a private Ethereum blockchain from the most simplistic to the most complicated.

Here are some other examples:

  • Microsoft Azure and RPi  (here)
  • Docker image (here)
  • Pre-defined images such with EthRaspian (here)

Part 1: Install an Ethereum node on a Raspberry PI (RPi)

In this first part, we will describe the steps to transform your Raspberry PI 3 (RPi) into an Ethereum node.

The RPi is intended to act as a node connected to our private Ethereum blockchain. This means that it’s not required to install a full flesh operating system. A minimal image of Raspbian is good enough.

For information, there are pre-bundled RPi images that make it possible for you to transform your RPi into an Ethereum node.

One of these images is provided by the project EthRaspbian.

Here, we chose to build our Ethereum node without these prepared images. The objective is to show you all the required steps to do it from scratch.

Due to hardware limitations (CPU, memory), your RPi will not be able to mine ethers or to build new blocks of transactions.

Step 1 – Check your configuration

We will use a Raspberry PI 3 with a microSD of 16 Gb and a computer to prepare the microSD card.

The setup of the RPi will require the following hardware:

  • A Raspberry Pi
  • An SD Card with at least 16Gb
  • A LAN cable
  • A keyboard
  • A display

Step 2 – Format your SD Card

Insert your SD card on your computer and format it as FAT32.

On macOS, use the format ExFat in Disk Utility:

Step 3 – Write the Raspbian image

From your computer, download the Raspbian Jessie Lite image (minimal image) available here.

Unzip the file.

Write the image on the SD card by following instructions there. The process varies slightly depending on whether you are on a MacOS, Linux or Windows machine.

Here is an example for macOS (be very careful with the commands, every character matters):

computer$ diskutil list
...
/dev/disk5 (external, physical):
...

computer$ diskutil unmountDisk /dev/disk5

computer$ sudo dd bs=1m if=2016-11-25-raspbian-jessie-lite.img of=/dev/rdisk5

computer$ diskutil eject /dev/disk5

Ensure that your RPi is powered off.

Insert the SD card on you RPi and power on the device. Your RPi will boot the image.

Step 4 – Configure your RPi

Log in the RPi with the default credential is:

  • username: pi
  • password: raspberry

The RPi needs to be configured:

  • Change the keyboard layout (if required)
  • Set the timezone: required to allow a blockchain synchronisation between nodes
  • Enable SSH: securely access your RPi from your computer
  • Change your hostname: easily identified your RPi within your network (example: node1, node2, etc.)

We use raspi-config to setup all these settings:

pi$ sudo raspi-config

1) Timezone can be changed from the option "Internationalisation Options" and "Change Timezone".

2) Keyboard layout can be changed from the option "Internationalisation Options" and "Change Keyboard Layout". 

3) SSH can be enabled from the option "Advanced Options" then "SSH". 

4) The hostname can be changed from the option "Advanced Options" and then "Hostname. In our tutorial, we use the hostname "ethpinode1"

Press Finish and reboot your RPi:

p$> sudo reboot

Finally, you should really change the default password of the pi account:

pi$ passwd

Step 5 – Setup Wi-Fi

To setup your Wi-Fi interface, proceed as described below:

pi$ sudo nano /etc/wpa_supplicant/wpa_supplicant.conf
  1. Change the country code to set yours
  2. Add the following lines at the end of the file and replace the ssid with the name of your WiFi and psk with your WiFi’s password:
network={
 ssid="enter the SSID of your Wi-Fi network"
 psk="enter the password of your Wi-Fi network"
}

To apply your changes, restart your RPi or your Wi-Fi interface:

pi$ sudo ifdown wlan0
pi$ sudo ifup wlan0

You can now unplug  your LAN cable.

Step 6 – Connect to your RPI

To connect remotely to your RPi through SSH, you have to know the IP address of your RPi device.

You can find it by typing the following command from your RPi:

pi$ ifconfig

Or you can search it from your LAN by filtering IP adresses from a MAC  prefix address (b8:27:eb is the MAC prefix address of RPi devices):

computer$ arp -na | grep -i b8:27:eb
? (192.168.1.31) at b8:27:eb:1c:aa:94 on en0 ifscope [ethernet]


If you have several RPi, you can locate them using the “host” command:

computer$ host 192.168.1.31
31.1.168.192.in-addr.arpa domain name pointer ethpinode1.

At this stage, you can continue the setup of your RPI remotely from your computer using the “ssh” (“pi” is the username defined on your RPi):

computer$ ssh pi@192.168.1.31

It’s time to install Ethereum.

Step 7 – Install Geth

In this step, we are going to install the Go implementation of Ethereum client called Geth.

Connect to your RPi and retrieve the type of your CPU:

pi$ cat /proc/cpuinfo
...
model name : ARMv7 Processor rev 4 (v7l)
...

Go to the download page of Go-Ethereum by clicking here.

Select the tab Linux from the stable releases page.

Locate the row related to your CPU model and copy the link address . It’s recommended to retrieve the latest version of Geth.

In our example, we use Geth 1.5.7.

Back to your RPi, retrieve the bundle and extract the archive:

pi$ wget https://gethstore.blob.core.windows.net/builds/geth-linux-arm7-1.5.7-da2a22c3.tar.gz

pi$ tar zxvf geth-linux-arm7-1.5.7-da2a22c3.tar.gz 

Copy the Geth application to the /usr/local/bin folder:

pi$ cd geth-linux-arm7-1.5.7-da2a22c3

pi$ sudo cp geth /usr/local/bin

You can remove the archive and the uncompressed folder.

Check the version of Geth:

pi$ geth version
Geth
Version: 1.5.7-stable
Git Commit: da2a22c384a9b621ec853fe4b1aa651d606cf42b
Protocol Versions: [63 62]
Network Id: 1
Go Version: go1.7.4
OS: linux
GOPATH=
GOROOT=/usr/local/go

The same process can be applied to update an existing version of Geth.

Now, Ethereum is installed.

Let’s start it!

Step 8 – Run Geth

Start Geth using the following command:

pi$ geth
...
I1217 19:11:27.420830 p2p/server.go:342] Starting Server
...
I1217 19:11:39.816110 eth/downloader/downloader.go:326] Block synchronisation started

Press CTRL-C to stop the Ethereum server.

Summary

At this stage, Ethereum is installed on your RPi and able to synchronise with the live chain (mainnet).

The blockchain data (chaindata) is located right here: ~/.ethereum/chaindata

Your accounts will be stored in a wallet located in this folder: ~/.ethereum/keystore

Congratulations! Your RPi is an Ethereum node.

You can repeat these steps to setup additional RPi.

Part 2 describes how to set up Ethereum on a computer.

Shameless plug

While you are waiting for the next part of this series, we just wanted to let you know that we are currently preparing a full-blown online training about the development of distributed applications on Ethereum and we are looking for your feedback to figure out what you would like to see in this training. If you want to help us, you can take a few minutes to answer a survey here.

And if you just want us to keep you informed when the full online training program will be available, you can register to our mailing list on beta.chainskills.com.