Understanding Blockchain isn’t easy. At least it wasn’t for me. I had to go through number of frustrations due to too few funcional examples of how this technology works. And I like learning by doing so if you do the same, allow me to guide you and by the end you will have a functioning Blockchain with a solid idea of how they work.
Before you get started..
Remember that a Blockchain is an immutable, sequential chain of records called Blocks. They can contain transactions, files or any data you like, really. But the important thing is that they’re chained together using hashes.
What is needed?
Make sure that you have Python 3.6+ installed (along with pip) and you will also need Flask and Requests library.
You will also need an HTTP client like Postman or curl. But anything will do.
So what does a block look like?
Each block has an index, timestamp, transactions, proof (more on that later) and a hash of the previous transaction.
Here is an example of what a single Block looks like:
Represenging a Blockchain
We’ll create a Blockchain class whose constructor creates a list to store our Blockchain and another to store transactions. Here is how the Class will look like:
This Blockchain class is responsible for managing the chain. It will store transactions and have helper functions.
The new_block method will create a new block and adds it on the chain and returns the last block in the chain.
The last_block method will return the last block in the chain.
Each block contains the hash and the hash of the previous block. This is what gives blockchains it’s immutability – i.e. if anyone attack this, all subsequent blocks will be corrupt.
It’s the core idea of blockchains. 🙂
Adding transactions to the block
We will need some way of adding transactions to the block.
The new_transaction returns index of the block which will be added to current_transactions and is next one to be mined..
Creating new blocks
In addition to creating the genesis block in our constructor, we will also need to flesh out methods for the new_block(), add_new_transaction() and hash().
Once our block is initiated, we need to feed it with the genesis block (a block with no predecessors). We will also need to add “a proof of work” to our genesis block which is the result of mining.
At this point, we’re nearly done representing our Blockchain.
So lets talk about how the new blocks are created, forged and mined. 🙂
Understanding Proof of Work
A proof of work algorithm are how new Blocks are created or mined on the Blockchain.
The goal is to discover a number that solves a problem.
The number must be difficult and resources consuming to find but super quick and easy to verify.
This is the core idea of Proof of Work. 🙂
So lets work out some stupid-shit math problem that we are going to require to be solved in order for a block to be mined.
Lets say that hash of some integer x multiplied by another y must always end in 0. So, as an example, the hash(x * y) = 4b4f4b4f54…0.
In this example we fixed the x = 5. The solution in this case is x = 5 ands y = 21 since it procuced hash 0.
In the Bitcoin world, the Proof of Work algorithm is called Hashcash. And it’s not any different from the example above. It’s the very algorithm that miners race to solve in order to create a new block. The difficulty is of course determined by the number of the characters searched for in the string. In our example we simplified it by defining that the resultant hash must end in 0 to make the whole thing in our case quicker and less resource intensive but this is how it works really.
The miners are rewarded for finding a solution by receiving a coin. In a transaction. There are many opinions on effectiness of this but this is how it works. And it really is that simple and this way the network is able to easily verify their solution. 🙂
Implementing Proof of Work
Let’s implement a similar algorithm for our Blockchain. Our rule will be similar to the example above.
“Find a number p that when hashed with the previous block’s solution a hash with 4 leading 0 is produced.”
To adjust the difficulty of the algorithm, we could modify the number of leading zeors. But strictly speaking 4 is sufficient enough. Also, you may find out that adding an extra 0 makes a mammoth difference to the time required to find a solution.
Now, our Blockchain class is pretty much complete, let’s begin to interact with the ledger using the HTTP requests.
We’ll use Python Flask framework. It’s a micro-framework and it’s really easy to use so for our example it’ll do nicely.
We’ll create three simple API endpoints:
- /transactions/new to create a new transaction block
- /mine to tell our service to mine a new block
- /chain to return the full Blockchain
Setting up Flask
Our server will form a single node in our Blockchain. So let’s create some code.
The transaction endpoint
This is what the request for the transaction will look like. It’s what the user will send to the server.
Since we already have the method for adding transactions to a block, the rest is easy and pretty straight forward.
The mining endpoint
Our mining endpoint is where the mining happens and it’s actually very easy as all it has to do are three things:
Calculate proof of work
Reward the miner by adding a transaction granting miner 1 coin
Forge the new Block by adding it to the chain
So, let’s add on the mining function on our API:
At this point, we are done, and we can start interacting with out blockchain. 🙂
You can use a plain old cURL or Postman to interact with our Blockchain API ovet the network.
Fire up the server:
So first off let’s try mining a block by making a GET request to the “mine” http://localhost:5000/mine:
Motherfucker, very good! 🙂
Now lets create a new transaction by making a POST request to http://localhost:5000/transaction/new with a body containing our transaction structure. Let’s make this call using the cURL:
I have restarted the server, mined two blocks, to give 3 in total. So let’s inspect the full chain by requesting http://localhost:5000/chain:
For this we will be using Python NaCl to generate a public/private signing key pair: private.key, public.key which need to be generated before runtime. We will employ the cryptography using the Public-key signature standards X.509 for Public Key Certificates.
This is very cool. Wallet is a gateway to decentralized applications on the Blockchain. It allows you to hold and secure tokens and other crypto-assets. This Blockchain example is built on ERC-20 standards and therefore should be compatible and working out of the box with your regular wallet. 🙂
This is very cool actually. We’ve got a fully valid basic Blockchain that accepts transactions and allows us to mine a new block (and get rewarded for it). But the whole point of Blockchains is to be decentralized, and how on earth do we ensure that all the data reflect the same chain? Well, it’s actually a well know problem of Consensus, and we are going to have to implement a Consensus Algorithm if we want more that a single node in our network. So better buckle up, we’re moving onto registering the new nodes. 🙂
Registering new Nodes
OK, first off, before you start adding new nodes you’d need to let your node to know about his neighbouring nodes. This needs to be done before you even start implementing Consensus Algorithm. Each node on our network needs to keep registry of other nodes on the network. And therefore we will need to add more endpoints to orchestrate our miner nodes:
- /miner/register – to register a new miner node into the operation
- /miner/nodes/resolve – to implement our consensus algorithm to resolve any potential conflicts, making sure all nodes have the correct and up to date chain
First we’re goint to modify the Blockchain class constructor and add in the method for registering nodes:
Implementing the Consensus Algorithm
As mentioned, conflict is when one node has a different chain to another node. To resolve this, we’ll make the rule that the longest valid chain is authoritative. In other words, the longest valid chain is de-facto one. Using this simple rule, we reach Consensuns amongs the nodes in our network.
OK so the first method the valid_chain loops through each block and checks that the chain is valid by verifying both the hash and the proof.
The resolve_conflicts method loops through all the neighbouring nodes, downloads their chain and verify them using the above valid_chain method. If a valid chain is found, and it is longer than ours, we replace our chain with this new one.
So, what is left are the very last two API endpoints, specifically one for adding a neighbouring node and another for resolving the conflicts, and it’s quite straight forward:
And here comes the big one, the one you have been waiting for as at this point you can grab a different machine or a computer if you like and spin up different miners on our network. 🙂
Or you can run multiple miners on your single machine by running the same process but using a different port number. As an example, I can run another miner node on my machine by running it on a different port and register it with the current miner. Therefore I have two miners: http://localhost:5000 and http://localhost:5001.
Registering a new node
Request OK, returned:
Consensus Algorithm at Work
Request OK, returns:
And that’s a wrap… Now go get some friends to mine your Blockchain. 🙂
Have fun! 🙂