When we’re trying to learn something new, it can oftentimes be tempting to dive headfirst into documentation, articles, and conceptual explanations. While all of that is certainly important, programmers have a great tool in their arsenal for understanding complex topics that they often take for granted.

Building models for different topics in code can help us understand how different pieces of an idea fit together and operate in practice.

In this tutorial, I’ll show you how to build a basic blockchain with some relatively simple Javascript.


What is a Blockchain?

It can be helpful to think of blockchains as augmented linked lists, or arrays in which each element points to the preceding array.

Within each block (equivalent to an element in an array) of the blockchain, there contains at least the following:

  • A timestamp of when the block was added to the chain
  • Some sort of relevant data. In the case of a cryptocurrency, this data would store transactions, but blockchains can be helpful in storing much more than just transactions for a cryptocurrency
  • The encrypted hash of the block that precedes it
  • An encrypted hash based on the data contained within the block(Including the hash of the previous block)

The key component that makes a blockchain so powerful is that embedded in each block’s hash is the data of the previous block (stored through the previous block’s hash). This means that if you alter the data of a block, you will alter its hash, and therefore invalidate the hashes of all future blocks.


Creating a Block

While this can probably be done with vanilla Javascript, for the sake of simplicity we are going to be making a Node.js script and be taking advantage of Node.js’s built-in Crypto package to calculate our hashes.

We can define a block in code like so:

const crypto = require('crypto'); // Import NodeJS's Crypto Module

class Block { // Our Block Class
    constructor(data, prevHash = "") {
        this.timestamp = Date.now(); // Get the current timestamp
        this.data = data; // Store whatever data is relevant 
        this.prevHash = prevHash // Store the previous block's hash
        this.hash = this.computeHash() // Compute this block's hash
    }
  
    computeHash() { // Compute this Block's hash
        let strBlock = this.prevHash + this.timestamp + JSON.stringify(this.data) // Stringify the block's data
        return crypto.createHash("sha256").update(strBlock).digest("hex") // Hash said string with SHA256 encrpytion
    }

}

Note that we use SHA256 encryption to hash our function. This is the standard cryptographic hash function that is used in most blockchains because it is incredibly easy to calculate, but incredibly hard to reverse.

We can then create instances of these blocks like so:

let a = new Block({from: "Joe", to: "Jane"}, precedingHash = "0")
let b = new Block({from: "Jane", to: "Joe"}, precedingHash = a.hash)

Try printing out the hashes for these blocks and note how they are different. Also note that if you alter the data of the first block, the hashes of both will change.


Creating a Blockchain

Now that we have our building blocks (pun intended), let’s create a class for our chain. We can define it like so:

class BlockChain { // Our Blockchain Object
    constructor() {
        this.blockchain = [this.startGenesisBlock()] // Initialize a new array of blocks, starting with a genesis block
    }
    startGenesisBlock() {
        return new Block({}) // Create an empty block to start
    }
    obtainLatestBlock() {
        return this.blockchain[this.blockchain.length - 1] // Get last block on the chain
    }
    addNewBlock(newBlock) { // Add a new block
        newBlock.prevHash = this.obtainLatestBlock().hash // Set its previous hash to the correct value
        newBlock.hash = newBlock.computeHash() // Recalculate its hash with this new prevHash value
        this.blockchain.push(newBlock) // Add the block to our chain
    }
    checkChainValidity() { // Check to see that all the hashes are correct and the chain is therefore valid
        for(let i = 1; i < this.blockchain.length; i++) { // Iterate through, starting after the genesis block
            const currBlock = this.blockchain[i]
            const prevBlock = this.blockchain[i -1]
            
            // Is the hash correctly computed, or was it tampered with?
            if(currBlock.hash !== currBlock.computeHash()) { 
                return false
            }
          
            // Does it have the correct prevHash value?; ie: What a previous block tampered with?
            if(currBlock.prevHash !== prevBlock.hash) {                 
              return false
            }
            
        }
        return true // If all the blocks are valid, return true
    }
}


// Create two test blocks with some sample data
let a = new Block({from: "Joe", to: "Jane"})
let b = new Block({from: "Jane", to: "Joe"})

 
let chain = new BlockChain() // Init our chain
chain.addNewBlock(a) // Add block a
chain.addNewBlock(b) // Add block b
console.log(chain) // Print out the blockchain
console.log("Validity: " + chain.checkChainValidity()) // Check our chain for validity

First, note that we call the initial block in the chain the Genesis Block. Since this block is the first in the chain, it cannot store any previous hash value.

Next, we also created a function to check the validity of the blockchain to monitor tampering. We are checking for two possibilities.

  • Someone tampered with the data and that the stored hash value is no longer the correct hash value
  • Someone tampered with a previous block’s data, and that the prevHash value stored is therefore incorrect.

If you run that code and print out the value of the chain, you should be able to see how each block in the chain is storing both its own hash, and the hash of the prior block!


That’s all for this example, but if you want to get more comfortable with blockchain, I highly recommend playing around with this code and seeing what breaks the validity of the chain!

Comments are closed.