We’re going to write a very basic application for Blockchain development in JavaScript, it won’t be anything too fancy but it will be just enough so you can understand how a blockchain actually works. We called this Blockchain a “devprofessorCoin”.

Install node.js and open bash terminal in your project directory and write the following command to generate crypto-js library, we will use this because we need SHA256 as a hash function and JavaScript doesn’t provide it by default.

npm install --save crypto-js 1 npm install -- save crypto - js

Output:

Now create a file called main.js and add the following code in it. (Read comments for explanation)

const hashCode = require("crypto-js/sha256"); class Block { constructor(index, timestamp, data, previousHash = '') { //Properties of block this.index = inadex; //where the blocks sits on the chain this.previousHash = previousHash; //contains hash of the previous block this.timestamp = timestamp; //when the block was created this.data = data; //any type of data that will be associated with the block this.hash = this.buildHash(); //hash of current block } buildHash() { //Calculate Hash for all the data. return hashCode(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)).toString(); } } class Blockchain{ constructor() { //Initializing Blockchain this.chain = [this.makeGenesisBlock()]; //First block called Genesis Block } makeGenesisBlock() { return new Block(0, "01/04/2018", "Genesis block", "0"); //Genesis Block Data } getLastBlock() { return this.chain[this.chain.length - 1]; //Return Last Block in the chain } addNewsBlock(newBlockData) { //adding a new block on to the chain newBlockData.previousHash = this.getLastBlock().hash; //setting previous hash newBlockData.hash = newBlockData.calculateHash(); //setting new hash by re calculating hash this.chain.push(newBlockData); //pushing to the chain } //return true if chain is valid and false if something wrong isChainValid() { for (let i = 1; i < this.chain.length; i++){ //not starting from block 0 because its genesis block const currentBlock = this.chain[i]; const previousBlock = this.chain[i - 1]; if (currentBlock.hash !== currentBlock.calculateHash()) { //check if blocks are properly linked together return false; } if (currentBlock.previousHash !== previousBlock.hash) { //check if our block points to correct previous block return false; } } return true; // true if our chain perfectly valid. } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 const hashCode = require ( "crypto-js/sha256" ) ; class Block { constructor ( index , timestamp , data , previousHash = '' ) { //Properties of block this . index = inadex ; //where the blocks sits on the chain this . previousHash = previousHash ; //contains hash of the previous block this . timestamp = timestamp ; //when the block was created this . data = data ; //any type of data that will be associated with the block this . hash = this . buildHash ( ) ; //hash of current block } buildHash ( ) { //Calculate Hash for all the data. return hashCode ( this . index + this . previousHash + this . timestamp + JSON . stringify ( this . data ) ) . toString ( ) ; } } class Blockchain { constructor ( ) { //Initializing Blockchain this . chain = [ this . makeGenesisBlock ( ) ] ; //First block called Genesis Block } makeGenesisBlock ( ) { return new Block ( 0 , "01/04/2018" , "Genesis block" , "0" ) ; //Genesis Block Data } getLastBlock ( ) { return this . chain [ this . chain . length - 1 ] ; //Return Last Block in the chain } addNewsBlock ( newBlockData ) { //adding a new block on to the chain newBlockData . previousHash = this . getLastBlock ( ) . hash ; //setting previous hash newBlockData . hash = newBlockData . calculateHash ( ) ; //setting new hash by re calculating hash this . chain . push ( newBlockData ) ; //pushing to the chain } //return true if chain is valid and false if something wrong isChainValid ( ) { for ( let i = 1 ; i & lt ; this . chain . length ; i ++ ) { //not starting from block 0 because its genesis block const currentBlock = this . chain [ i ] ; const previousBlock = this . chain [ i - 1 ] ; if ( currentBlock . hash !== currentBlock . calculateHash ( ) ) { //check if blocks are properly linked together return false ; } if ( currentBlock . previousHash !== previousBlock . hash ) { //check if our block points to correct previous block return false ; } } return true ; // true if our chain perfectly valid. } }

Now write this below code to create blocks

let devprofessorCoin = new Blockchain(); devprofessorCoin.addNewsBlock(new Block(1, "01/15/2018", { amount: 4 })); devprofessorCoin.addNewsBlock(new Block(2, "01/16/2018", { amount: 9 })); console.log(JSON.stringify(devprofessorCoin, null, 4)) 1 2 3 4 let devprofessorCoin = new Blockchain ( ) ; devprofessorCoin . addNewsBlock ( new Block ( 1 , "01/15/2018" , { amount : 4 } ) ) ; devprofessorCoin . addNewsBlock ( new Block ( 2 , "01/16/2018" , { amount : 9 } ) ) ; console . log ( JSON . stringify ( devprofessorCoin , null , 4 ) )

Now go to your bash command prompt and write the following command to run you code.

node main.js 1 node main . js

Output:

Our block chain is the object, it contains a property “chain” which is an array and contains all of the blocks on our chain and you can see that each block references the previous block.

Blockchains are great because once a block is added it cannot be changed without invalidating the rest of the chain. We have created a function to validate our blocks called isChainValid()

Now let’s try to check if our blocks are valid.

console.log('Blockchain valid? ' + devprofessorCoin.isChainValid()); //True because its correct console.log('Changing a block...'); devprofessorCoin.chain[1].data = { amount: 1000 }; //Overriding chain data console.log("Blockchain valid? " + devprofessorCoin.isChainValid()); //False because its tempered 1 2 3 4 console . log ( 'Blockchain valid? ' + devprofessorCoin . isChainValid ( ) ) ; //True because its correct console . log ( 'Changing a block...' ) ; devprofessorCoin . chain [ 1 ] . data = { amount : 1000 } ; //Overriding chain data console . log ( "Blockchain valid? " + devprofessorCoin . isChainValid ( ) ) ; //False because its tempered

Output:

Now of course if you detect that a new block broke your chain or if something is wrong with your chain then you should have a mechanism that rolls back the changes and then puts your block chain back in a correct state.

It’s also lacks many features such as proof of work or appear to be network to communicate with other miners and it even doesn’t check if you had enough funds to make a transaction so there are lots of limitations to my little Blockchain right here but it perfectly demonstrates how a Blockchain works behind the scenes.

Read More: What is Blockchain Technology?

Read More: Building Blockchain using PHP

Proof of work

Right now we can create new blocks really quickly. All we have to do is create a transaction, compute its hash and add it to an array. Now modern computers can do that incredibly quickly but we don’t want people to create hundreds of thousands of blocks per second and spam our blockchain.

There’s also a security issue, you can change the contents of a block and then simply recalculate the hashes for all the blocks after that and you will end up with a valid chain – even though you tampered with it and obviously that’s not what we want.

To solve these issues block chains have something that is called PROOF OF WORK. With this mechanism you have to prove that you’ve put a lot of computing power into making a block. This process is also called MINING so how can we implement something like this? While Bitcoin for example requires the hash of a block to begin with a certain amount of zeros and because 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 zeroes in front of it, this requires a lot of computing power, this is also called the difficulty and it is sent so that there is a steady amount of new blocks. In Bitcoin’s case the aim is to create one new block every ten minutes, as computers get faster over time they will require less time to mine a new block, to compensate for that the difficulty will simply be increased.

Lets change our code (Follow comments for details)

const hashCode = require("crypto-js/sha256"); class Block { constructor(index, timestamp, data, previousHash = '') { this.index = index; this.previousHash = previousHash; this.timestamp = timestamp; this.data = data; this.hash = this.buildHash(); this.nonce = 0; //nonce setting to zero } buildHash() { //added another variable nonce. return hashCode(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data) + this.nonce).toString(); } //make the hash of our block begin with a certain amount of zeros mineBlock(difficulty) { while (this.hash.substring(0, difficulty) !== Array(difficulty + 1).join("0")) { this.nonce++; //random number and can be changed this.hash = this.buildHash(); //calculate the hash of block } console.log("BLOCK MINED: " + this.hash); } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 const hashCode = require ( "crypto-js/sha256" ) ; class Block { constructor ( index , timestamp , data , previousHash = '' ) { this . index = index ; this . previousHash = previousHash ; this . timestamp = timestamp ; this . data = data ; this . hash = this . buildHash ( ) ; this . nonce = 0 ; //nonce setting to zero } buildHash ( ) { //added another variable nonce. return hashCode ( this . index + this . previousHash + this . timestamp + JSON . stringify ( this . data ) + this . nonce ) . toString ( ) ; } //make the hash of our block begin with a certain amount of zeros mineBlock ( difficulty ) { while ( this . hash . substring ( 0 , difficulty ) !== Array ( difficulty + 1 ) . join ( "0" ) ) { this . nonce ++ ; //random number and can be changed this . hash = this . buildHash ( ) ; //calculate the hash of block } console . log ( "BLOCK MINED: " + this . hash ) ; } }

class Blockchain{ constructor() { this.chain = [this.makeGenesisBlock()]; this.difficulty = 2; //difficulty means number of zeros. } makeGenesisBlock() { return new Block(0, "01/04/2018", "Genesis block", "0"); } getLastBlock() { return this.chain[this.chain.length - 1]; } addNewBlock(newBlockData) { newBlockData.previousHash = this.getLastBlock().hash; newBlockData.mineBlock(this.difficulty); //mine block with difficulty. this.chain.push(newBlockData); } 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; } } let devprofessorCoin = new Blockchain(); console.log('Mining block 1...'); devprofessorCoin.addNewBlock(new Block(1, "01/15/2018", { amount: 4 })); console.log('Mining block 2...'); devprofessorCoin.addNewBlock(new Block(2, "01/16/2018", { amount: 9 })); 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 class Blockchain { constructor ( ) { this . chain = [ this . makeGenesisBlock ( ) ] ; this . difficulty = 2 ; //difficulty means number of zeros. } makeGenesisBlock ( ) { return new Block ( 0 , "01/04/2018" , "Genesis block" , "0" ) ; } getLastBlock ( ) { return this . chain [ this . chain . length - 1 ] ; } addNewBlock ( newBlockData ) { newBlockData . previousHash = this . getLastBlock ( ) . hash ; newBlockData . mineBlock ( this . difficulty ) ; //mine block with difficulty. this . chain . push ( newBlockData ) ; } isChainValid ( ) { for ( let i = 1 ; i & lt ; 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 ; } } let devprofessorCoin = new Blockchain ( ) ; console . log ( 'Mining block 1...' ) ; devprofessorCoin . addNewBlock ( new Block ( 1 , "01/15/2018" , { amount : 4 } ) ) ; console . log ( 'Mining block 2...' ) ; devprofessorCoin . addNewBlock ( new Block ( 2 , "01/16/2018" , { amount : 9 } ) ) ;

Output:

As you can see the hashes of our blocks now start with two zeros and that is because we set the difficulty to 2. However you also saw that it happened really quickly, a spammer could still easily generate many fake blocks or someone could tamper with our entire chain so to counteract this we will increase the difficulty to 4 and run it again.

Output:

You can see that it already takes a lot longer to mine our blocks and our blocks now start with four zeros instead of two so using this mechanism we can control how fast new blocks can be added to our block chain.