Smart Home Solution using Android and Blockchain

Figure1: Architecture diagram

Smart home solutions can control the house hold electrical and electronics equipments such as light, fan, doors, lockers, water pumping motor, TV, refridgerator etc. Android app can be used to control these equipments through Blockchain and smart contracts. Android app connects with Ethereum nodes through JSON-RPC and Web3j. Raspberry Pi is employed as an ethereum node along with two more GCP VM based miner nodes. All 3 nodes run Blockchain and form a P2P network. The Raspberry Pi node controls a light to switch on and off. A smart contract is deployed on Blockchain through Web3.0 and controls the light by transactions such as depositing the tokens and withdrawing the tokens. This mini-project involves technologies such as Blockchain, Android, IOT, Cloud computing and Web3.0.

The following development environments are required:

1. Google cloud VMs (2nos) for running miners (Geth)

2. Raspberry PI as a Blockchain node (Geth)

3. Truflle Environment to build and deploy Smart Contract (Solidity)

4. Android Studio to build Android application with Web3J (Java/Kotlin)

5. IOT client application running on RPI (JavaScript/NodeJS)

Figure 2: Blockchain running on GCP VMs

Pre-requisite

1. Make sure Part1 of this article is executed:

https://anbunathanramaiah.medium.com/smart-home-solution-using-smart-contract-7eb7cd3407d3

2. Assign static IP to RPI

192.168.0.1

admin

admin

DHCP->Address Reservation

Add new -> mac address = b8:27:eb:13:29:78, ip = 192.168.0.200

save

system tools -> reboot

3. Configure GCP Firewall:

name = allow-rpc

Direction=Ingress

Action on match=Allow

Target tags = rpc

Source IP ranges = 0.0.0.0/0

Protocols and ports = Specified protocols and ports

tcp:8042,8043

Save

Add target tag:

Add Target tags in both instances 35.247.47.68 and 34.105.65.4

compute engine -> VM instances -> instance-1 -> Network tags -> Add rpc -> Save

compute engine -> VM instances -> instance-2 -> Network tags -> Add rpc -> Save

Re-start both VMs

Steps to build an IOT application

1. Start miners

cd /home/digitransolutions7/RPI

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

1.1 Start miner1 in vm1 (35.247.47.68)

Create startminer1.sh

— — — — — — — — — — -

#!/bin/bash

geth — identity “miner1” — networkid 42 — datadir “~/RPI/miner1” — nodiscover — mine — rpc — rpcaddr 0.0.0.0 — rpcport “8042” — port “30303” — allow-insecure-unlock — unlock 0 — password “~/RPI/password.sec” — ipcpath “~/.ethereum/geth.ipc” — rpcapi “db,eth,net,web3,personal,miner,admin,txpool,debug”

— — — — — — — — — — —

sh startminer1.sh

//from another cmd window with admin

geth attach “http://35.247.47.68:8042"

1.2 Start miner2 in vm2 (34.105.65.4)

cd /home/digitransolutions7/RPI

Create startminer2.sh

— — — — — — — — — — — -

#!/bin/bash

geth — identity “miner2” — networkid 42 — datadir “~/RPI/miner2” — nodiscover — mine — rpc — rpcaddr 0.0.0.0 — rpcport “8043” — port “30304” — allow-insecure-unlock — unlock 0 — password “~/RPI/password1.sec” — rpcapi “db,eth,net,web3,personal,miner,admin,txpool,debug”

— — — — — — — — — — -

sh startminer2.sh

//from another cmd window with admin

geth attach “http://34.105.65.4:8043"

Install Geth

https://geth.ethereum.org/downloads/
wget https://gethstore.blob.core.windows.net/builds/geth-linux-arm7-1.10.3-991384a7.tar.gz
tar zxvf geth-linux-arm7–1.10.3–991384a7.tar.gz
cd geth-linux-arm7–1.10.3–991384a7
sudo cp geth /usr/local/bin
geth version

cd /home/ubuntu/rpi-gcp

geth — identity “node1” — syncmode “fast” — networkid 42 — datadir “~/rpi-node/node” — nodiscover — rpc — rpcaddr 0.0.0.0 — rpcport “8042” — port “30303” — allow-insecure-unlock — unlock 0 — password “password.sec” — ipcpath “~/.ethereum/geth.ipc” — rpcapi “db,eth,net,web3,personal,miner,admin,txpool,debug”

To attach

open separate cmd window

geth attach “http://localhost:8042"

eth.coinbase

“0xe6f8bbc22d6ef8cb0991e1a27d9909c92422c119”

from miner1, send 10 ethers to RPI:

eth.sendTransaction({from: eth.coinbase, to: “0xe6f8bbc22d6ef8cb0991e1a27d9909c92422c119”, value: web3.toWei(10, “ether”)})

1.4 Synchronize RPI

Finish RPI configuration based on ‘rpi configuration.txt’

Update the file “static-nodes.json” with RPI enode

— — — — — — — —

[

“enode://f9d48547c373fd61124d110791168572382298979d18ab5d6314cd399538ef77b8ff826b870a3474ad351f175b6d4d6f03c09ab4382b4d075e6a3c7fdeee58aa@35.247.47.68:30303?discport=0”,

“enode://991f8279ae27e665151621a9940b42e208bb7cda0108c3cda219059bed28fbb7ec869b04db84d173fbb1cecdce5fef222d010f02a90238e7d8a53b163f6b0a2a@34.105.65.4:30304?discport=0”,

“enode://2bb141277704d6ca1e7920c744090e01f53c3842f238a09c9b14c425eb0eb75ef5bbf3b294d9d3dd37f9d321ffcac1314c46e49473f1f66a3f7ad828d116a364@192.168.0.200:30303?discport=0”

]

— — — — — — — — -

/copy static-nodes.json into the folders

in vm1,

/home/digitransolutions7/RPI/miner1

in vm2

/home/digitransolutions7/RPI/miner2

/home/ubuntu/rpi-gcp/node

//exit all 3 miners and again re-start miners

//from attached windows, check peer status

admin.peers

//Observe all 3 miners are paired.

Figure 3: Blockchain running on RPI

2 Start mining

from both vm1 and vm2 cmd window attachments,

miner.start()

eth.mining > true

//in first attachment

web3.personal.listAccounts

web3.personal.unlockAccount(web3.personal.listAccounts[0],”blockchain”, 15000)

eth.getBalance(eth.coinbase)

eth.blockNumber

eth.coinbase

“0xfaec65d82c950b9f21e46c506c359a74eca5c9c9”

3 Get Private Key

3.1 Get private key for RPI (to control light)

In RPI,

sudo npm install -g keythereum

sudo npm install keythereum

data dir = /home/ubuntu/rpi-gcp/node

cd ~/

node

— — — — — — — — — — — —

var keythereum = require(“keythereum”);

var keyObject = keythereum.importFromFile(“0xe6f8bbc22d6ef8cb0991e1a27d9909c92422c119”, “/home/ubuntu/rpi-gcp/node”);

var privateKey = keythereum.recover(“blockchain”, keyObject);

console.log(privateKey.toString(‘hex’));

— — — — — — — — — — — — — -

Observe >

0x57fbf0ad60b682272423afa3c5bd9ed9c459cbf5af3c6f074594ba386ec37428

3.2 Get private key for miner1 (for test purpose):

npm install -g keythereum

data dir = /home/digitransolutions7/RPI/miner1

//cd /home/ubuntu/rpi-gcp

cd ~/

node

— — — — — — — — — — — —

var keythereum = require(“keythereum”);

var keyObject = keythereum.importFromFile(“0xfaec65d82c950b9f21e46c506c359a74eca5c9c9”, “/home/digitransolutions7/RPI/miner1”);

var privateKey = keythereum.recover(“blockchain”, keyObject);

console.log(privateKey.toString(‘hex’));

— — — — — — — — — — — — — -

Observe > 0x0938d8684c5f65dcf89a0c196d43e9e5f586ee75681d1b254de112a46998b9dd

4. Smart contract

4.1. Install truffle

open a new cmd window with admin

mkdir SmartToken

chmod -R 777 SmartToken

cd /home/digitransolutions7/SmartToken/

//https://registry.npmjs.org/truffle/-/truffle-5.1.66.tgz

sudo npm install -g truffle@4.1.16

//npm install solc@0.4.15

npm install solc@0.4.21

truffle init

truffle compile

4.2. Create smart contract

Copy the code from Github

https://github.com/anbunathan/blockchain_examples/tree/master/SmartTokenGCP

cd /home/digitransolutions7/SmartToken/contracts

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

— — — — — — — — — — — — — — — — — — — — — -

pragma solidity ^0.4.15;

contract SmartToken {

mapping(address => uint) tokens;

event OnValueChanged(address indexed _from, uint _value);

function depositToken(address recipient, uint value) public returns (bool success) {

tokens[recipient] += value;

emit OnValueChanged(recipient, tokens[recipient]);

return true;

}

function withdrawToken(address recipient, uint value) public returns (bool success) {

if (int(tokens[recipient] — value) < 0) {

tokens[recipient] = 0;

} else {

tokens[recipient] -= value;

}

emit OnValueChanged(recipient, tokens[recipient]);

return true;

}

function getTokens(address recipient) constant public returns (uint value) {

return tokens[recipient];

}

}

— — — — — — — — — — — — — — — — — — — — — -

4.3. Create 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);

};

— — — — — — — — — — — — — — — — — — — — — -

4.4. Update truffle.js

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

— — — — — — — — — — — — — — — — — —

module.exports = { networks: { development: { host: “localhost”, port: 8042, network_id: “*”} } };

— — — — — — — — — — — — — — — — — —

4.5. Generate Smart Contract address and ABI (Application Binary Interface)

Make sure blockchain is running

Mining is started

eth.mining should return true

eth.blockNumber should return block number > 0, block number should keep incrementing

cd /home/digitransolutions7/SmartToken

truffle compile

//should compile successfully

truffle migrate — reset

truffle console

//Observe truffle(development)>

SmartToken.address

‘0x0ce678aa4dabef4627fd351deeb35889e6c3d246’

JSON.stringify(SmartToken.abi)

//ABI (Application Binary Interface)

— — — — — — — — — — — — — — —

[{“anonymous”:false,”inputs”:[{“indexed”:true,”name”:”_from”,”type”:”address”},{“indexed”:false,”name”:”_value”,”type”:”uint256"}],”name”:”OnValueChanged”,”type”:”event”},{“constant”:false,”inputs”:[{“name”:”recipient”,”type”:”address”},{“name”:”value”,”type”:”uint256"}],”name”:”depositToken”,”outputs”:[{“name”:”success”,”type”:”bool”}],”payable”:false,”stateMutability”:”nonpayable”,”type”:”function”},{“constant”:false,”inputs”:[{“name”:”recipient”,”type”:”address”},{“name”:”value”,”type”:”uint256"}],”name”:”withdrawToken”,”outputs”:[{“name”:”success”,”type”:”bool”}],”payable”:false,”stateMutability”:”nonpayable”,”type”:”function”},{“constant”:true,”inputs”:[{“name”:”recipient”,”type”:”address”}],”name”:”getTokens”,”outputs”:[{“name”:”value”,”type”:”uint256"}],”payable”:false,”stateMutability”:”view”,”type”:”function”}]

— — — — — — — — — — — — — — — -

Figure4: JSON-RPC and Web3J

5. Generate Java code which connects Android app with Ethereum through JSON-RPC and Web3j:

//Install solc and web3j:

sudo npm install -g solc@0.4.21

sudo wget –O https://github.com/web3j/web3j/releases/download/v4.0.1/web3j-4.0.1.tar

sudo chmod 777 web3j-4.0.1.tar

sudo tar -xvf web3j-4.0.1.tar

sudo mv /home/digitransolutions7/web3j-4.0.1 /home/digitransolutions7/web3j

sudo nano ~/.bashrc

export PATH=”/home/digitransolutions7/web3j/bin:$PATH”

source ~/.bashrc

web3j version

//observe 4.0.1

mkdir code

cd code

sudo chmod -R 777 code

cd ~/SmartToken/contracts

sudo cp SmartToken.sol ~/code/SmartToken.sol

cd ~/code

solcjs SmartToken.sol — bin — abi — optimize -o .

//Generate java file

web3j solidity generate -b SmartToken_sol_SmartToken.bin -a SmartToken_sol_SmartToken.abi -o . -p com.noev.ethereumhelloworld

//Observe Java file — “SmartToken_sol_SmartToken.java” is generated under

“/com/noev/ethereumhelloworld/” folder tree.

Figure 5: Android App

6. Add Android code

Copy the code from Github

https://github.com/anbunathan/blockchain_examples/tree/master/Android-GCPVM-SmartToken

6.1 The generated Java class — SmartToken_sol_SmartToken.java is added under:

“/app/src/main/java/com/noev/ethereumhelloworld/” folder

This Java class includes the following Remote procedures:

depositToken

withdrawToken

getTokens

6.2 In MainActivity.kt, the following variables are updated:

Add smart contract address in Android code

const val geth_url = “http://35.247.47.68:8042"

const val CONTRACT_ADDRESS = “0x0ce678aa4dabef4627fd351deeb35889e6c3d246”

const val PRIVATE_KEY_GETH = “0x57fbf0ad60b682272423afa3c5bd9ed9c459cbf5af3c6f074594ba386ec37428”

val recipient = “0xe6f8bbc22d6ef8cb0991e1a27d9909c92422c119”

private val credentials = Credentials.create(PRIVATE_KEY_GETH)

infuraHttpService = HttpService(geth_url)

web3j = Web3j.build(infuraHttpService)

“Success initializing web3j/GCPVM”

7. Build Android application and install

Gas=1wei

limit>=73000

Change token = 10

click on ‘Deposit’

Observe “Successful…” message

Click on “Get Token”

Observe 10 is displayed

click on ‘Withdraw’

Observe “Successful…” message

Click on “Get Token”

Observe 0 is displayed

Figure 6: Project setup

8. Create IOT application in RPI

Copy the code from Github:

https://github.com/anbunathan/blockchain_examples/blob/master/RPI/smart_token.js

Create the Client application

//create — “smart_token.js”

cd ~/RPI/SmartToken

sudo nano smart_token.js

//Add SmartToken.address and ABI

— — — — — — — — — — — — — — — — —

// 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 = ‘0x0ce678aa4dabef4627fd351deeb35889e6c3d246’

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

// 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() {
web3.eth.defaultAccount = web3.eth.coinbase
//web3.personal.unlockAccount(web3.eth.accounts[1], ‘blockchain’)
//web3.eth.defaultAccount = web3.eth.accounts[0]
// retrieve the value of the token
var token = contract.getTokens(web3.eth.defaultAccount)

// display the LED according the value of the token
const led = new Gpio(17, ‘out’); // Export GPIO17 as an output
if (token > 1) {
// Green: you have enough token
redLed.writeSync(0)
greenLed.writeSync(1)
led.writeSync(1)

} else {
// Red: not enough token
greenLed.writeSync(0)
redLed.writeSync(1)
led.writeSync(0)
// Toggle the state of the LED connected to GPIO17 every 200ms
//const iv = setInterval(_ => led.writeSync(led.readSync() ^ 1), 200);
}
}

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

— — — — — — — — — — — — — — — — —

9. Run the client application

cd ~/RPI/SmartToken

node smart_token.js

10. Run Android application

Gas=1wei

limit>=73000

Change token = 10

click on ‘Deposit’

Observe “Successful…” message

Observe light is switched on

click on ‘Withdraw’

Observe “Successful…” message

Observe light is switched off

11. Demo

The demo of this project is given in the link:

Source code:

https://github.com/anbunathan/blockchain_examples/tree/master/Android-GCPVM-SmartToken

https://github.com/anbunathan/blockchain_examples/tree/master/RPI-GCP

References

1.Communicating with an Ethereum Smart Contract via Android

https://medium.com/interfacing-with-a-blockchain/communicating-with-an-ethereum-smart-contract-via-android-24ee0dd2c115

2.How to sync an Ethereum node without making the mistakes I made

3.Nodeless Ethereum Smart Contracts Development with Infura

4.Ethereum Blockchain “Hello World” Smart Contract with JAVA

Contact Details

Email: anbunathan.r@gmail.com

Website: http://digitranssolution.com

Dr. Anbunathan R is founder & CEO of ‘DigiTran Solutions’ and making innovative products, based on Digital Transformation technologies such as AI/Blockchain/IOT