Step 1: Hook multichain daemon and write to a steam

In the previous step, we’ve got our two cloud nodes setup and connected to the same blockchain. Now we need a way to connect the output of our blockchain to our web application. There are many ways we could do this (for example, we could use drush to update Drupal, or we could use a reverse proxy and post data via http request), but in this demo I’ve chosen to use web sockets and pipes. The reason behind this is that we can subscribe our Angular application to the web socket and then we get a ‘real time’ update every-time that a block is published to the blockchain. There are many ways to skin a cat and I’ve chosen the more interesting over the more usual!

So the first step is for us to hook up the daemon. In the multichain runtime parameters https://www.multichain.com/developers/runtime-parameters/ we can see the ‘blocknotify’ command, a command executed every time a new block is published to the blockchain.

blocknotify Execute this command when a new block is added at the end of the current chain. A %s in the command parameters will be substituted with the block hash.

So, the plan is simply to write the block hash to a FIFO in linux, then subscribe to this file through our ExpressJS reverse proxy.

# login to node 2

cd /var/www/medium-demo-angular

mkdir server

cd server

mkfifo blocks.fifo # Write block hashes to fifo when initalize daemon

multichaind medium-demo-blockchain@159.65.5203:7891 -blocknotify="echo '%s' > /var/www/medium-demo-angular/server/blocks.fifo" -daemon #Check this is working

nano fifo.sh

fifo.sh

#!/bin/bash pipe=/var/www/medium-demo-angular/server/blocks.fifo trap "rm -f $pipe" EXIT while true

do

if read line <$pipe; then

echo $line

fi

done echo "Reader exiting" #exit

Now we can run the script!

sh fifo.sh

Now if we simply add content to https://medium-demo-drupal.blockbinder.com (or your node 1), the terminal will be subscribed to the FIFO and you should get output like the below. Hashes from our blockchain!

All going well, your command line is now full of wonderful block hashes!

cd /var/www/medium-demo-angular

mkdir server

cd server # Setup express server

nano package.json

package.json

{

"name": "auth",

"version": "1.0.0",

"description": "",

"main": "index.js",

"scripts": {

"test": "echo \"Error: no test specified\" && exit 1"

},

"author": "",

"license": "ISC",

"devDependencies": {},

"dependencies": {

"body-parser": "^1.18.2",

"express": "^4.16.2",

"ws": "^5.0.0"

}

}

Install packages

npm install

node server.js

Setup express server

const express = require('express'), bodyParser = require('body-parser');

const http = require('http');

const url = require('url');

const WebSocket = require('ws');

const app = express();

app.use(bodyParser.json())

var exec = require('child_process').exec; const server = http.createServer(app);

const wss = new WebSocket.Server({ server });

var fs = require('fs') wss.broadcast = function broadcast(msg) {

console.log(msg);

wss.clients.forEach(function each(client) {

client.send(msg);

});

};

const location = url.parse(req.url, true);

// You might use location.query.access_token to authenticate or share sessions

// or req.headers.cookie (see

console.log('Server is connected'); wss.on('connection', function connection(ws, req) {const location = url.parse(req.url, true);// You might use location.query.access_token to authenticate or share sessions// or req.headers.cookie (see http://stackoverflow.com/a/16395220/151312 console.log('Server is connected'); // PIPE LISTENER

const fd = fs.openSync('/var/www/medium-demo-angular/server/blocks.fifo', 'r+')

const stream = fs.createReadStream(null, {fd})

stream.on('data', data => {

function puts(error, stdout, stderr) { sys.puts(stdout) }

exec("multichain-cli medium-demo-blockchain liststreamitems root", function(error, stdout, stderr) {

if (!error) { // things worked!

// console.log(stdout)

wss.broadcast(stdout); } else {

console.log(stderr)

// things failed :( }

}); }) ws.on('close', function(code, reason) {

console.log(code);

console.log(reason);

}); }); app.get("/retrieve-database" , function (request, response) { function puts(error, stdout, stderr) { sys.puts(stdout) }

exec("multichain-cli medium-demo-blockchain liststreamitems root", function(error, stdout, stderr) {

if (!error) { // things worked!

console.log(stdout)

response.send(stdout) } else {

console.log(error)

// things failed :( }

});

}); server.listen(3500, function listening() {

console.log('Listening on %d', server.address().port);

});

Congrats, we now have an ExpressJS reverse proxy opening a websocket which is subscribed to a pipe! Cool isn’t it (not the most efficient method but definitely the most fun). We now need to subscribe Angular to a websocket, ensuring real-time updates to the HTML.