You may have read lots of theoretical posts on how cryptocurrencies work, how blockchain works and several other related concepts like Proof of Work, sha256. etc. But such theoretical posts can only give you basic idea about working and lots of things still remain mystery to you. So, the goal of this thread is to give you firsthand experience about how Blockchain works using real coding.
Before I start the guide, I would like to clear few things:
First, this thread is for learning purpose only. The code below is not production ready and have several vulnerabilities. If you plan to use it for production, make sure to contact me first and I will tell you the necessary additions you have to make in order to make it ready for production.
Second, this guide will use Javascript/Node.JS environment so if you have basic idea about how Javascript works then this guide is cake-walk for you. If not, even then you can learn so much as I tried to remain as descriptive as possible. But if you get stuck somewhere, just PM me or post here and I will solve every doubt I receive. Enough said, let's start:
PART 1: BLOCK
Part 1(a): Constructor Class
Ok! So block as we all know is fundamental unit of Blockchain. Series of interconnected blocks make blockchain. Let me give you an example: Suppose 10 children are playing in a park. Each one of them is holding the hand of another child thus forming the structure of human chain, children on both extreme ends will be holding the hand of one other child while rest 8 will be holding the hands of 2 children, one on each side. Blockchain works on the same concept. The first block of the chain (known as genesis block) will be holding the hand of second block only while the most recent block will be holding the hand of last second block only. All the other blocks will be holding the hands of blocks previous and next to them.
A small pictorial representation of what I just said:
(
I am bad artist, I know. )
Ok! So now one thing is clear that every block must hold the hand of other block to form chain. In order to ensure that, blockchain uses the concept of hash and previous hash (I like to call it last hash). Every block has unique hash which is generated through SHA256 algorithm (will explain that in detail later). This hash act as the hand of every block. Second block will save hash of genesis block, third block will save hash of second block and so on...This brings us to the basic design of block, a block should have hash, lastHash (hash of previous block), data (something unique stored in block), timestamp (the timing of the creation of block) and nonce (will explain what nonce is with PoW). Before starting with the code, please make sure you have following things ready:
(i) install Node.js on your system
(ii) download any code editor (I would suggest Visual Studio Code)
(iii) create a new file with any name but with .js extension, example: app.js or index.js
(iv) open the file in visual studio code
Here comes the first snippet of code:
class Block {
constructor(timestamp, lastHash, hash, data, nonce) {
this.timestamp = timestamp;
this.lastHash = lastHash;
this.hash = hash;
this.data = data;
this.nonce = nonce;
}
}
Boom! Here is the code for Part: 1(a). Now let me explain what we just did. Starting with the word 'class'. Class is actually a skeleton. We have created skeleton of name 'Block'. Like every human have same skeleton but different muscles and organs. Similarly, every block in the chain will have this Block skeleton. Timestamp, lastHash, hash, data and nonce are the bones. Every block must have these bones in order to form a skeleton. Moving forward, word 'constructor' refers to the function which will take the bones as input and create skeleton out of that. So we are actually inputting the value of timestamp, lastHash, hash, data and nonce into constructor function which in turn is setting the value of timestamp, lastHash, hash, data and nonce of Block’s instance equivalent to that.
Great? Let's move forward to Part: 1(b).
Part 1(b): Genesis Block
Here goes the code for Part: 1(b), this code will come after constructor function :
static createGenesis() {
return new this("17/01/2020", "dummy-last-hash", "dummy-hash", "data in genesis block", 0)
}
Great! So, let me tell you what we just did, we have created a static function in Block class which will create a genesis block for us. You may be noticing that we have created a hard-coded value for this block (anything inside '' " is string or hard-coded value, not code). We are doing this way because genesis block cannot have lastHash, so it is not viable to create hash for it, which makes it risky to store any data in genesis block. So, it is better if we define the properties of genesis block on our own and don't use it for any storage.
Moving forward, let me describe what above code is doing. Starting with the word 'static'. We can create two types of functions in class, normal functions and static functions. Normal functions could be used with every instance of class (for example, every block created with Block class can use normal function) but it is not possible to use static function with every instance. In our chain, we only want one genesis block so it would be bad if we create normal function for this. Therefore, static function will make sure that createGenesis() function can be called only once in blockchain.
You maybe noticing 'return' in the code above. Return actually means return (smart, ehh). It makes sure that whenever this function is called, the function returns the value of genesis block. 'new' refers to the instance of Block class. Whenever, we create instance of any class, we have to use new keyword. ‘this’ refers to Block class’s constructor. If we are using constructor within the class then we have to refer it with ‘this’.
Enough said, let’s move forward and create the most important function i.e. createBlock.
Part 1(c): Create Block function and Proof of Work
Code will go after createGenesis() function:
static createBlock(previousBlock, data) {
let hash, timestamp, nonce=0;
const lastHash = previousBlock.hash;
do {
timestamp = Date.now();
nonce++;
hash = hashGenerator(timestamp, lastHash, data, nonce);
} while (hash.substr(0,4) !== ‘0’.repeat(4));
return new this(timestamp, lastHash, hash, data, nonce);
}
Neat! Now time to understand what we did above. The function takes two inputs: previousBlock which is the block previous to the one we are creating and data i.e. the actual data we want to save in the block. Then, we are letting the starting value of hash = nothing, timestamp = nothing and nonce = 0. In Javascript ‘let’ and ‘const’ are two ways of defining variables. We refer variables that don’t change their value with ‘const’ and those which change their value by ‘let’. Next, we extracted the value of lastHash from previous Block which is equal to previousBlock’s hash.
Cool! Next comes the mighty concept of Proof of Work. We have tried to achieve it via do/while loop. ‘While’ part of the do/while loop takes condition and the loop keeps running the code in ‘do’ part until the condition in while statement fulfils. So the condition we mentioned in while statement is: hash.substr(0, 4) !== ‘0’.repeat(4). Now let’s break this statement. hash.substr(0,4) means first 4 characters of hash starting from 0 i.e. first character then second, third and fourth. ‘0’.repeat(4) means four zeros or ‘0000’. So we are actually stating that keep running the loop as far as first four characters of the hash are not 0. Once the first 4 characters of hash becomes 0, the loop will break and the resultant value will become the hash of the block. This is not exactly how proof of system works but basic idea is same. We are finding hash with four zeros in the starting like 0000vddvd5vd4dv5dvdXXXXXXXXXX. If you want to increase the difficulty of Proof of Work system, increase the number of zeros to 5 or more and blocks will be mined slower. If you want to lower the difficulty then reduce the number of zeros to 3 or lower and blocks will be mined faster.
Now coming to code inside ‘do’ statement. First is timestamp which we have taken equals to Data.now() which is javascript function to generate current date. Next is nonce. Nonce is the number which keeps on incrementing by 1 at every loop so that the value of hash keeps changing, if nonce remain stagnant then it is not possible to generate new hash at every loop. The final thing in the code is hashGenerator which intakes the value of timestamp, lastHash, data and nonce and generate hash by combining all the 4 values as a single string using sha256 algorithm. We will write hashGenerator function in next part. Let’s move to it.
Part 1(d): SHA256
Let’s write the code first, this will go at the top of the file before Block class:
const crypto = require(‘crypto’);
const hashGenerator = (...inputs) => {
const hash = crypto.createHash(‘sha256’);
hash.update(inputs.map(item => JSON.stringify(item)).join(‘’));
return hash.digest(‘hex’);
}
Lovely! Time for explanation. Crypto is in-built library of Node.js. So, we have simply called it into our file by requiring it. Next comes hashGenerator function. First, we are taking inputs i.e. if you remember from Part: 1(c) are timestamp, lastHash, data and nonce. Next you must be noticing three dots in front of inputs. Those dots aren’t by mistake, these dots convert all 4 inputs into Array like this: [timestamp, lastHash, data, nonce]. Bingo! Now let’s enter into the hashGenerator function. In first line we defined the value of hash equals to createHash(‘sha256’) function of crypto library. Then we are inputting each item of inputs Array through update method. We first mapping over inputs array which means looping over item of array, converting every item to string through JSON.stringify method and then joining everything as single string. Finally, we are returning the value of function through digest method but first converting generated value from line two to hex.
If you are having hard time understanding hashGenerator function then don’t worry, it’s because we have used the native syntax of crypto library and which is different from generic Javascript syntaxes.
This brings us to the end of first part of our two parts guide on creating Blockchain. We have successfully created Block class. Next we will create Blockchain class and add blocks to our blockchain.