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.