Writing a Simple Blockchain

This section borrows code from [Savjee](https://www.savjee.be/2017/07/Writing-tiny-blockchain-in-JavaScript/), [Xavier Decuyper](https://www.codementor.io/@savjee/how-to-build-a-blockchain-with-javascript-part-1-k7d373dtk), and [Alibaba Cloud](https://www.alibabacloud.com/blog/build-your-own-blockchain-with-javascript_595314). Thank you for the inspiration!

To help you understand what a blockchain is, the next section will take you through a simple JavaScript implementation of a custom blockchain.

This section borrows code from Savjee, Xavier Decuyper, and Alibaba Cloud. Thank you for the inspiration!

Creating the Blockchain#

Now that we have VSCode, Node.js and npm installed, let's use these tools to create our own blockchain using JavaScript. This will allow us to really understand some of the key concepts behind blockchain and it gives us the opportunity to brush up on some JavaScript.

To kick things off, let's open VSCode.

From here we will select File > Open. This will take you to a file explorer. From here, create a new folder and call it blockchain-in-js.

vs-code-empty
vs-code-new-folder
vs-code-new-folder-2
vs-code-new-folder-3

Now that we have the empty folder open, let's get VSCode ready for the next few steps. We want to get a terminal up and be able to see the file explorer.

To enable the terminal view, click through from the main menu: Terminal > New Terminal. If you cannot see the file explorer, click View > Appearance > Show Sidebar from the main menu.

Your view should now look something like this:

vs-code-ready

Now that our development environment is ready, we will run npm init in the terminal. This will trigger a script that allows you to create a package.json file our project.

To keep things simple to start with, hit enter through the prompts of this script. Once completed, you should see a package.json file has been created with the following content:

As we won't need any dependencies just yet, we will leave this file for the moment.

Block Class#

Now, let's create a file called blockchain.js in the folder we are working in. To do this, right-click (or two-finger click on Mac OS) to open a menu in the Visual Studio Code side bar. You can select New File from the menu that appears.

A blockchain is a "chain of blocks". Let us start off by writing a class for a block.

Now that we have the block class, we will add a set of functions that will give us what we need to represent a block. The values of a block that we will be capturing include a timestamp, the data we want on the blockchain, a reference to a previous block and a reference of the current block. In addition, we will have a value that allows us to index the block.

calculateHash function#

We will add a function called calculateHash that takes in the values being captured for the block, and generates and returns a hash. A hash is a function that converts one value to another. To calculate the hash for our block, we will import a library called SHA256. To have it available for our code, we will have to run it in the code directory.

Once we have this package saved, we will import a SHA256 library. Add the following line of code to the top of your file (before you declare the block class).

Now that you have the SHA256 function available, let's start writing the calculateHash function in the block class.

To capture the required values, we will create a constructor to instantiate variables for them. We will be passing in the variables mentioned and then setting them in the constructor function. To generate the hash for this block, we will be calling the calculateHash function that we just created.

At this point, code should look something like this:

Blockchain Class#

Now that we have a Block class, let's create the Blockchain class. For this class, we will need the following functions:

  • constructor

  • createGenesisBlock

  • getLatestBlock

  • addBlock

  • isChainValid

We will start off by declaring the Blockchain class.

Constructor and createGenesisBlock Function#

The constructor function starts the blockchain. The first block in a blockchain is referred to as a genesis block. Let's create a function createGenesisBlock that will help us create a genesis block with an index set to 0.

Now that we have a function to create the genesis block, let's create our constructor. We will be setting a variable called chain to be equal to the function we created. We will treat the chain variable as an array of blocks.

Our constructor now starts our blockchain for us, so let's add some functionality around adding blocks, reading block information, and checking that the blockchain we have is valid.

getLatestBlock Function#

We will write a function to get the latest block, getLatestBlock. Since the chain is an array, we will return the last value of the array.

addBlock Function#

The next function, addBlock will allow additional blocks to be added to the chain array.

To create a new block, the block's values will be passed into the function, which will then set a previousHash variable and a new block hash variable.

Once we set those variables, we will push the new block into the chain variable.

Since we now have blocks with hashes that point to the hash of the block that came before it, we can write a function to check if the chain variable is valid.

isChainValid Function#

We will create a function called isChainValid which will loop through all the blocks to confirm if the hashes all correspond as they should. In the blockchain that we are building, we simply need the block we are looking at to have the hash of the block that precedes it. If the hash doesn't correspond, then the function will return false.

The other thing that we can check as we are looping through the blocks is whether the hash that is created for the current block is the hash that gets created if we call the calculateHash function that we wrote for the block class.

We now have a simple blockchain function that will behave as basic blockchains do.

Test the Functions#

To test this functionality, let's run some code to see how the blockchain works.

To ensure that the code that we have created makes sense, let's run through some simple tests to validate the code and functionality. To start this process, let's initialize the simple blockchain we are working on.

We can add a block to the blockchain we created with the following function.

Let's add one more block...

Now we can call getLatestBlock or isChainValid on the blockchain that we created. Try changing some parameters around and see if the function calls give you the results that you expect.

Adding Proof of Work Consensus#

To enhance the blockchain that we wrote in the previous section, we now have to upgrade the protocol at which blocks can be added upon.

The protocol that is most common in blockchains nowadays is called proof of work consensus. This protocol is used to confirm transactions and produce new blocks to the chain. With proof of work, miners compete against each other to complete transactions on the network and get rewarded.

Miners are users who are responsible for adding transactions to a blockchain.

Adding the Nonce to Blocks#

A nonce is an abbreviation for "number only used once," which is a number added to a hashed or encrypted block in a blockchain that, when rehashed, meets the difficulty level restrictions as described below. Since miners will be adding blocks to our blockchain, the nonce is something that we need to add to our blocks.

Update the block constructor to include a nonce variable

We will also need to update the calculateHash function to include the nonce.