Your personal Blockchain using NodeJS

Due to popularity of the blockchain we will create your own in  roughly 10 minutes, to understand how it works and have fun  mining our coins !

Basic requirements:

  • NodeJS
  • NPM
  • CMD/ Terminal /BASH

First Steps:

  • Create a JavaScript file within the root of the folder, call it main.js
  • Go in the folder using terminal/cmd/bash and run“npm init” and follow the command prompts
  • Install the dependency with the command “npm install crypto-js

Implementing the Blockchain

Create a class called Block with a constructor which takes 5 properties:

    • index (optional): Where the block sits within the chain
    • timestamp: When the block was created
    • data: Any type of data that we would like to store in the block. It may be useful to store the details of the transaction here, such the sender and receiver
    • previousHash: A string that contains the hash of the block before. This is how we verify integrity of our blockchain
    • hash: Contains the hash of our block
class Block {
 constructor(index, timestamp, data, previousHash = '') {
    this.index = index;
    this.timestamp = timestamp;
    this.data = data;
    this.previousHash = previousHash;
    this.hash = this.calculateHash();
    this.nonce = 0;
 }
}

 

Create a function that can calculate the hash function of a block. This is done by taking the properties of the block and running them through a hash function and return the hash. This is how we can identify the block on the blockchain. For this example, we will use sha-256 as a hash function which we previously install via npm. We now will need to import this library within our main.js file so we can use it within our calculateHash() function which takes all the parameters of the Block constructor.

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

Now lets create a new class for our blockchain called Blockchain and give it a constructor that’s responsible for initializing our blockchain. We will store our blockchain within an array called chain.

The first block on a blockchain is called the genesis block which should be created manually. We can create a method to do this called createGenesisBlock(), which will return a new Block like the following with some dummy data. Since we haven’t had a previous hash, we will just put 0.

 

We can now update our constructor so that we initialise the chain not as an empty array but as an array that contains our Genesis block

 

class Blockchain {
  constructor() {
    this.chain = [this.createGenesisBlock()];
    this.difficulty = 2;
  }

  createGenesisBlock() {
    return new Block(0, "12/01/2017", "Gensis block", "0");
  }
}

 

Now we can create some other methods that will be useful for us later called getLatestBlock(), and addBlock() which will receive a newBlock.The getLatestBlock method simply returns the latest block within the chainThe addBlock() method is responsible for adding a new block onto the chain but it needs to do some work before it can just push blocks on the array. First is needs to set the perviousHash property of newBlock to the last block’s hash on our chain. So we get the lastest block and its hash by doing the followingNext thing that we need to do since we have changed our block, we need to recalculate it’s hash. Anytime we change any properties of our block, the hash function should be changed as well. Finally we can add this newBlock onto the chain array.

 

class Blockchain {
  constructor() {
    this.chain = [this.createGenesisBlock()];
    this.difficulty = 2;
  }

  createGenesisBlock() {
    return new Block(0, "12/01/2017", "Gensis block", "0");
  }

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

  addBlock(newBlock) {
    newBlock.previousHash = this.getLatestBlock().hash;
    newBlock.mineBlock(this.difficulty);
    // This is no longer needed since we are mining to get our hash
    // newBlock.hash = newBlock.calculateHash();
    this.chain.push(newBlock);
  }

  isChainValid() {
    for(let i = 1; i < this.chain.length; i++) {
      const currentBlock = this.chain[i];
      const previousBlock = this.chain[i - 1];

      if (currentBlock.hash !== currentBlock.calculateHash()) {
        return false;
      }
      if (currentBlock.previousHash !== previousBlock.hash) {
        return false;
      }
      return true;
    }
  }
}

Bonus: add the following like to the function addBLock() to have a incremental index for each node

           newBlock.index= (this.getLatestBlock().index) +1;

  • One thing to note, is that in reality it not this easy to add a block because there are numerous checks in place. However, just for our blockchain this is enough to demonstrate how a blockchain actually works. To test this, at the bottom of main.js create an instance of our blockchain, add a few blocks, and console a stringify version of our chain so its easier to read.
  • Go ahead and run the our main.js file and see what our blockchain looks like within the terminal. We can see how the blocks reference each other!
  • Blockchains are powerful because once they have been added, they cannot be changed without invalidating the rest of the blockchain. Our current implementation does not verify the integrity of our blockchain. Lets correct this by added a new method to our class called isChainValid(), which will return true or false depending on if its valid or not. In order to verify the integrity we will need to loop over all the blocks within our blockchain. Note that will wont start with block 0 since that’s our gensis block.Within our loop we will compare the currentBlock and the previousBlock in order to verify if that they are linked together correctly. First we test if the hash of the block is still valid. If the following are not equal we know something is wrong and we need to return false. We also we need to check if it points to the correct previousBlock hash. If its completes the loop without any issues then we can return true.

Proof of Work

In the current state we can create new blocks really quickly by creating a transaction, compute it’s hash, and add it to an array. Modern computers can do this extremely fast, however we don’t want people to create hundreds of thousand blocks per second and spam our blockchain. Also, we have a security issue by being able to change the contents of a block and then recalculate the hashes for all the blocks after that. You will end up with a valid chain even though it was tampered with. To resolve this, blockchains use something called proof of work.

With the proof of work mechanism, you have to prove that you have put a lot of computing power into making a block. For example, bitcoin requires the hash of a block to begin with a certain amount of zeros. Since you cannot influence the output of a hash function, you simply have to try a lot of combinations and hope you get lucky with the hash that has a sufficient number of zeros in front of it. This requires a lot of computing power and is also called the difficulty. The difficulty is set so there is a steady amount of blocks. In Bitcoin’s case, the goal is to create one new block every 10 minutes. As computers get faster over time they will require less time to mine a new block. In order to compensate for this, the difficulty will simply be increased. So let’s now implement this!

 

Within our Block class, lets add a new method called mineBlock() that takes a property called difficulty. In this method we will try to make the hash of our block begin with a certain amount of 0’s. Below is a quick way to make a string of zeros that is the exact length of the difficulty. We will also calculate the hash of the block and log this so we can see the output of the hash that was just mined.

 

We currently have an issue… The hash won’t change unless we change the contents of our block, meaning what we currently have an endless loop! What can we change inside of our block? Since we dont want to change in of the current properties of the block, we can do this by adding a nonce value. A nonce value is random and doesn’t have anything to do with your block, but can be changed to something random. Lets add this to our class.

 mineBlock(difficulty) {
    while(this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0")) {
      this.nonce++;
      this.hash = this.calculateHash();
    }
    console.log("Block mined:: ", this.hash);
  }
  • Within our while loop we will increment the value as long as our hash doesn’t start with enough 0’s.We need to take the nonce value into account when we are getting our hash as well.

 

  • Lets update our addBlock method and add the difficulty as a property of the Blockchain class. Also lets comment out some of the code that we were using before and add some different logs within our code.After you run this again, you will now see that our hashes start with two 0’s and this was due to us setting the difficulty to 2. However, we also saw that this was done really fast, making it easy for a spammer to generate fake blocks or tamper with the entire chain. To counteract this, we just have to increase the difficulty. Try increases the difficulty to 4 and see how long it takes.

 

  • Using this mechanism we can control how fast new blocks can be added to our blockchain.

Final Thoughts

I’m sure that after this article we’ll understand more about this interesting technology!

The code is pretty much all here, just run it and enjoy your personal blockchain !

github repo :  https://github.com/msirrele/