Implementing PBFT in Blockchain – Coinmonks

In this section, we will implement a blockchain with PBFT as its consensus algorithm. It may be noted that this blockchain would not use a cryptocurrency but can be if we use an account model. Moreover, PBFT can only operate under a permissioned environment since it is vulnerable to Sybil attacks, the members of the network are required to be known.
Prerequisites
- Node.js
- Postman
- VS code
- Knowledge about blockchain concepts
Architecture and Design
To implement PBFT we will develop the following components:
- Wallet class — for public key and signing data.
- Transaction class — to create transactions and verify them.
- Block class — to create blocks, verify blocks and verify proposer of the block.
- Blockchain class — to create a chain, add blocks, calculate proposer, validate blocks, update blocks.
- P2p Server class — to broadcast and receive data among peers.
- Validators — to generate and verify validators
- Transaction pool, block pool, commit pool, prepare pool and message pool — to store transactions, blocks, commits, prepare and new round messages respectively.
- App — Express API to interact with the blockchain
- Config — to store global variables
- Chain Utilities — to store common functions such as hashing and verifying signatures.
Code
Create a root directory pbft and cd into it. All the files in this project are present in the root directory.
mkdir pbft && cd pbft
The ChainUtil Class
We will start off by creating a chain-util.js file which will be used multiple times in this project. This file will be used to create key pair for signing data, generating id’s for transactions, hashing data and verifying signatures.
We need three modules to perform these functions. Therefore we need to install them.
npm i --save elliptic uuid crypto-js
Create a class ChainUtil and export it.
The Transaction Class
Next, we’ll make a transaction class. Create file transaction.js in the project folder. Transactions in this project will contain the following properties:
- id — for identification
- from — the senders address
- input — an object that further contains data to be stored and timestamp
- hash — the SHA256 of input
- signature — the hash signed by the sender
Create a class Transaction in the file and export it.
The Wallet Class
Up next is wallet. The wallet holds the public key and key pair. It is also responsible for signing data hashes and creating signed transactions.
Create a file wallet.js in the project directory. Add a class Wallet and export it.
The Validator Class
Since PBFT is a permissioned blockchain consensus algorithm we need to store the address of all the nodes in each nodes system. We can do this manually by choosing a secret, creating a wallet, getting its public key and storing this key into a file and when we run our project it reads this file for keys.
But instead of doing this manually we can automate this by creating a class and adding a function that can return a list of public keys of N number of nodes.
We will create a Validator class that will generate a list of public keys known to every node. In this project, we have used the secret phrase for each node as
NODE1, NODE2, NODE3......
This way it would be easier for us to make a list of public keys and create the nodes from the command line with the same public key.
NOTE: Secret phrase should never be made public. It is only for the demonstration that we have used such Secret phrases. In real-world projects, a registration request is sent to make a node a validator. If the whole network approves this request, the node becomes a validator and the public key is added to the list.
The Config.js file
The number of validators in the network can be passed through the command line but instead it easier to store it in a file and import it where ever needed.
Create a file config.js and create three variables NUMBER_OF_NODES ,MIN_APPROVALS and TRANSACTION_THRESHOLD
The Block Class
Next we will create the block class. In the project directory, create a file block.js and make a class Block in it. Block will have the following properties:
- timestamp — the time at which the block was made
- lastHash — hash value of the last block
- hash — hash value of the current block
- data — the transactions that the block holds
- proposer — the public key of the creator of the block
- signature — the signed hash of the block
- sequenceNo — the sequence number of block
The TransactionPool Class
We need a place to store transactions received from other nodes. Therefore we will make a TransactionPool class to store all transactions. Create a file called transaction-pool.js
The BlockPool Class
To store blocks temporarily we will also make block pool. Create a file block-pool.js in which the BlockPool class holds the blocks until it is added to the chain. A block is added to the block pool when a PRE-PREPARE message is received.
There are many other data objects received from the nodes that need to be stored. PREPARE , COMMIT andNEW_ROUND messages
Therefore will create three more pools namely, PreparePool , CommitPool and MessagePool . MessagePool will hold the NEW_ROUND messages.
The PreparePool Class
The CommitPool Class
Commit messages are added after 2f+1 prepare messages are received, therefore we use the prepare message to get the block hash instead of passing the entire block.
The MessagePool Class
MessagePool will work similarly to the other two pools. The only difference would be the extra message it takes with it.
The Blockchain Class
We have all of the classes required to make our blockchain class. We can now create a file blockchain.js The Blockchain class will have the following properties:
- chain — list of blocks that are confirmed
- validatorsList — validators list for the given network
The P2pserver Class
How do we send messages to other nodes? We will make a P2p Server. Create a class P2pserver in a file p2p-server.js
To create a p2p server we will make use of sockets. In order to use sockets we will install a ‘ws’ module. This module makes it utterly easy to work with sockets.
npm i --save ws
P2pserver class is where the consensus algorithm is implemented. It is the core of the project. This class is responsible for handling messages and broadcasting them.
The App
Now we will connect all the files using an application created using express module. Install the express module using npm.
npm i express --save
Our application will instantiate the pools, wallet, blockchain, p2pserver and declare some endpoints to interact with our blockchain.
Following are the minimum endpoints required, (you may add more):
- POST: ‘/transact’ — creates transactions, request object consists of data to be stored in the transaction
- GET: ‘/transactions’ — sends the transactions in the transaction pool as a response
- GET: ‘/blocks’ — sends the chain of the blockchain as a response
This completes our coding. You test this application by running the following in the separate terminals:
First node:
SECRET="NODE0" P2P_PORT=5000 HTTP_PORT=3000 node app
Second node:
SECRET="NODE1" P2P_PORT=5001 HTTP_PORT=3001 PEERS=ws://localhost:5000 node app
Third node:
SECRET="NODE2" P2P_PORT=5002 HTTP_PORT=3002 PEERS=ws://localhost:5001,ws://localhost:5000 node app
You can make as many as you want. Do update the total number of nodes config file before creating more nodes.
Hit the endpoint for any node until the pool fills up and check the chain by hitting the /blocks endpoint.
Also, hit the endpoint /transactions to check if the transaction pool is empty.
You can also make more such endpoints for commit, prepare and message pool.
Published at Mon, 05 Aug 2019 06:07:27 +0000
Bitcoin Pic Of The Moment
From Bitcoin (BTC) and beyond we look at where it all began from its inception to its current day notoriety helping shape the way in which we pay. We also look at what it means for consumers and merchants and how it can be easily integrated into new and existing platforms.
By devsteve on 2014-10-29 18:11:02

