Blockchain

How To Create Blockchain Using Node.js? Learn by creating your own blockchain… | by Abhishek Chauhan | Better Programming | Better Programming

blockchain development | photo credit: Tezos

In this article, we take a practical approach and dive deep into the code. The examples in this article are designed to be straightforward and easy to understand for learning purposes. If you want to learn about blockchain technology and how to create a fully functional blockchain prototype, this article will give you a better understanding.

  1. Creating a basic P2P network
  2. Sending and receiving blocks
  3. Registering miners and creating new blocks
  4. Setting up a name-value database, LevelDB
  5. Creating a private-public wallet
  6. Creating an API
  7. Creating a command-line interface

Peer-to-peer networking is a type of computer network that uses a distributed architecture. In such a network, each peer or node shares the workload and is equal to the other peers, without any privileged peer.

Let’s create a folder and name it Blockchain.

Your code needs to find and connect peers, deploy servers that are used to discover other peers, and get an available TCP port. That is done by utilizing these three libraries:

  • discovery-swarm: It is used for connecting to peers in a network by using the discovery-channel
  • dat-swarm-defaults: Deploys servers that help identify other potential peers
  • get-port: Retrieves available TCP ports

To install these libraries, run this command:

npm install crypto discovery-swarm dat-swarm-defaults get-port@5.1.1 -save

Now that the libraries are installed, you will need to create a file and name it p2p.js. In this file, you will need to write the following code. If you would prefer, you could just copy the code below.

p2p.js

Open two Terminal windows and navigate to the location of the library. In both Terminal windows, type the following command:

node p2p.js

output p2p

As you can see from the code above, your machine generates a random peer ID and picks a random port when it discovers other peers on the network. By doing this, you are now connected to a P2P network with other users.Sending and receiving blocks

Creating Genesis Block and Sharing Blocks

The Block object varies among different blockchain models; for the purposes of this tutorial, you will be using a Block object similar to the one used in the bitcoin network.

block flow

the Block object has the following properties:

  • index: The first block in the chain is known as the GenesisBlock, which has an index of 0.
  • txns: This is the transaction data within the block. You can think of this as any type of data you would want to store.

The Block object contains the BlockHeader object, with following properties:

  • Version: There are four versions of blocks, with the genesis block being version 1 from 2009. Version 2 is a soft fork of bitcoin core 0.7.0 from 2012, while version 3 blocks were a soft fork of bitcoin core 0.10.0 from 2015. Version 4 blocks, which are BIP65 in bitcoin core 0.11.2 from 2015, are the most recent.
  • Previous block header hash: This is an SHA-256 (Secure Hash Algorithm) hash function of the previous block’s header. It ensures that the previous block cannot be altered, as this block needs to.
  • Merkle root hash: It is a hash of all the key-value pairs in a Merkle tree. The tree is hashed so that each key-value pair is unique, and the overall hash is used to identify the tree.
  • Time: This is the Unix epoch time when the miner began hashing the header.

As you know, Bitcoin has a “difficulty” property that miners need to recalculate every 2,016 blocks. With this in mind, you will not need to use the nBits and nounce params for PoW.

  • nounce: It is the number that miners use to adjust the hash of a block so that it will be less than or equal to the current target. This number is 32-bit, or 4 bytes.
  • nBits: This is the target, which is a 256-bit number that’s sort of inversely proportional to the difficulty. It gets recalculated every 2,016 blocks.

P2P communication consists of each peer requesting the latest block from a peer on the network and then receiving a block request.

Flow diagram of P2P communications requesting latest block and receiving latest block

Now that you understand how the P2P network works, you’re ready to start sending and requesting blocks.

P2P network sending block

Setting Up a Block Class and Chain Library

There are two files you need for a blockchain: block.jsand chain.js. block.js contains the code for the block class, and chain.js has the methods for interacting with the blocks. As for the Block object, you’ll want to create properties similar to the ones in bitcoin core. If you’re unsure about what the Block and BlockHeader objects are supposed to be like, take a look at the block.js.

block.js

As you can see, chain.js contains the first block, which is referred to as the genesis block. Furthermore, this method can be used to receive the entire blockchain object, add a new block, or retrieve a specific block. It is worth mentioning that you will need to install the momentlibrary in order to save time in Unix time format. This can be accomplished by using npm.

npm install moment -save

Now create the chain.js :

chain.js

Now that we have a block object that is included in chain.js, our library can create a genesis block and add a block to your blockchain object. In addition, we will be able to send and request blocks. To use the chain.js in p2p.js, simply follow these steps:

p2p.js

As of now, we have a working P2P network, and we can connect peers within the network, create a genesis block, and exchange blocks.

The next step is to enable the generation of new blocks. We will adopt a proof-of-stake (PoS) approach, whereby we trust each miner to generate blocks. Each peer will register as a miner and take turns mining blocks.

Your blockchain handles mining using a simple PoS mechanism

To automate the generation of a block every X number of minutes, you can use the Node.js cron library. This library is similar to the Linux library which automates tasks. To install the cron open-source library, run the following command:

npm install cron -save

In your p2p.js file, you will create two variables: one to keep track of the registered miners, and one to keep track of who mined the last block. This will allow you to assign the next block to the next miner.

let registeredMiners = [];let lastBlockMinedBy = null;

You are also going to add two messages types.

  • REQUEST_ALL_REGISTER_MINERS
  • REGISTER_MINER

let MessageType = { REQUEST_BLOCK: ‘requestBlock’, RECEIVE_NEXT_BLOCK: ‘receiveNextBlock’, RECEIVE_NEW_BLOCK: ‘receiveNewBlock’, REQUEST_ALL_REGISTER_MINERS: ‘requestAllRegisterMiners’, REGISTER_MINER: ‘registerMiner’ };

Before you register your own peers as miners, you will need to request a list of all existing registered miners in the network. This can be done by running a timer to update your list of miners every five seconds. Once you have a list of all existing miners, you can then add your own peer as a miner in the registeredMiners object.

setTimeout(function(){ writeMessageToPeers(MessageType.REQUEST_ALL_REGISTER_MINERS, null); }, 5000);

Now, that has an automated timeout command that can point to a handler to update the list of registered miners you can also automate a command to register your peer as a miner;

setTimeout(function(){ registeredMiners.push(myPeerId.toString(‘hex’));console.log(‘ — — — — — Register my miner — — — — — — — ‘); console.log(registeredMiners); writeMessageToPeers(MessageType.REGISTER_MINER, registeredMiners); console.log(‘ — — — — — Register my miner — — — — — — — ‘); }, 7000);

In your switch command, modify the code to be able to set handlers for incoming messages regarding the registrations of miners. We want to keep track of the registered miners as well as handle a message once a new block is mined.

case MessageType.REQUEST_ALL_REGISTER_MINERS: console.log(‘ — — — — — -REQUEST_ALL_REGISTER_ MINERS — — — — — — — ‘ + message.to); writeMessageToPeers(MessageType.REGISTER_MINER, registeredMiners); registeredMiners = JSON.parse(JSON.stringify(message. data)); console.log(‘ — — — — — -REQUEST_ALL_REGISTER_ MINERS — — — — — — — ‘ + message.to); break; case MessageType.REGISTER_MINER: console.log(‘ — — — — — -REGISTER_MINER — — — — — — — ‘ + message.to); let miners = JSON.stringify(message.data); registeredMiners = JSON.parse(miners); console.log(registeredMiners); console.log(‘- REGISTER_MINER- ‘ + message.to); break;

You also need to unregister a miner once a connection with the miner is closed or lost.

console.log(`Connection ${seq} closed, peerId: ${peerId}`); if (peers[peerId].seq === seq) { delete peers[peerId]; console.log(‘ — — registeredMiners before: ‘ + JSON.stringify(registeredMiners)); let index = registeredMiners.indexOf(peerId); if (index > -1) registeredMiners.splice(index, 1); console.log(‘ — — registeredMiners end: ‘ + JSON.stringify(registeredMiners)); } });

Mine a new block

As opposed to bitcoin, which generates a block every 10 minutes, your blockchain will be improved and will generate a block every 30 seconds. To achieve that, you already installed the open-source cron library for Node.js. The cron library works the same as the Linux cron. You can utilize the cron library to set how often to call the same code again, which will be used to call your miners every 30 seconds.

To do so, first include the library in your code’s import statement on top of the p2p.js file. Next, you set a cronjob to run every 30 seconds, and job.start(); will start the job,

After adding all the above functions your p2p.js file will look like this:

p2p.js

A LevelDB database stores name-value pairs in what is called a level-up and level-down fashion. It is an ideal option for blockchain networks. In fact, bitcoin uses LevelDB to store not only block information but also transaction information. To use it, install level with npm.

npm install level -save

Next, make a directory where you will be saving the database.

mkdir db

You can now implement the database. In chain.js, add some code to save your block in the LevelDB database.

chain.js

Lastly, in your p2p.js file, all you need to do is create a database once you start the code.

chain.createDb(myPeerId.toString(‘hex’));

adding createDb in p2p.js

In cryptocurrency, a wallet is necessary in order to reward miners for generating blocks, as well as to create and send transactions. In this section, you will create a wallet by generating a combination of public and private keys. This will not only authenticate the user but also allow you to store and retrieve data that the user owns.

You will be using an elliptic-curve cryptography library implementation to generate private-public key combos. Note that the elliptic-curve library uses secp256k1 as the ECDSA curve algorithm. To install it, run the following command:

npm i elliptic -save

Create a new file wallet.js and copy the following code,

Next, create a wallet directory to store the private key and run the script. The code will initialize the script and create your public key.

mkdir walletnode wallet.jscat wallet/private_key

output private key

Remember to comment out last lines 32 to 34 of wallet.jsbecause in the next, you will create an API to be able to create your keys via the browser.

The next step is to create an application program interface (API) to be able to access the code you write. This is an important part of a blockchain, as it allows you to access your blocks and wallet or any other P2P network operation using an HTTP service.

You will need to install express and body-parser. These libraries will allow you to create a server and display pages in the browser.

npm install express body-parser — save

Now open your p2p.js file and follow along,

To call your services, run the P2P network,

node p2p.js

p2p.js output

Now, open a browser and call the API,

http://localhost:8001/blockshttp://localhost:8001/getBlockhttp://localhost:8001/getDBBlockhttp://localhost:8001/getWallet

calling /blocks API in the browser

For the last step in this article, you will be creating a command-line interface (CLI). The CLI is needed to be able to easily access the services you created.

Next, install the libraries you will be utilizing to run promises, run the async function, add colors to the console, and store cookies.

npm i babel-polyfill async update-notifier handlebars colors nopt -save

Create a new directory cliand inside another cmds for commands

mkdir clicd climkdir cmdstouch block.js help.js version.js wallet.js

In the block.js, you will be setting two commands: get and all,

block.js cli

As you can see, the wallet.js will include the get and all methods to point to a curl command to run the HTTP service call,

wallet.js cli

Similarly, we will do for others please follow this link. Copy codes from the given link.

Now, create a directory bin and add cli.js ,

Now that you have your commands set up, you can add your CLI to the bash_profile as an alias to be able to run the CLI from any path location.

nano .bash_profilealias cli=’node /<location>/Blockchain/bin/cli.js’

Press ctrl+o to save and ctrl+X to exit, then run bash_profile,

. ~/.bash_profile

Hurray!! Our command-line interface is ready 😃, let’s test it,

node p2p.js

Open another terminal and run,

cli block -get [port] 1 cli block -all [port] cli wallet -create [port]

cli interface output

Congrats👏 we have created our own blockchain 🔥🔥🔥🔥

In this article, we have covered how to create your very own basic P2P blockchain network; you were able to send and receive messages and include blocks in these messages; you were able to register and unregister miners and implement a simple PoS consensus mechanism; you created new blocks and sent them between the peers; you also set up a name-value LevelDB database to store blocks; you continued and created a wallet that consists of private-public key pairs. Lastly, you created ways to communicate with your P2P network via API services and the CLI.

Want to Connect?For the full code visit and if you like it, follow me on GitHub:https://github.com/ac12644/Blockchain

Related Articles

Back to top button

Adblock Detected

Please consider supporting us by disabling your ad blocker