Skip to content

2. Ethereum

LouisVlrd edited this page Jan 17, 2018 · 18 revisions

(documentation in progress)

This page describes the setup of a local blockchain (using Parity client) and the DAISEE application on a Raspberry Pi 3.

Parity installation

Use the EthRaspbian image (Parity v1.6.8)

An image is available with Parity and Geth clients:
http://ethraspbian.com/downloads/image_2017-06-13-EthRaspbian-parity-1.6.8-lite.zip
(see repository diglos/pi-gen for more informations).

This image is compatible with Rapsberry Pi 2 and 3 and runs Parity Ethereum client as a boot service (full Ethereum node).

After turning on the Raspberry Pi, disable the Parity service for now:

$ sudo systemctl stop parity
$ sudo systemctl disable parity
Removed symlink /etc/systemd/system/multi-user.target.wants/parity.service

And update/upgrade Raspbian:

$ sudo aptitude update && sudo aptitude upgrade

Use the Parity binary (Parity v1.7.9)

You can get the Parity binary for Raspberry Pi (ARM architecture) from parity.io:

$ sudo wget http://d1h4xl4cr1h0mo.cloudfront.net/stable/arm-unknown-linux-gnueabihf/parity

Parity configuration

For testing purposes and due to ressources limitations, a private/local blockchain will be set up with Proof-of-Authority consensus engine, for this version of DAISEE prototype.

[Proof-of-Authority] does not depend on nodes solving arbitrarily difficult mathematical problems, but instead uses a hard-configured set of "authorities" - nodes that are explicitly allowed to create new blocks and secure the blockchain. This makes it easier to maintain a private chain and keep the block issuers accountable.

Here are some links to introduce the creation of a private blockchain, some concepts are described here:

All steps for setting up a local blockchain with Proof-of-Authority are described here:
Demo PoA tutorial

Parity can be easily configure through a configuration file:
https://github.com/paritytech/parity/wiki/Configuring-Parity#config-file

Init configuration files

The first step is to initialize configuration files, here are two differents files used for one node of the prototype:

All files will be created in /home/pi.

  • blockchain specifications (demo-spec.json):
{      
    "name": "DemoPoA",
    "engine": {
        "authorityRound": {
            "params": {
                "gasLimitBoundDivisor": "0x400",
                "stepDuration": "5",
                "validators" : {
                    "list": []
                }
            }
        }
    },
    "params": {
        "maximumExtraDataSize": "0x20",
        "minGasLimit": "0x1388",
        "networkID" : "0x2323"
    },
    "genesis": {
        "seal": {
            "authorityRound": {
                "step": "0x0",
                "signature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
            }
        },
        "difficulty": "0x20000",
        "gasLimit": "0x5B8D80"
    },
    "accounts": {
        "0x0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
        "0x0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
        "0x0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
        "0x0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
    }
}
  • node configuration (config.toml)
[parity]
chain = "demo-spec.json"
base_path = "/home/pi/tmparity"
[network]
port = 30300
[rpc]
port = 8540
apis = ["web3", "eth", "net", "personal", "parity", "parity_set", "traces", "rpc", "parity_accounts"]
[ui]
port = 8180
[websockets]
port = 8450
[ipc]
disable = true

Run Parity

Try to launch the node:

$ parity --config config.toml --unsafe-expose

We find the name of our blockchain "DemoPOA".

noderunning

Stop the node with ctrl+c.

Create an account

To access to the Parity UI, add the raspberry IP in config.toml in [ui] part like this:

interface = "0.0.0.0"

Start the node:

$ parity --config config.toml --unsafe-expose

Go to http://raspberry-ip:8180 and follow the wizard.
DON'T FORGET TO COPY THE ACCOUNT ADDRESS IN THE RECOVERY STEP !

To find your raspberry ip, you can either type ip a s after stopping Parity (ctrl+c) or it is indicated at the end of the public node URL (192.168.xx.xx)

If no wizard showed, go to the Accounts tab and click "ACCOUNT", 'New Account' and follow it.
It would be best using an easy password, and don't forget to set one

The account is created, stop the node with ctrl+c.

Add a node

The goal is to connect with another node. The blockchain is private/locale, adding a node can be done with the node configuration file. Get the address of another node and add it in config.toml in [network] part:

bootnodes = ["enode://ff14ae0a273e08ffbbe20b4b398460eb471e23f1b4301ce46b92a86ad420f67b9b470d097f1939fa7b9b2aae7d24e72cf7c63fe67217bdf3fd6cb60bbb7ecc59@192.168.0.47:30300"]

To get that enode, you can read the line you used to get your raspberry IP in the parity launch, or via the UI, click the network status bar (red) and your enode should be displayed. If no info is displayed, simply refresh (f5)

in the bottom right

Launch the node:

$ --config config.toml --unsafe-expose

A node is connected 1/25 peers

nodeconnected

We can see the same log in the terminal of the other node.

Stop the node, use ctrl+c.

Once the nodes are connected, their demo-spec.json must always be identical

Add authorities

In Proof-of-Authority, we have to define authorities which validate transactions between nodes. An authority is an account on a node of the blockchain.

Add one or more account addresses in demo-spec.json in "validators" part:

"list": [
    "0x005d23c129e6866B89E1C73FC3b05014255CEFA2",
    "0x0011067b3a4fE6fd301296AD5bC730F7a1CeCE4f"
]

And for each node of each authority account, following parameters have to be add in config.toml:

[account]
password = ["node.pwds"]
[mining]
engine_signer = "0x002e28950558fbede1a9675cb113f0bd20912019"
reseal_on_txs = "none"

engine_signer is the account address used for authorities.

Create an empty file node.pwds and write to it the account password.

Deposit Ether on the account

Each account needs Ether to deploy a smart-contract or to execute a transaction.

Add the account address in demo-spec.json in "accounts" part like this:

"0x005d23c129e6866B89E1C73FC3b05014255CEFA2": { "balance": "100000000000000000000" }

Start the node:

$ parity --config config.toml --unsafe-expose

Go to http://raspberry-ip:8180 and check if the account has been credited.

If it is the case, you can add to your addressbook the accounts of the other nodes. To do it, go to the Addressbook tab and click 'Address' and paste the address of the other account you want to add, and his name.
The address of an account is displayed under that account's name in the Accounts tab

Troubleshooting

In the case where a new validator node is added, after some blocks validation, the following message may appear during blocks import:

Error: Engine(NotProposer(Mismatch { expected: 00aa39d30f0d20ff03a22ccfc30b7efbfca597c2, found: 00bd138abd70e2f00903268f3db08f2d25677c9e }))

The workaround is to modify the chain specifications to revert to the precedent version, until a new error message.
Exemple: parity client Only 3 blocks are imported with the last version of chain-specs.json (3 validators). In order to import the next blocks, the last validator is removed from chain specs, and blocks are imported until block #55. After this message, using the last version of chain specs (with the 3 validators) allows to import the full blockchain.
The best solution would be to add the new validator account only after importing the full blockchain on the node.

Smart-contracts

2 smart-contracts (in Solidity) are used:

  • token.sol
    This is the smart-contract described in the tutorial "Create your own crypto-currency".
    It allows to create a token, according to the ERC20 Token Standard.
  • daisee.sol
    The current version allows to :
    • store energy data on blockchain (consumption and production),
    • make transactions between peers.
      For now, the rules that trigger transactions are not implemented in a smart contract. Note: the smart contract is still under development, the code may change (see Issues).

Several methods exist for deploying and testing a smart contract.
In this wiki, the use of the Parity UI is described.

Deploying contracts

In Contracts Tab, after clicking on "DEVELOP" button, copy paste the code from token.sol then, at the end of this code, copy/paste the code of daisee.sol:

Then, in the 'select a Solidity version', choose the version 0.4.2 and click "COMPILE". That done, select the contract MyAdvancedToken in the 'select a contract' field and click "DEPLOY":

Enter the name of the contract as shown, then the details on the next page and finally confirm the contract creation with your user's password:

We successfully deployed the DaiseeCoin contract. Now, to deploy the Daisee contract, go back to the Contracts tab, "DEVELOP" then select Daisee under the 'select a contract' field:

Simply name it Daisee and confirm the transaction. The two smart-contract now appear in the Contracts tab:

At this point normally, only one node has these two contracts. For letting all nodes use that contract, they have to "WATCH" it. To do that, copy the contract's address (0x----------------) on the node that has it, then transmit it to the others:

The ABI has to be transmitted to for each contract too. To view it, select the contract, click 'Details' in the top-right, and go down until the ABI:
To copy the contract, click inside the ABI code then use : ctrl+a to select all the code, then ctrl+c to copy it

Then, all the nodes that are on the same network can use that contract by going to the Contracts tab, select "WATCH" on the top-right, select 'Custom contract', then pasting the right data in the right field :

That done for the two contracts, the other node should see in the Contracts tab the contracts with the same address as well :

Each account/node will be able to buy energy to another account/node. The smartcontract Daisee must have permission to send DaiseeCoins to the producer.
Select the DaiseeCoin contract and click on "EXECUTE".
Choose the 'approve' function, select Daisee contract for the address and choose the number of DaiseeCoins that the Daisee contract will be able to send:

'Post transaction' and enter the account password before to 'Confirm request':

The DaiseeCoin contracts has been deployed on the blockchain through only one node and a number of DaiseeCoin has been credited on this node. All the others nodes will need DaiseeCoin to buy energy.
On the node which deployed the DaiseeCoin contract, select the DaiseeCoin contract and click on "EXECUTE".
Choose the 'transfer' function, enter the address of another node and choose the number of DaiseeCoins to transfer to it:

'Post transaction' and enter the account password before to 'Confirm request':

Note: the current version of DAISEE smart contract allows to update consumption and production directly. To do this, select the Daisee contract, click the "EXECUTE" button at the top right, and choose the function 'setProduction' or 'consumeEnergy':

see Issue DApp-v2/issues/5

Interface

To view data, a Web interface communicates with the local node, through Web3 JavaScript API, using web3.js.
The microframework Flask allows to display the interface from the Raspberry Pi node.

Tutorial used:
A simple smart contract Web UI using web3.js

Install the requirements

$ sudo aptitude install git
$ sudo pip3 install flask pyyaml requests

Clone the repository

$ git clone https://github.com/DAISEE/DApp-v2.git

In DApp-v2/dapp, create the configuration file (config.yml) from the example and complete it:

contracts:
  daisee: '0xbeaE6e2747bD6db798d222E2D2185c484b5f2f9d'
  token: '0x9cf61b2b43f5695D65e633d0CA2dC03908eB6dd1'
user:
  login: 'daisee'
  pwd: '4df74be9792adc7848b15d833748b3affe59fced7e5dd5623831fa3040424761'
  coinbase: '0x005d23c129e6866b89e1c73fc3b05014255cefa2'
  name: 'node1'
  typ: 'C'
  url: 'http://0.0.0.0'
  sensorId:
  sensorLogin: ''
  sensorPassword: ''
  sensorSource: ''
  sensorPort: ''
Type Field Description
contracts
daisee Daisee.sol address on the blockchain
token DaiseeCoin smart-contract address on the blockchain
user
login login for UI
pwd hashed password for the UI*
coinbase user address
type type of node ('C' for consumer, 'P' for producer). Not Used
url url of energy monitoring application**
sensorId url of energy monitoring application
sensorLogin login for energy monitoring application
sensorPassword password for energy monitoring application
sensorSource energy monitoring application : 'CW' for citizenWatt (only app supported for now)
sensorPort if necessary, port of energy monitoring application, example : ':8080'

still under development, it may change

* to obtain the hashed password, use 'raspberry-ip:5000/hash/<password>' after running the server
** if the energy monitoring application is (or will be) on the same Raspberry Pi, follow these instructions before running DAISEE app.
*** if sensors are not used, sensor parameters can be empty

Run the server

$ export FLASK_APP=server.py
$ python3 -m flask run --host=0.0.0.0

Go to http://raspberry-ip:5000 to access to the interface.

For this prototype, we use Mozilla Firefox.

The current version displays Ethereum transactions and realtime data from the energy monitoring application