1. 程式人生 > >Blockchain Revolution: Part Five

Blockchain Revolution: Part Five

Blockchain Revolution: Part Five

Implementing Proof-of-Work in application

In our fourth post we walked you through the process of building a simple blockchain application. Now let’s implement the most important aspect of blockchain applications — consensus algorithms. In this fifth post of the series ‘Blockchain Revolution’, we will implement the Proof-of-Work (PoW) protocol into our blockchain application. In order to do so, we must first understand some of the terminologies used commonly:

  • Difficulty: In PoW protocol, the blockchain has to solve a PoW puzzle. This puzzle is to find a hash, which has a specific number of zeros prefixing it. The Difficulty defines how many prefixing zeros the hash must contain, in order for the block to be valid. Let’s take an example, if difficulty is 2, then hash should contain 2 prefixed zeros.
  • Nonce: Nonce (number used once), is a counter value used for generating hash of the current block. Nonce is used to generate different hashes for the same content, based on the difficulty. Mining is trying a different nonce value until the difficulty matches.

Don’t worry if it sounds confusing at this point. As we try implementing this in code, you will have a better understanding.

Add a property difficulty in constructor of Blockchain class.

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

Add nonce property to the constructor of block and initialize the value to 0.

class Block {

constructor(data, previousHash, timestamp, index,
currentHash) {
this.index = index;
this.previousHash = previousHash;
this.timestamp = new Date().getTime();
this.data = data;
this.hash = this.calculateHash();
this.nonce = 0;
}
}

Mining a block

Mining a block means that only when difficulty is satisfied, the block will be added to the blockchain.

Create a method, mineBlock() in Block class.

mineBlock(difficulty) {
while (this.hash.substring(0, difficulty) !==
Array(difficulty + 1).join("0")) {
this.nonce++;
this.hash = this.calculateHash();
}
console.log("Mining Block", this.hash);
return this.hash;
}

Here we are checking if the hash of the string contains required number of prefixed zeros or not, based on the difficulty and understand why nonce is required. Each time the condition is satisfied, the nonce is incremented and hash is calculated. But the hash is not changing because the contents of the block is not changing. How can we change the hash of the current block, without changing the contents of the current block? The solution is to add the nonce to calculateHash() function we created above.

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

This generates a new hash based on nonce and difficulty without changing the contents of the block.

Adding new block based on difficulty

One last step is to modify the addNewBlock() function and add the mineBlock() condition to it as shown below.

addNewBlock(newBlock) {
newBlock.mineBlock(this.difficulty);
this.isChainValid();
newBlock.index = this.fetchLatestBlock().index + 1;
newBlock.previousHash = this.fetchLatestBlock().hash;
newBlock.hash = newBlock.calculateHash();
this.chain.push(newBlock);
}

The block will only be added when the mineBlock() and isChainValid() conditions are satisfied. The time taken increases with the difficulty. Which obviously means time taken to mine a block with difficulty 5 is more than it takes for difficulty 2.

Adjusting the difficulty

getDifficulty (blockchain) {
const latestBlock = this.fetchLatestBlock();
if (latestBlock.index % DIFFICULTY_ADJUSTMENT_INTERVAL === 0
&& latestBlock.index !== 0) {

return this.getAdjustedDifficulty(latestBlock, this.chain);
} else {
return blockchain.difficulty;
}
};

And that’s it. You have successfully built a blockchain application that follows Proof-of-Work protocol. You can check the github repository for the above code here. Stay tuned for the next post where we will introduce Ethereum Blockchain, and please leave a comment to let us know if this was helpful.