Designing Blockchain D-Apps, Part 4: Technical Development

This is part of a series of articles exploring how to design decentralised apps (D-Apps) using Ethereum. Part 4 of this series covers Technical Development and is designed for Developers.

As part of our exploration of blockchain we’ve been learning the nuances of creating D-Apps, from inception to QA testing. This article is designed to act as a recording of the process, for anyone attempting to follow the same path. If we have something wrong, inaccurate or out of date, let us know in the comments!

Contents of this article:

  • Overview — of the project
  • Insights — into developing D-Apps
  • Future work — we’re planning on doing
  • Technical Walkthrough — step-by-step of developing the D-App
  • Resources — we found along the way

Overview

So far we’ve gone through Initial Scoping, Concept Development and Design & Specification . This left us with a solid understanding of what we planned to build and the following decisions being made:

  • Learning is the goal— the goal of this project is to improve our processes/skills/tools, to generate insights/credibility and have some fun.
  • An Ethereum D-App — that will focus on Peer-t0-Peer lending of books, using a smart contract to store a record on the blockchain
  • Designed as an MVP *— “Is it slightly better than lending a book to someone without the D-App?”
  • Overly Ambitious — We’ve had to cut back our initial specification and design, as we were overly ambitious with our features (not MVP)
  • MVP — Minimum Viable Product, a concept from Lean Startup that focuses on building the most cost effective test for a business hypothesis.

Technical Decisions

We made several decisions before starting development, based on our goals and work to date:

  • We decided to use the Ethereum Javascript API (web3.js) to interact with the blockchain as frameworks abstract away lot of the details.
  • We chose Bootstrap for the front end, as it’s a framework we’ve used a lot and we didn’t want to experiment with the UI.
  • Handling public and private keys can be a tricky subject. We decided it was best to use testrpc to generate accounts.

Insights

A summary of some of what we learnt by building the D-App.

Web3js is in Beta

Using the Ethereum Javascript API (web3.js) to interact with the blockchain, proved more challenging than anticipated. Web3.js was upgraded during development with a number of breaking changes. We decided to reverted back to using the last stable version and we’ll look to upgrade our demo once web3js 1.0 has a stable release and documentation. Other than that web3.js functions much like other JS libraries, if you’re familiar with JQuery, then you should be ok with it.

D-App Considerations

With Ethereum, calls to the blockchain cost Gas. Gas is the fee given to Ethereum miners for running transactions. Gas is priced in ETH, a currency for computing power in Ethereum. This means that transactions cost money and so it’s important to make your D-App as efficient as possible (in this context) to save costs.

Permissions

Permissions in smart contracts are also a key consideration. In our contract the book owner is able to add, remove and return books. The lender can only call the smart contract to lend a book. Without permissions on the methods, the smart contract could be called outside of this D-App and the information manipulated. A flaw we have already identified in our current contract is that anyone can call the “lend item” method. Whilst this presents a low risk for us when lending books, if payments were to be involved, the risk increases. There are also well known examples of recursive call bugs, 51% attacks and unknown, blockchain specific vulnerabilities that are not yet well documented. Keeping on top of these is key for D-App development.

Testing is Different

Testing the D-App took longer than normal because changes to the smart contract required us to re-deploy it. In hindsight, a D-App framework would have improved this process. Also speed and immediacy were not a challenge when working locally with testrpc, but we think it will become more of an issue on testnet/mainnet. This is because on testrpc blocks are mined instantly, on the testnet/mainnet there are delays, depending on network load. This could mean, extended duration for testing as block confirm. To undertake longer term development, we’d likely explore a private Ethereum blockchain for testing prior to deploying to testnet.

Calling external data

Using parameters that are outside of the blockchain can be complex. For example, we made the assumption that we could store time-based values in a smart contract and use them to trigger an action at a later date. However, due to blockchain’s consensus-based system, storing time in a smart contract becomes impossible. Consensus only works if every node reaches an identical state after processing every transaction and block. To work around this, services like Ethereum Alarm Clock allow scheduling of future events, based on blocks that are not yet created on the chain.

Payments are not straightforward

We dropped payments entirely from the project as the process of setting it up proved too complex for our time constraints. We have some persisting questions:

  • How best to store ETH in a smart contract?
  • Can you make payments directly in a D-App?
  • Do you always need a wallet application like Metamask to facilitate?

At the time of writing, this is one of the areas we’re least sure about. Both in terms of technical solution and best practice for security.

Keep it Simple

The lender D-App we’ve now built is simple, but it works. We initialise a smart contract with an owner. The owner can then add / remove their items to the blockchain. The smart contract handles an owner lending out items and then marking each item as returned when they get the item back from the lender. By cutting our specification we managed to deliver on time and we’d encourage anyone else exploring the space to be humble when they plan their D-App.


Future Work

What we plan to do next.

Time based

We’d like to take a look at the Ethereum Alarm Clock (EAC) Service properly. EAC is an smart contract that facilitates scheduling function calls for a specified block in the future. We’d also like to explore game theory as a way to incentivise users to call smart contracts at specific times in the future as a lower-technology alternative.

Integrate Payments

The next step for our lender D-App is to build in payments. We’re not sure if this means creating a Metamask integration or handling payments through web3.js directly. We’re also exploring allowing lenders to buy tokens through an ERC20 smart contract, or building a wallet application like MetaMask.

Play with Storage

To build a fully decentralised app, we’ll need distributed storage. In future sprints we plan to take a closer look at the following storage options:

  • IPFS — https://ipfs.io/ — IPFS is a distributed file system that seeks to connect all computing devices with the same system of files. In some ways, this is similar to the original aims of the Web, but IPFS is actually more similar to a single bittorrent swarm exchanging git objects.
  • Storj — https://storj.io/ — Blockchain-based, end-to-end encrypted, distributed object storage.
  • Swarm — https://github.com/ethersphere/swarm — Decentralised file storage system directly built-in to Ethereum.

Deploying to testnet

We plan to deploy the Lender contract to a real working blockchain and interact with it. This will cover, syncing the testnet blockchain with our local machine, deploying the Lender contract to Ropsten test network and utilising the Truffle Framework to help us automate a lot of the steps.


Code Walkthrough

A step by step guide to doing what we did.

*You can find all our code and short Readme on github — https://github.com/nujded/lender

Development environment on Mac OS

We used an in-memory blockchain called testrpc. To install testrpc, you’ll need:

  1. Node and npm installed (we recommend v8.01 or above)
  2. To run the following commands (from your project route)
npm install ethereumjs-testrpc web3@0.20.1
node_modules/.bin/testrpc

Testrpc creates 10 test accounts to play with automatically. These accounts come preloaded with 100 (fake) ethers.

Note: web3js 1.0 is still in beta so we’ve installed version 0.20.1.

The smart contract

Our Lender smart contract is written in Solidity. The constructor is invoked only once, when the smart contract is deployed to the blockchain. The contractor is used to set the owner of the contract and later used in other methods.

We have six other methods in our smart contract, these are:

  • add/remove items available to lend
  • lend an item
  • return an item
  • a getter, to get the number of items on the blockchain
  • a getter, to get the the item details

Below is the lender contract code with inline comment explanation:

Compiling the Contract

Next, compile the smart contract and deploy it to testrpc blockchain using the node console to compile and web3.js to interact with the contract. To compile the contract, you need to install an npm module call solc:

npm install solc

To start the node console and initialise the web3 objects run the following commands:

node
> Web3 = require('web3')
> web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));

To make sure web3 object is initialised and can communicate with the blockchain, it’s wise to query all the accounts in the blockchain. You should see a result like below:

> web3.eth.accounts
[ ‘0x14507e93152f58f305be33436e039d7526305d66’,
‘0x926042ec860331046e425281fe63481ff11c0db1’,
‘0x51c227ea44a747d8f04c48171d23af6828bdf6fa’,
‘0xb6156c8559f40beba3427ec4cd396b37f50e8436’,
‘0xe07643183238f8dcdefd49087c1edf325a4094d1’ ]

To compile the contract, load the code from Lender.sol in to a string variable and compile it.

> code = fs.readFileSync('Lender.sol').toString()
> solc = require('solc')
> compiledCode = solc.compile(code)

This will give you a contract object (compiledCode) which contains the bytecode and an interface of the contract (called abi). The abi tells the contract user what methods are available in the contract. You will need both of these to deploy your smart contract.

Deploying the Contract

> abiDefinition = JSON.parse(compiledCode.contracts[':Lender'].interface)
> LenderContract = web3.eth.contract(abiDefinition)
> byteCode = compiledCode.contracts[':Lender'].bytecode
> deployedContract = LenderContract.new({data: byteCode, from: web3.eth.accounts[0], gas: 4700000})
> contractInstance = VotingContract.at(deployedContract.addr

To check the contract has been deployed successfully, try to output the deployedContract address:

> deployedContract.address
'0x97e00da837edc396a536f347ab12a5f9ccda5075'

You will need the deployedContract.address and compiledCode.contracts[‘:Lender’].interface to get the demo D-app working.

Get the D-App working locally

To get the Lender D-App working locally, you can download the source code from Github (https://github.com/nujded/lender) and follow the steps in the readme.md file.

Feedback and crits

If you have any thoughts or questions, please share them in the comments!


List of resources

A list of resources we found along the way.

  1. Ethereum Whitepaper — https://github.com/ethereum/wiki/wiki/White-Paper
  2. Ethereum Javascript API (web3.js) — https://github.com/ethereum/web3.js/
  3. Fast Ethereum RPC client for testing and development — https://github.com/ethereumjs/testrpc
  4. Solidity Documentation — http://solidity.readthedocs.io/en/develop/index.html
  5. Ethereum Alarm Clock Service — http://www.ethereum-alarm-clock.com/
  6. Dapp Developer Resources — https://github.com/ethereum/wiki/wiki/Dapp-Developer-Resources
  7. Ethereum Contract Tutorials — https://dappsforbeginners.wordpress.com/
  8. https://ipfs.io/