There are so many buzz around blockchain these days everywhere and at ParallelScore we like buzzes especially around emerging technologies. This time we narrowed down the buzz to focus on tendermint. You learn more about it by visiting https://tendermint.com. This is a first attempt into the world of tendermint. A brief summary of the steps taken to implement a minimal blockchain application using tendermint.

Language of choice: javascript(node).

Setup: tendermint on local machine

I downloaded one of the prebuilt binaries and copied to the appropriate directory. You can find them here https://github.com/tendermint/tendermint/releases. Since I use a MacBook, I downloaded the zip tendermint_0.22.8_darwin_amd64.zip which was the latest as at the time this writing. Downloaded and unzipped to get an executable file(unix executable) then simply moved the file to my /usr/local/bin directory, and boom its all set.

More detail: https://tendermint.com/docs/introduction/install.html.

Verify: initialize tendermint

To verify your installation and to initialize tendermint, you just need to type in the following commands in your terminal(macOS) `tendermint init` and then `tendermint node`. After the last command you should see a lot of activity(logs) in the terminal. You can cancel out of this anytime by pressing `CTRL + C`. And you can also clear all generated data by executing `tendermint unsafe_reset_all`.

ABCI: application blockchain interface 

Next we need to set up an application blockchain interface server(abci) which our tendermint installation will connect to. So to clarify the flow, a client app will make a request(an http request for example) to the tendermint process which then forwards a request(which can be a transaction or a query) to an abci server(which will be your application). Furthermore your application server should be started first before starting up tendermint (More on this below). Check out this link https://tendermint.com/docs/app-dev/getting-started.html#first-tendermint-app. For me I used the abci package from npm found here https://www.npmjs.com/package/abci. Below is a sample code of how to use this package.

// filename: app.js

let createServer = require(‘abci’);

let server = createServer({
Info (request) {
console.log(‘got info request’, request)
return { … }
},
// implement any ABCI method handlers here
}
server.listen(26658);

We can then start the server from terminal by running the command ’node app.js’. So with your application running you can now go ahead and start up tendermint like so `tendermint node`.

 

KX: What is an handler?

Before we proceed further, just a brief word on handlers. See the snippet above where we passed in an object to createServer. The `info` method is a handler. Now the abci specification expects specific handlers to be implemented like above to handle different operations. The info handler for example is called when tendermint initially connects to your abci application. Now if you want to handle a scenario when a transaction is sent, you have to implement two handlers

  1. checkTx: this will be called by tendemint to verify that the transaction is valid. Note that you are in total control of the verification logic.
  2. deliverTx: This will handle the state modification logic.

For an example on how this looks like in javascript code you can check out the counter example on GitHub https://github.com/tendermint/js-abci/blob/master/example/counter.js.

So what is state modification? For your application, you could initialize a simple javascript object, which we call the state object. This object will hold all data we want to store. So what we are saying about deliverTx above is that, we can add logics to modify this state object. So our application sample above will look like this

// filename: app.js

let createServer = require(‘abci’);

let state = {};

let server = createServer({
Info (request) {
console.log(‘got info request’, request)
return { … }
},
  checkTx (request) {
  },
  deliverTx (request) {
  },
// implement any ABCI method handlers here
}
server.listen(26658);

Note that every handler will receive a request object which has properties such as tx in cases where we are dealing with a transaction.
For example the following request

curl ‘localhost:26657/broadcast_tx_commit?tx=“tendermint”’

Notice the query parameter `tx`. We can access the data in tx from our request object like so `request.tx`.

 

More on the request object passed to the handlers. The data contained in the handlers usually come as base64 string so we need to convert to something useful. For my case I found the node `atob` https://www.npmjs.com/package/atob and `btoa` https://www.npmjs.com/package/btoa libraries very useful. Consider the following request

curl ‘localhost:26657/broadcast_tx_commit?tx=“tendermint”’

Can be handled in your code as follows

let createServer = require(‘abci’)
let atob = require(‘atob’);

let server = createServer({
deliverTx (request) {
let str = atob(request.tx); // decode from base64
console.log(str); // tendermint
return { … }
}

Conclusion

And thats it. Learning tendermint will still be an ongoing project for me. Like I mentioned earlier this is my first attempt. I’d like to learn more about best practices and design patterns when structuring applications built on top of tendermint. Also how to handle security concerns and more.
I’ll add more articles on these subjects as I cover them.