Implementing Proof of Stake Part — 3

Kashish Khullar
Coinmonks
8 min readFeb 1, 2019

--

This article presents an easy implementation of Proof of Stake consensus algorithm in node.js

In the previous post, we coded a basic blockchain. In this part, we will implement the functionality to validate a chain and add multiple contributors.

To add the support of multiple contributors, we need to add some form of validation. Each node in the network might have a different chain at some point in time. To achieve a common state we need to validate the new chains that we receive for other nodes. In bitcoin, the longest chain rule is used. In which, the chain which is valid, i.e. all the blocks are valid and has the maximum number of blocks is considered the valid chain. Thereby, all the nodes replace their chain to the longest chain. For us, on any new connection, we send our chain and receive the chain from another node.

We will create a isValidChain(chain) static function in the blockchain class that tells if the chain is valid or not. In this function, we recompute the hash of the block and compare it with the given hash of the block. This checks if the block has been tampered or not.

Before adding this function, we need a way to find the hash of the block, given the block instance. Let’s add this functionality to the block class.

Handover a block, and I’ll hash it

Now we can use this function in our isValidChain() function.

chain valid ? yes : no ;

Moving on. When we receive a new chain which is valid and longer than ours, we must use that chain and discard our chain, more formally we must replace our chain with the new longer chain. Let’s add this functionality.

Create a function replaceChain(chain) in the blockchain class. This should assign the new chain of the current blockchain object to the new chain received as an argument.

Let’s move on to creating a web API around this blockchain system that we’ve already created. These API will allow a user to interact with the blockchain by each HTTP requests and since we have multi-chain validation soon we will have multiple minors updating one shared in decentralized blockchain across the network.

Before we have our web API, let’s organize our project as we will add a couple of more files soon into our project.

Create a new directory named blockchain and move the block and blockchain files in it along with the test files.

Our file project structure should look like this

Now let’s create our app a separate app folder. Let's create a new index.jsfile in this folder.

To make our API we’ll use the express module. Let’s install it.

To manipulate data in post request we need a bodyparser module. So install that too.

We will have multiple users running our app. To test this app on our own machine we need to run the app on a different port each time we run a new instance. Hence we must provide a new port every time we run a new app.

We will do this using the environment variables. We can pass the port from the terminal and assign it to the port on which we run our app. By default, we will run our app on port 3000.

We also need an instance of the blockchain in this API to send and receive block data.

We also need to add a start script to our app. In the package.json file add a script to run the index.js file in the app directory.

We add some basic endpoints to the app:

Get /blocks — sends the chain to the user.

Post /mine — sends data in the request to create a new block.

Let’s create our app.

Plain simple APIs

Sweet! Let’s try this out in postman.

Making a get request will give the entire chain. In our case, we only have a genesis block.

Get request sends the entire chain

Making a post request will generate a new block. Hence, we also need to pass in some data.

Post request with data
The response has a new chain added to the blockchain

Cool.

We can interact with are blockchain, but we still have a single user. To have multiple peers we will make a p2p server and connect these peers using WebSockets allowing each peer to communicate to every other peer and transmit data.

When we will start our app, we will connect to some of the peers whose address we will pass when we start our app.

The P2pserver

We need a p2p-server so that different peers in the decentralized network can send blocks, chains, transactions, and other messages to each other over the network.

To implement a p2p server in node.js we need a module called ws This is a lightweight and easy to use web-socket module available. There are various other modules available, but to keep things simple we’ll stick with this one.

Within the app, directory create a file p2p-server.js. Import the ws module and define a P2P_PORT for the server. Like our HTTP server, we can use an environment variable to assign a port from the terminal.

We need a list of peers which we will connect to when we start the app. Each peer will have an address like this

Hence we can pass the peers address to which we want to connect to from our terminal as an environment variable and later access in out p2p-server.

Now let’s make a P2pServer class in p2p-server.js which will hold all the message handlers and event listeners.

The p2p-server will have its a blockchain variable which will be the same blockchain that we use in our app. Hence, we will pass a blockchain instance as a dependency. Our p2p-server will also have a list of sockets which it would be connected to at a given amount of time.

We use the peers list to connect to the peers by iterating over each peer and saving its socket connection object in the socket list for later use.

Let’s implement what we have discussed till now.

P2pserver class

In our app/index.js file, we’ll create the instance of the p2pserver, pass the blockchain instance and then start the p2pserver.

Alright, now let’s test our p2p server.

Fire up the terminal and open three tabs. In the first tab run

In the second

In the third

In the first terminal, we will get the output

In the second terminal, we will get the output

In the first terminal, we will get the output

Our sockets are now connected to each other.

Awesome! Let’s use this p2pserver to synchronize the blockchain to make a completely decentralized blockchain network.

Let’s add a message handler to the p2p-server. This messageHandler function will take a socket as an argument.

I handle your messages

We need to assign this handler to each socket. We can do this every time we make a new connection in the connectSocket() function.

We need to send a message to the peer when we connect to it. Hence, we can do so using socket.send() On connection, we want to send our chain the peers. Therefore, we will send the chain to them as a message when we connect to a socket.

Note: Ideally we would send blocks since the size of the chain is extremely huge. But to keep things simple we’ll send the entire chain in our case.

If you run two different apps, you see the chain of the other peer printed on the console of the first peer and vice-versa. This means that our sockets are correctly sending messages to each other.

To synchronize our chain with the chains of the peers, we can check if the received chain is valid and longer. We have already implemented this functionality in our blockchain class. Let’s use the replaceChain() function in p2pserver class when we receive a chain from a peer.

In the messageHandler(socket) function add

To make our life easier we’ll add two helper functions sendChain() and syncChain() in our p2pserver.

sendChain(socket) will be used to send our chain to a socket

The chain sender

syncChain(socket) will be used in our index file to synchronize the chains

The chain synchronizer

Now in our app/index.js file, we can use the syncChain() function whenever we add a new block to our chain.

Our final code for p2pserver will look like

Test this functionality by firing up two app instances. Add new blocks in the first app.

Now open the second terminal, you will see the output printed in the console.

You can confirm this by using the get endpoint of the second app. You can try the same with the second instance and the chain of the first instance will get replaced by the longer change.

Great! Our blockchain is getting synchronized.

In the next part, we’ll create a wallet for our project.

Thank you for reading. In the next part, we’ll write code to validate a blockchain and add support for multiple nodes. Hope you enjoyed coding. If you found this helpful throw a bunch of claps.

If you have any questions about blockchain, ethereum or the world in general, leave a comment. :)

--

--