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
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
- 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}
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}
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
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.
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
#!/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
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 ...
Step 7 – JavaScript console
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
pi$ cd ~/ChainSkills/node pi$ ./startnode.sh ...
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
> 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.
Step 5
i can’t run
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
command stop unlocked account .
how can fix
Hi Said,
thanks you for tutorial, but i have a problem i can’t start node from RPi .
When i run command step5 command stop on unlock account .
How can this be solved?
thanks.
J
Hi
Are you sure that your have set a password into the file:
/home/pi/ChainSkills/node/password.sec
This password must be the same as the one used to create the first account (accounts[0]).
Best
Said
Thank you for answer.
I’ve already entered password.sec and it’s correct. Because it warned me to enter when I didn’t do it. But now my problem is
I’m stuck at the unlocked account line.
I’ve attached photo for you.
https://imgur.com/AZ2wNwK
Thank you so much for your help.
J
Hi,
Can you define the maximum ETH that can be mined from the genesis file?
Hi Albert
The reward mechanism is part of the Ethereum platform and cannot be adjusted on the genesis file.
Said
hello, i am having problem with synchronizing pi-node to miner1/2. Rpi is connected to internet sharing via wifi to mac in which two miners are located.
FOR MINER 1:
1. name: “Geth/miner2/
localAddress: “169.254.239.105:51232”,
remoteAddress: “169.254.239.105:30304”,
2. name: “Geth/node1/
localAddress: “169.254.239.105:30303”,
remoteAddress: “192.168.2.9:45388”,
FOR MINER 2:
1. name: “Geth/miner1/
localAddress: “169.254.239.105:30304”,
remoteAddress: “169.254.239.105:51232”,
2. name: “Geth/node1/
localAddress: “169.254.239.105:30304”,
remoteAddress: “192.168.2.9:41144”,
FOR NODE:
1. name: “Geth/miner2/
localAddress: “192.168.2.9:41138”,
remoteAddress: “169.254.239.105:30304”,
2. name: “Geth/miner1/
localAddress: “192.168.2.9:45382”,
remoteAddress: “169.254.239.105:30303”,
same issue im facing now.
Can you tell me how to fix this issue .
Hi, we are doing part 5 ,step 3. When I exexuted this command : geth –datadir ~/ChainSkills/node init ../genesis.json , we got an error saying that , Fatal : failed to read genesis file: open ../genesis.json: no such file or directory. Please help us.
Hi
According this tutorial, this file is expecting there: /home/pi/ChainSkills/genesis.json
Did you transfer the genesis file to your RPi?
Are you able to view or to edit this file?
Said
Yeah we got it .
Hey Said,
i have a problem syncing my raspberry…
My admin.peers output is unstable… Miners are dropped out and added back frequently.
Furthemore, when i send ether to the eth.coinbase account of my raspberry, it doesnt see the ethers incomming, i can verify that the transaction went through, and miners see the update of raspberry’s address funds, however its just raspberry not seeing any updates.
My static nodes json file seems fine:
[
“enode://a8b3b535c6bfc06afeec87f06bf2b72c75ee0b047001941ac61ab5795100cccb43699d9a917220e49414e6f517511af61cd66467bcc4030007d7f7a3dd55829b@164.48.200.200:30303”,
“enode://f28a4719df07905a88a4dac20b80476d2005d0ca9585cd53750733b4cb62e41afa9b12300a8ef5ab5349c9ecf0412745d5a13c3af3222468bd02ce29d4030c96@164.48.200.200:30304”,
“enode://1ad5e0e90dd12fd9dedfd491b8348a5ffae965396707f8807bb7b6c3fc2a71a805964742c1bb11f53fcb433a1f85e3868008827efa1a6a3ce602befbda7da481@164.48.200.51:30303”
]
where the third one is the raspberry…
Hello!
Is it necessary for every single node to be connected to each and every node in the blockchain?
No, clearly not. Here the example is somewhat artificial because it’s a very small network. But usually, in a real network, a node is directly connected to a few nodes around it through the discovery protocol, and can reach every node indirectly through others.
I have created a private network with 3 nodes – two nodes in computer and one in raspberry pi
I connected computer and raspberry pi to same network through LAN
computer ip: 192.168.122.1
pi ip address: 10.1.200.157
enode of node1: “enode://f44eea7f09627b885f012ea3947dd676f01b13bb92a18216c497ec7cccce28d958b4fb9f9c942b5d41f8169cae5e6919350a95feb2b8a4f2e022a20801be282b@192.168.122.1:30303”
enode of node2:
“enode://b00916eb3723de7e2c2ad683283b184fe639c41e902316dbca8a457f353694e02f98e1b770ae2e1e7f6216a7332087fb2701a91d20d82758e8b74651754f4bb3@192.168.122.1:30304”
enode of pi node: “enode://090c17aac6f826e5e771c925e36933407a799747bbe31856ea69fa11e9b906e4a24a28280a28dcfc9f0bb7960083f211759b5e4cebf4b4d66d8b79358b1fac3c@10.1.200.157:30305”
Iam able to synchronize the node1 and node2 and send some ether from node1 to node2 and viceversa.
But unable to sync pi node to node1 or node2 and unable to sync node1 or node2 to pi
when i give the following command in node1 console admin.addPeer(“enode://090c17aac6f826e5e771c925e36933407a799747bbe31856ea69fa11e9b906e4a24a28280a28dcfc9f0bb7960083f211759b5e4cebf4b4d66d8b79358b1fac3c@10.1.200.157:30305”)
im getting True response but when i check admin.peers i can see only node2 synced.
Please click the below link for attachement
https://i.stack.imgur.com/0IKXf.png
Hi guys, I’m experiencing the problem that I cant connect my Rpi with the other 2 Miners. Static-nodes.json is set up right and everything else is made like in the tutorial…. after running the startnode.sh it always “stops” at …..unlocked Account…… I tried to send Transaction with geth which worked great so it seems that the acc is really unlocked. But everytime I check the peers in rpi geth it’s returning an empty array…