Create your own tiny blockchain using JavaScript

April 16, 2018
by Rahil Shaikh
  • JS Blockchain

Blockchain and Bitcoin are a few words that are used a lot these days by the Media. But do we really know what is blockchain? In this article I try to highlight a few technical aspects of Blockchain. We will do this building our own tiny Blockchain in Javascript.

Of course, our blockchain will not be anything fancy, just a simple program that demonstrates how blockchain works. First of all let’s understand what is Blockchain.

The blockchain is a list of records called as blocks that are linked to each other forming a ledger. This ledger is secured cryptographically (the hash of the previous block is a part of the data for the next block) using proof-of-work and stored in a decentralized way.

The distribution and the cryptographic security forming a chain makes data in Blockchain technology practically unalterable. There is a whole lot of debate between private blockchain and public blockchain, we won’t get much into that. Without further ado, let’s start with creating our own Blockchain.

Building the Blockchain

Add this to your package.json

package.json
{
  "name": "jsblockchain",
  "version": "1.0.0",
  "description": "",
  "main": "Block.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.2",
    "crypto-js": "^3.1.9-1",
    "express": "^4.16.3",
    "uuid": "^3.2.1"
  }
}

Run npm install.
This will install all the dependencies we will need.

Next, let’s create a class Block. This will represent a Block in the Blockchain.

Block.js
const SHA256 = require("crypto-js/sha256");
class Block {
    constructor(index, timestamp, data, prevHash=''){
        this.index = index;
        this.data = data;
        this.timestamp = timestamp;
        this.prevHash = prevHash;
        this.hash = this.calculateHash();
    }

    calculateHash(){
        return SHA256(this.index + this.timestamp + JSON.stringify(this.data) + this.prevHash).toString();
    }
}

module.exports = Block;

Here we have a class that stores, various properties of a Block. We also have a calculateHash method that will calculate the hash of the data combined. prevHash is the hash of the previous block. This is important so when we form a chain, and if an attacker tries to change a Block in the Blockchain, he will have to recalculate the hash of all the following block. Which is practically impossible in a decentralized system sealed by proof of work.

Now that we have our block class ready. Let’s add a class named Blockchain. This class will represent a Blockchain.

Blockchain.js
const Block = require('./Block');
class Blockchain {
    constructor(){
        this.chain = [this.createGenesisBlock()]; //initiaize with a genesis block
    }

    createGenesisBlock(){
        return new Block(0, Date.now(), 'Genesis Block', 0);
    }
}

The first block in the blockchain is called the Genesis Block. This block is seeded by the creator of the blockchain. Here above we are initializing the blockchain with the Genesis block.

Next, let’s add a method which will add a new block to our Blockchain.

Blockchain.js
const Block = require('./Block');
class Blockchain {
    constructor(){
        this.chain = [this.createGenesisBlock()]; //initiaize with a genesis block
    }

    createGenesisBlock(){
        return new Block(0, Date.now(), 'Genesis Block', 0);
    }

    /** Add a new block */
    addBlock(newblock){
        newblock.prevHash = this.getLastBlock().hash;
        newblock.hash = newblock.calculateHash();
        this.chain.push(newblock);
    }

    getLastBlock(){
        return this.chain[this.chain.length - 1];
    }
}

We have also added a method to get the last block in the blockchain. This is required because we need to store the hash of the previous block with the current block.

Next, the people using our Blockchain will need a method that will validate the chain. For this we will create a method isChainValid. In this method, we will iterate through the entire chain and validate each and every block.
We must check if the hash store in the chain matches the calculated hash. And also, we will validate if the value in the prevHash of the current block is equal to hash property of the previous Block.

Blockchain.js
const Block = require('./Block');
class Blockchain {
    constructor(){
        this.chain = [this.createGenesisBlock()]; //initiaize with a genesis block
    }

    createGenesisBlock(){
        return new Block(0, Date.now(), 'Genesis Block', 0);
    }

    /** Add a new block */
    addBlock(newblock){
        newblock.prevHash = this.getLastBlock().hash;
        newblock.hash = newblock.calculateHash();
        this.chain.push(newblock);
    }

    getLastBlock(){
        return this.chain[this.chain.length - 1];
    }

    /** validates the chain */
    isChainValid(){
        for(let i=1; i < this.chain.length; i++){
            const currentBlock = this.chain[i];
            const prevBlock = this.chain[i-1];
            if(currentBlock.hash !== currentBlock.calculateHash()){
                return false;
            }

            if(currentBlock.prevHash !== prevBlock.hash){
                return false;
            }
           
        }
        return true;
    }
}

module.exports = Blockchain;

This completes our Blockchain class.

Now it’s time to test our chain. Create another file named tests.js.

tests.js
const Blockchain = require('./Blockchain');
const Block = require('./Block');

var chain = new Blockchain();
chain.addBlock(new Block(1, Date.now(), {amount: 10}));
chain.addBlock(new Block(2, Date.now(), {amount: -15}));

const valid = chain.isChainValid();
console.log('Is chain Valid?', valid);

Run tests.js. If everything is setup correctly it should tell us our chain is valid. Now let’s try to change something in our chain and see if the chain becomes invalid.

I’ll edit the same tests.js file.

tests.js
const Blockchain = require('./Blockchain');
const Block = require('./Block');

var chain = new Blockchain();
chain.addBlock(new Block(1, Date.now(), {amount: 10}));
chain.addBlock(new Block(2, Date.now(), {amount: -15}));

//Attacker Trying to manipulate the chain to gain advantage
chain.chain[2].data = { amount: 20};

const valid = chain.isChainValid();
console.log('Is chain Valid?', valid);

So what we are doing here is taking our chain and changing the data of the 3rd block of the chain. Now when we run the file using node tests.js. The program says the chain is invalid.

REST APIs

To make it easier to test our blockchain, I have also created REST APIs.

app.js
const express = require('express');
const app = express();
const Blockchain = require('./Blockchain');
const Block = require('./Block');
const uuid = require('uuid');
const bodyParser = require('body-parser');
var chains = {};

app.use(bodyParser());

app.get('/chain/init', (req, res)=>{
    const chainId = uuid();
    chains[chainId] = new Blockchain();
    res.send(chainId);
});

app.get('/chain/:chainid/isvalid', (req, res)=>{
    const chainId = req.params.chainid;
    const blockchain = chains[chainId];
    res.send(blockchain.isChainValid());
});

app.get('/chain/:chainid', (req, res)=>{
    const chainId = req.params.chainid;
    const blockchain = chains[chainId];
    res.json(blockchain.chain);
});

app.post('/chain/:chainid/block', (req, res)=>{
    const data = req.body;
    const chainId = req.params.chainid;
    const blockchain = chains[chainId];
    const timestamp = Date.now();
    const index = blockchain.chain.length;
    blockchain.addBlock(new Block(index, timestamp, data));
    return res.json(blockchain.chain);
});

app.listen(3000);

You can run the express server using node app.js and use a tool like Postman to test our APIs

A note on Proof-of-work and Nuance

Here we have built blockchain, but it’s not really secure. The reason is that it’s very easy for an attacker to alter the data in the blockchain and rehash the entire chain. That’s where proof-of-work comes in. In proof-of-work, it’s not just enough to hash the block, but there is a need for a very specific condition to be met for the hash to be valid. Bitcoin, for example, requires the hash to start with a specific number of zeroes, this is also known as the difficulty. But how will we generate a hash that starts with zeroes with the same data? To solve this problem Bitcoin uses a nuance value, which is just a random number generated and added to the data until a valid hash is found.

Conclusion

Thus we have seen how the Blockchain works and we have created a tiny Blockchain using Javascript. I would like to give a shoutout to Savjee, for his content on Blockchain, this article has taken ideas from his brilliant video on creating a blockchain. Watch here.

Further Links

About

Engineer. Blogger. Thinker. Loves programming and working with emerging tech. We can also talk on Football, Gaming, World Politics, Monetary Systems.

Free PDF

Subscribe and get AngularJS Tips PDF. We never spam!
First Name:
Email:

3 comments

  1. |

    Nice intro to blockchain. It was a perfect 101 introduction that I was looking for. Thanks!

Leave a Comment