Lightshow — Ethereum+IoT device @ uOttahack

Kaustav Haldar
10 min readFeb 26, 2018

--

Editors note: This article is in-progress, please report any issues/inconsistencies or reach out for collaboration to hi@kaustav.me.

Full source code: https://github.com/kaustavha/eth-lightShow-uottahack

The final creation with the lights off

At uOttahack at the University of Ottawa in Canada my team and I created a PoC interactive art device. Users could interact with it using their phones or computers by visiting a website or potentially sending ether to an address causing lights to change or light up.

In this post I’ll describe what went into creating it, roadblocks and issues we faced and how we overcame them and the different components of our hack.

Index:

  • Executive summary, project pitch, example use cases
  • A technical overview of the architecture
  • Reasoning behind the use of various components
  • Future research
  • Technical deep-dive exploring the various components and also links back to the source code.

Pitch

Our project features a 3d printed canada leaf shaped chassis with RGB leds behind it connected to an arduino and wired up to run on events on the ethereum blockchain that come in as people trigger our smart contract either directly or via our interface which is served from a nodejs server.

The pitch was sectioned for different audiences:

  • Artists: we would encourage artists to use more technology in their creations and incentivize artists and also their friends who could see activity on their creations on the open ethereum blockchain. Artists could also see which creations were more popular
  • General public: if this technology was used in cities would create smart spaces that the public could interact with, while preventing malicious actors with financial disincentives.
  • Government: open data guarantees since interaction is logged to an open ledger (ethereum)
  • Infrastructure: reduction in infrastructure costs due to the relative serverless nature afforded by the use of ethereum
  • City: potential for smart city monitoring since recorded data could be leveraged to find hot spots in the city and understand public movement and interests

Examples:

  • Lights in a park the public can change the hue of depending on their mood — lights in a park that are kept at a low level and increased depending on people showing up or requesting more light
  • Charity activated christmas tree lights that illuminate as people contribute, public near the tree are motivated to contribute using easy cryptocurrency based donation mechanisms as the tree lighting slows down as the goal is neared — Fun group based art projects that many people interact with to turn on or complete a light based puzzle
  • We want to improve, document and open source our code and methods for artists to be able to freely pick up and use to further their artistic endeavours. Also possibly set it up in the makerspace at uOttawa.

Project synopsis

We wanted the user to be able to interact with the lights semi-anonymously by interacting directly with the blockchain or by using our server to interact for free using an e-wallet with funds and funding limits.

Index:

  • Executive summary, project pitch, example use cases
  • A technical overview of the architecture
  • Reasoning behind the use of various components
  • Future research
  • technical deep-dive exploring the various components and also links back to the source code.

Project synopsis

We wanted the user to be able to interact with the lights semi-anonymously by interacting directly with the blockchain or by using our server to interact for free using an e-wallet with funds and funding limits.

Architecture diagram

The final project had 5 distinct parts:

  • A 3D printed chassis for the lights in the shape of a Canada 150 maple leaf design
  • An arduino with LEDs connected to a laptop for internet access
  • A website and frontend users could visit
  • An ethereum smart-contract
  • A consolidated back-end server responsible for 3 distinct functions; serving up the front-end, conversing with the Arduino, and conversing with the blockchain

Reasoning behind components

  • Server: We consolidated the 3 distinct functions of the server into a single Nodejs Express server to save time, but ideally we would have 3 distinct server runtimes.
    - One with an open wallet meant for conversing to the blockchain without incurring costs or special software from the user side.
    - One for serving the frontend to users
    - One to listen to events coming in from the blockchain and controlling the arduino
  • Blockchain: Using a blockchain is a contentious and controversial topic. Apart from the benefit of buzzwords we justify using Ethereum due to the open data guarantees given, wherein the data is hosted and can be viewed by anyone for free due to it’s presence on an open trust-less distributed ledger.
    - This lines up with government open data initiatives and prevents vendor-lock-in for smart city/analytics providers who can hoard data.
    - Building atop the financial system offered by Ethereum also allows artists to benefit financially from their work without middlemen involved and monitor the popularity of different pieces.
    - This financial mechanism also disincentivizes bad actors, e.g. people trying to abuse the piece to flicker lights or continually turn them on/off increasing the risk of epileptic attacks or annoyance in passerbys. All while allowing both anonymous and registered interaction.
  • Arduino: To create a simple and reliable physical frontend, we decided to use an Arduino setup that could be controlled with serial input. The use of serial enabled flexibility in our language choice, since most languages have libraries to write/read serial data.

Future research

IoT devices connected to the blockchain is a good area of research and work for a plasma compliant side chain with faster block confirmation times.
A hybrid quorum based system could be useful here. Using a quorum based system and falling back to BFT if contention occurs as outlined in this MIT paper or using a leader-election based consensus mechanism like RAFT to power a Kafka queue as outlined here which then acts as the main source of truth for our side-chain. Think of it as a mix of Hyperledger Fabric and Hyperledger Indy. There’s less work overhead since only leaders do ordering, and we can use industry standard and tested Kafka APIs while adding BFT. Alternatively either of those pre-defined options work.

PoET as outlined in Hyperledger Iroha is not useful for our case since Intel TEE processors are rare and none of our computers or the arduino has one or we didn’t know of it or how to enable or use it.

Building this IoT side chain on top of Ethereum as a layer 2 scaling mechanism/plasma compliant side chain benefits it with the guarantees of Plasma namely the trust of users who can exit out of it back into ethereum in case of ‘issues’. It also benefits from the network effect of the ethereum chain and the attack resistance and trust built over many epochs. The ability to escape the side-chain as outlined in the Plasma whitepaper also reduces the risk of malicious actions through collusion of the sidechains main actors and stake holders or of gross inconsistencies arising in the future as in the case of Ripples missing blocks.

Technical deep-dive

3D printing

3D printing facilities were generously provided by the UOttawa makerspace and this piece was built and lead by Quinn.

The leaf form was printed out of a recyclable plastic material called PLA (polylactic acid) on an Ultimaker 2+ 3D printer (https://ultimaker.com/en/products/ultimaker-2-plus). The 3D model was retrieved from Tinkercad, a basic 3D modelling website run by Autodesk, which is free for all users. The leaf model which was used can be found at the following link: https://www.tinkercad.com/things/dTp3z5N5kYj-leaf-size-w-base

The uOttawa Makerspace is located on the University’s campus in the Colonel By building (room B109A). It is a creative space which is free for students and community members to use. It is open to the general public on Sundays 11am to 5pm, and houses around 25 3D printers, a VR station, a soldering station and an industrial 50 Watt laser cutter . The Makerspace offers workshops which are free to community members and students on a variety of topics including basic Arduino, Autocad, Laser Cutting and 3D printing. For more information on the Makerspace visit the website at http://makerepo.com/

Arduino and IoT device :

This integral component was managed by Ryan with some help from both Quinn and I.

Ryan wrote the C++ code that powered the arduino logic, programmed the javascript-serial port interaction and wired the first revision of our arduino with LEDs. The Node.js server, after a brief pause to allow the serial port to open, was programmed to send a single number over serial to issue a command. In our implementation 5,6 and 7 would trigger green, red or blue to light up. Sending an 8 over serial cycled through the LEDs, giving us a foolproof method for changing the color of our system when it was requested.

The C/JS code was reworked a few times to account for any errata in the serial signal or fast switching, and the demoed implementation was quite robust; errors were indicated with a short animation, and the code ensured only a single LED would ever be lit during normal operation.

Quinn and I later rebuilt his circuit using a lower resistance level for brighter lights and using the LEDs the three of us had soldered and hot-glued onto the 3D printed chassis.

I learned how to work with an arduino & solder and hot-glue things!! And almost burnt myself. Also did you know a bread board isn’t a board you cut bread on?

We used the arduino IDE to figure out the serial port for the arduino, which is then supplied to the nodejs server when we start it as a command line flag e.g. here is how I would start it :

node server2.js 
<privKey for testrpc wallet>
<wether to log to console>
<wether to run the arduino>
<arduino port from arduino ide>

That is:

node server2.js 26ezu.. y y /dev/cu.usbmodem1461

Turns out MacOS identifies arduinos as usb modems. I’m disappointed in the lack of that nostalgic connection screech from old modems.

Front-End : Code

Dylan was our chief front end engineer and created a front-end and integrated it with our server. The front-end featured a CSS animated candle with a flickering flame and had planned functionality for more direct controlling of the lights. But we only had time to implement switching lights when users visited the site.
He learned the basics of git, html, css animations, nodejs express servers and blockchain mechanisms.

Pardon our french

Backend server: code

The backend server was built in javascript leveraging nodejs & express.
We used:

  • serialport.js to connect to the Arduino.
  • ethers js to connect to the blockchain

Here is a simplified example of how this would look:

var arduinoPort = process.argv[5]; // "/dev/ttyACM0" on Ryans thinkpad or "/dev/cu.usbmodem1461" on my MBPconst contract = require('./onOff2.js')var SerialPort = require('serialport');
var arduino = new SerialPort(arduinoPort,9600);
contract.deploy(privKey, isDevMode).then(res => {
c = contract.bindEventListener(res, arduino.write(9));
}

Ethereum components : Code => server contract

I built the Ethereum connecting functionality. Quinn helped with the smart contract.

pragma solidity ^0.4; 
contract OnOff {
event StateChange(bool indexed _value, address indexed _id);
address creator; bool state;
function OnOff() public { creator = msg.sender; state = false; } function changeState() public { state=!state;
StateChange(state, msg.sender); }
function GetState() public view returns (bool) {return state; } function () payable { changeState(); }
}

We had a simple smart contract that would fire an event when a function in it was called.

We listened for this event on the server using ethers.js for this. Although I found ethersjs to be much better documented and more consistent that web3js, there’s still a lot left to be desired, and issues with listening for events, getting the correct data from the chain, properly using a wallet to deploy and listen to a contract, waiting for and forcing blocks to be mined had to be discovered as comments on github issues.

But first we have to deploy the contract to the blockchain, testrpc in our case. And before even that we need to compile our solidity code to the EVMs (ethereum virtual machine) native bytecode and get an ABI (application binary interface) so our JS code knows whats up.

const fs = require('fs');
const contractSrc = fs.readFileSync('../contracts/1OnOff.sol', 'utf8');
const solc = require('solc');
const compiledCtrct = solc.compile(contractSrc);
const byteCode = compiledCtrct.contracts[':OnOff'].bytecode;
const abiDefinition = JSON.parse(compiledCtrct.contracts[':OnOff'].interface);

Now we can deploy to a ethereum network!

const ethers = require('ethers')
var providers = ethers.providers;
var network = providers.networks.rinkeby;
var provider =
new providers.JsonRpcProvider('http://localhost:8545', network);
var deployTransaction =
ethers.Contract.getDeployTransaction('0x'+byteCode, abiDefinition);
var privateKey, wallet; function deploy(privKey) {
privateKey = '0x'+privKey;
wallet = new ethers.Wallet(privateKey, provider);
return new Promise(resolve => {
var sendPromise = wallet.sendTransaction(deployTransaction);
sendPromise.then(function(transaction) {
var contractAddress =
ethers.utils.getContractAddress(transaction);
let addy = transaction.from;
var contract = new ethers.Contract(contractAddress,
abiDefinition, wallet);
resolve(contract);
});
})}

We used ethereumjs-testrpc as a drop-in replacement for the ethereum blockchain. This allowed us to manipulate the block-times, since the regular 10s blocktime on ethereum is far too slow for our purpose.

  • We noticed that on mining blocks testrpc would only fire an event denoting the final state and no events for intermediary states. We hacked around this by using ethers.js to forcibly cause blocks to be mined before future transactions are sent. You can do this like so:
deployedContract.changeState().then(res =>  {
provider.waitForTransaction(res.hash).then((transaction) =>
{... // tx has been mined now resolve()})
})

And on the events side you can bind a listener like so (note the trick to get the right event name):

// event name is `on` + event name in snake case
// e.g. stateChange becomes onstatechange
deployedContract.onstatechange = function(val, sender) {
this.getBlock().then(function(block) {...})
}

When people come into our site we trigger the smart contract function which in turn triggers the event on chain which in turn sends a command over serial port to the arduino which is listened for from our arduinos C++ code.

app.get('/', (req, res) => { 
if (contractIsDeployed) contract.sendTx(c)
}

Thanks for reading :)

Hopefully this article can help people see how easy it is to create blockchain connected IoT devices, grow this ecosystem and avoid some common pitfalls and issues. Feel free to reach out if you have any questions, comments or concerns.

--

--