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
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:
- 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
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 set
s a value and then get
s 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:
- Deploy a contract.
- Send it transactions.
- Query results from the contract.
- 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.
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.
Developer Relations, Technical Writing and Editing, (Board) Game Design, Education, Explanation and always more to come. English/Australian living in Berlin, Herzlich Willkommen!