Programming
Article

Building Your First Blockchain App with Eris

By Chris Ward

A few months ago I was at the Berlin Blockchain awards, and it appears that ‘blockchain’ is the new buzzword that startups and tech-folk like to throw into everything, without completely understanding the concepts behind it.

Whether you believe that blockchain is just a new buzzword for the industry or a truly revolutionary technology, developers are often uncertain of how they can use the blockchain concept in their applications. Eris Industries’ solution might make this a bit easier.

Eris Industries packages blockchain and smart contract concepts to make them more usable and apply them to your project. The best projects for this sort of technology are ideas that need a form of decentralized trust and security.

In this article, I will create a demo application that is a library of names of privileged users for a hypothetical situation. In the final section of the tutorial, the application will let you change a name in the list and check the values.

Installation and Setup

Installing Eris is confusing, the instructions on their homepage didn’t work for me, and I ended up following the steps in their more in-depth instructions instead. For me, on my Mac, I installed Docker Toolbox (Docker is a requirement) and then installed Eris with Homebrew.

Once installed, setup Eris with the following command which will create configuration files and download the (large) Docker images required:

eris init

Start Eris Process

Images Downloading

Process Completed

Note: It isn’t clear in the Eris documentation, but it’s best to run the rest of the commands in this tutorial within the Docker context. This mainly applies to Mac and Windows, find more details here.

Granting Access

Start an Eris keys service for authentication with:

eris services start keys

This command starts a service based on the keys service definition, these definitions are found inside the ~/.eris/services folder. Eris creates some by default for pre-defined application types (e.g. Tor, ipfs, and bigchaindb), but you can also create your own.

Now create some keys to allow particular users access to the service and application:

eris keys gen

Save the key for later use, replacing the key value with the key you just generated:

eris keys export E0F4BA1E6D15503074239A663101547074889574

And use the following command to check what keys are available across your host machine and containers:

eris keys ls

If you want to read more about keys with Eris, then I recommend their key tutorial.

Creating a Blockchain

Next, create a blockchain with a name (library_chain) and a type (simplechain):

eris chains make library_chain --account-types=Root:2,Full:1 simplechain

If you dig inside the hidden ~/.eris folder you will see the files generated from this command. Inside ~/.eris/chains/library_chain are a series of files:

Eris Hidden Files

  • genesis.json: Tells eris how to instantiate a particular blockchain, providing the “genesis” state of the blockchain.
  • accounts.csv and validators.csv: You can use two files later to create a new genesis.json if it gets lost.
  • addresses.csv: Has the addresses and the “names” of the nodes.

Now you’re ready to instantiate the Blockchain:

eris chains new library_chain --dir ~/.eris/chains/library_chain/library_chain_full_000

Check that the chain exists and is running:

eris chains ls

Chain Existing

Contracts

A ‘smart contract’ is a popular blockchain-related term for “an agreement that the blockchain will analyze transactions you send it”. As a simple Eris related example, you will create a contract that sets a value and then gets it back again. Start by creating a folder for the application and moving into it:

cd ~/.eris/apps
mkdir library
cd library

Create a library.sol file inside this folder, and add the following to it:

contract Library {
  string storedData;

  function set(string x) {
    storedData = x;
  }

  function get() constant returns (string retVal) {
    return storedData;
  }
}

This file should be reasonably self-explanatory, it defines a string variable and the relevant set and get functions.

Next create an epm.yaml file that is read by the Eris package manager, looking for jobs within it to run:

jobs:

- name: setStorageBase
  job:
    set:
      val: "Book Title"

- name: deployStorageK
  job:
    deploy:
      contract: library.sol
      wait: true

- name: setStorage
  job:
    call:
      destination: $deployStorageK
      data: set $setStorageBase
      wait: true

- name: queryStorage
  job:
    query-contract:
      destination: $deployStorageK
      data: get

- name: assertStorage
  job:
    assert:
      key: $queryStorage
      relation: eq
      val: $setStorageBase

Some of these job declarations make more sense than others, read the job specification document for more details.

Next, you need to tell Eris to look at these two files, generate the other files it needs and then:

  1. Deploy a contract.
  2. Send it transactions.
  3. Query results from the contract.
  4. Assert results.

First, get the address of where you want to deploy the contract:

addr=$(cat ~/.eris/chains/library_chain/addresses.csv | grep library_chain_full_000 | cut -d ',' -f 1)

echo $addr

And inside the application folder (~/.eris/apps/library) invoke the Eris package manager upon the files you created and deploy the contract to the blockchain:

eris pkgs do --chain library_chain --address $addr

This command will find the jobs you declared, deploy them and then return the assertion made, which in this case, is that the book title is a string.

Assert Results

Making an Application

Now it’s time to write some code that interacts with the blockchain and performs actions upon it. This is still a simple example that allows users to set a new value for the book in the blockchain, and to then check the current value.

The example will use Node.js, so first create a package.json file in the ~/.eris/apps/library folder with the following contents:

{
  "name": "library_app",
  "version": "0.0.1",
  "dependencies": {
    "eris-contracts": "^0.13.1",
    "prompt": "*"
  }
}

Next, create an app.js file, and add the following:

'use strict';

var contracts = require('eris-contracts');
var fs = require('fs');
var http = require('http');
var address = require('./epm.json').deployStorageK;

var abi = JSON.parse(fs.readFileSync('./abi/' + address, 'utf8'));
var accounts = require('../../chains/library_chain/accounts.json');
var chainUrl = 'http://192.168.59.103:1337/rpc';
var manager = contracts.newContractManagerDev(chainUrl,
  accounts.library_chain_full_000);
var contract = manager.newContractFactory(abi).at(address);

This first code block creates requirements and then some Eris specific variables for the abi (a ‘translator’ between the blockchain and the application), the accounts mentioned earlier, the IP address of the chain (in my case, a boot2docker ip) and initiates a manager and contract for the chain.

A couple of specifics aside, most of the rest of the code is more familiar JavaScript territory, creating a Node server, listening for requests and writing and reading data to the blockchain as appropriate:

var server;
server = http.createServer(function (request, response) {
  var body;
  var value;

  switch (request.method) {
    case 'GET':
      console.log("Received request for details.");
      contract.get(function (error, result) {
        if (error) {
          response.statusCode = 500;
        } else {
          response.statusCode = 200;
          response.setHeader('Content-Type', 'application/json');
          response.write("You have requested details on: " + result);
        }
        response.end('\n');
      })

      break

    case 'PUT':
      body = '';

      request.on('data', function (chunk) {
        body += chunk;
      });

      request.on('end', function () {
        console.log("Received request to set title to " + body + '.');

        contract.set(body, function (error) {
          response.statusCode = error ? 500 : 200;
          response.end();
        });
      });

      break;

    default:
      response.statusCode = 501;
      response.end();
  }
});

server.listen(process.env.NODE_PORT, function () {
  console.log('Listening for HTTP requests on port ' + process.env.NODE_PORT +
    '.');
});

Note: You may need to set the value of NODE_PORT to a suitable value.

Curl the application and PUT a value:

curl --request PUT --data Jane http://localhost:1111
# Or whatever your node IP address is

Now if you GET the application, you will see the value has changed:

curl http://localhost:1111

Look at the output from the curl command and the Node.js application to get a slightly clearer idea of what is happening behind the scenes.

‘Conclusion’

On first impressions it may seem that it is complex to get started with a basic application using Eris. But unless you encountered any problems, these setup steps shouldn’t actually take too long and then you’ll be ready to start using a blockchain in your applications.

Actually coding an application that uses a blockchain is a big and complex topic and I have barely touched the surface. For next steps, I recommend you make sure you have a bonafide use case for a blockchain in your application and then read the tutorials on the Eris website.

It’s going to be a bumpy and at times confusing journey but I would love to hear your experiences, thoughts and questions.

No Reader comments

Recommended

Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in Front-end, once a week, for free.