Building a Blockchain based application
When Bitcoin emerged as the first Blockchain application most people missed the significance of the Blockchain itself, preferring to focus on Bitcoin; a classic case of missing the forest by focussing on the trees. In reality Bitcoin is an almost trivial use of a Blockchain. It’s the concept of the Blockchain itself that is in fact the most disruptive thing about Bitcoin and other cryptocurrencies.
In 2013 Bitcoin researcher Vitalik Buterin released the Ethereum Whitepaper which outlined the design of
‘a blockchain with a built-in fully fledged Turing-complete programming language that can be used to create “contracts” that can be used to encode arbitrary state transition functions.’
This makes Ethereum unique. Rather than expecting miners to wastefully churn exponentially increasing power on purposeless hash calculations as a proof-of-work, Ethereum miners, over and above performing the basic blockchain verification calculations, execute the actual code that makes up what Buterin dubbed ‘smart contracts’.
Putting Smart Contracts into practice
Last year I was hired as part of a small team to develop a proof-of-concept smart contract based application for an insurance company that would allow asset owners to insure themselves against damages caused by short-term users of those assets. The parties represented were:
- Owners — people making their asset available to users, and who require insurance
- Claims Assessors — people, whitelisted by the insurance company and paid on a per-claim basis to assess insurance claims made by Owners,
- Liquidity Providers — people, whitelisted by the insurance company, who provided money and who expected some form of remuneration based on the profits of the system as a whole.
- The Insurance Company — the underwriting institution, controller of whitelists, and claim assessor of last resort.
A ‘DAO’ (Decentralised, Autonomous Organisation) was modelled using smart contracts written to the Ethereum blockchain. The smart contracts themselves were written in Solidity and unit-tested using Dapple.
A simple back-end server was developed in NodeJS, using Redux, that managed communication between the blockchain and a collection of front-end web pages. These pages connected to the server via WebSockets and operated in a pure asynchronous manner by exchanging standard Redux actions with the server. Instead of using a database, all data was written to, and read from the Ethereum Blockchain.
To implement this, a single smart contract, the ‘Hub’, was created that was in-turn able to issue, and track related smart contracts that represented each individual insurance contract, and the contracts for the claims assessors and liquidity providers. The ‘Hub’ kept track of all of its spawned contracts and was able to be queried by The Insurance Company’s approved staff via the dedicated web-interface.
Owners were able to initiate a new insurance contract via a simple button-push on a web page, and, if needed, were able to then make a claim on that contract and supply associated ‘evidence’ in support of their claim. As this was just a proof-of-concept the evidence supplied was a simple block of text, but could have comprised photos, or other digital assets.
Once a claim had been made, Claims Assessors were notified via a web page that there was a claim to assess. They could simply click on their ‘next claim’ button to have that claim assigned to them. The Claims Assessors could then either approve, or reject these claims. Claim rejections could be appealed by the Owner who was then required to submit additional evidence in support of their appeal. At that point a the Claim would go back onto the queue and could be picked up and re-assessed by a new Claims Assessor. If she was unable to assess the claim she was able to escalate the claim to The Insurance Company as the assessor of last resort.
Similarly we defined smart contracts and simple UI components to manage the interactions of the Liquidity Providers with the other actors in the network.
All payments were made using Ether attached to the smart contracts.
Overall the project met its goals and provided a valuable learning experience for both the developers and for The Insurance Company. The main lessons learned were
- Non-trivial smart contracts are hard to design properly, hard to test, and hard to debug.
- Because the blockchain is immutable, once a smart contract is written to the blockchain it’s not possible to edit it, or to retract it. Any bugs in a deployed smart contract are there forever. (Hence the use of our own private testnets). A consequence of this was that every time we redeployed the Hub contract we invalidated all of the associated insurance contracts. This is something that can be got around with more careful up-front design however, but is a trap for new players.
- The Ethereum network itself is brittle, with constant innovation in both the tools, the langauges for writing smart contracts, the testing frameworks, and the very structure of the Ethereum system. During the course of the project the Solidity language was updated 4 times, and Ethereum itself was forked. This added considerable drag to the project.
- Only very minimal effort was made to secure the interactions between smart contracts, and no effort was made to minimise the individual transaction costs.
Specific Development processes
The process for developing the the project followed the usual Scrum mechanics, with weekly sprints spanning an eight week period. We used Github for managing source code, and followed the standard forked GitFlow process for promoting code changes from the development team. We used Travis to manage continuous deployment of the server and client code, and also to run the unit tests on the smart contracts themselves. We deployed the server to Heroku, the client to Netlify, and ran our own private shared and local Ethereum testnets which allowed us to run and revise the smart contracts without committing them to the wider public blockchain.
Tools and techniques
The development of a network of smart contracts follows the same basic process as the development of any piece of software. Namely it starts with the framing of the problem into inter-related concepts, the implementation of those concepts as code, the testing of that code, and the deployment of that code into the real-world where it can be used.
For the most part however a typical Ethereum DAPP consists of the following layers
- Server (NodeJS / Web3) that manages communication between the client apps and the blockchain
- Smart Contracts (Solidity, compiled into EVM Byte Code, as well as a corresponding Application Binary Interface (ABI) that is derived from the Solidity source code and which tells other languages how to interact with the compiled contracts)
Conceptualising the problem
Once you start looking at a problem as a network of trustless obligations, a lot of scenarios that are, on the surface, quite different, all start to look very similar. The more experience you gain developing smart contracts, the more natural such problem decomposition becomes. After a while you start looking at everything as a network of trustless obligations.
The tools you use to model this network are the same as for any kind of software decomposition; a good diagramming tool such as Omnigraffle, or a whiteboard and markers, and a handful of experienced developers brainstorming with people who hold the domain specific knowledge being modelled.
Coding smart contracts involves writing Solidity source code in a text editor or IDE, compiling it, testing it, and deploying it, initially to a closed ‘testnet’ and eventually to the public Ethereum blockchain. To do this efficiently developers need to have installed a number of core sub-systems on their local machines, as well as have set up a number of shared resources.
- GoLang (The Go Programming language is needed to run Geth)
- Geth (The Ethereum system implemented in Go)
- a local closed testnet (run by invoking Geth), and a shared testnet running on a cheap cloud server
- NodeJS, and/or
- Python3 (we used both as different developers had different strenghts and Python was very good for just hacking stuff out quickly)
- Redux / React for the front end
- a text editor such as Atom, Sublime, or Textmate (whatever the dev prefers — Atom has plugins for developing and compiling Solidity but in my experience they were more bother than help)
- custom scripts to compile Solidity, generate the Binary files and ABIs as needed, and deploy the compiled contracts to a nominated blockchain (local or shared testnets, or the public blockchain)
- accounts with Jira (Project management), GitHub (source code versioning and reviews), Travis (Continuous delivery), Heroku (Server / shared testnet deployment), Netlify (static websites), AWS, etc as needed.
Unit testing of solidity code can be done using Dapple. Writing such unit tests is a familiar process for any NodeJS developer and, while Dapple includes some notions and restrictions specific to writing smart contracts, the overall structure of a Dapple unit test is similar to standard Mocha testing in Node.
Release management and continuous delivery
Writing, testing, and deploying Solidity applications can be handled with any full-featured CI/CD system such as Travis, which can detect changes, run tests, and report results back to GitHub and Slack, and deploy as needed. We found it useful to both run local testnets for developer level integration testing, and a shared testnet hosted on a cheap cloud server for the integration tests on Travis to access. Setting up a local testnet on Travis was shown to be prohibitively complex and added too much time to the execution of the test suites.
A significant catch with re-deploying smart contracts is the immutability of the blockchain. Any non-trivial project will involve a network of smart contracts that interact with each other. If you superceed a smart contract with a new one, the new one needs to be able to re-establish its relationships with its peers. Designing your smart contracts in advance to be upgradable adds significant complexity but is worth doing. We were bitten by this a number of times.
I believe that the ability to write executable code blocks into a Blockchain is a significant advance and it’s definately early days yet. The space is wide open for further innovation and experimentation.
I’ve been deliberately vague about the details of the actual project as it’s all wrapped up in a bunch of confidentiality agreements. It’s also for that reason I’ve been unable to share actual code samples.