Most people finds Blockchains is not an easy platform to use and understand. If you trudged through dense videos about it and nearly give up, let try my own way.
When we study Maths, we first learn formulas and understand them by applying in problems. In our opinion, we think it is an effective method. The fastest way to learn how Blockchains work – the fundamental technology behind them is to build one by ourselves.
Before you get started…
You need to know that a blockchains is an immutable, sequential chain of records – which called Blocks. They can contain transactions, files or any data. However, the important thing is that they are chained together by using hashes.
Who is this guide aimed at? You should be comfy reading and writing some basic Python, as well as have some understanding of how HTTP requests work, since we’ll be talking to our Blockchain over HTTP.
What do I need? Make sure that Python 3.6+ (along with pip) is installed. You’ll also need to install Flask and the wonderful Requests library. In addition, you’ll also need an HTTP Client, like Postman or cURL. And the source code is available here.
Step 1: Building a Blockchain
Firstly, open up your favourite text editor or IDE and create a new file, called blockchain.py.
We’ll only use a single file, but if you get lost, you can always refer to the source code.
What does a Block look like?
Each Block includes an index, a timestamp (in Unix time), a list of transactions, a proof, and the hash of the previous Block.
At this point, the idea of a chain should be apparent – each new block contains within itself, the hash of the previous Block. This is crucial because it’s what gives blockchains immutability: If an attacker corrupted an earlier Block in the chain then all subsequent blocks will contain incorrect hashes.
Adding Transactions to a Block
We’ll need a way of adding transactions to a Block. Our method is responsible for this, and it’s pretty straight-forward.
After new_transaction() adds a transaction to the list, it returns the index of the block which the transaction will be added to – the next one to be mined. This will be useful later on, to the user submitting the transaction.
Creating new Blocks
When our Blockchain is instantiated we’ll need to seed it with a genesis block – a block with no predecessors. We’ll also need to add a “proof” to our genesis block which is the result of mining (or proof of work). We’ll talk more about mining later.
Understanding Proof of Work
A Proof of Work algorithm (PoW) is how new Blocks are created or minedon the blockchain. The goal of PoW is to discover a number which solves a problem. The number must be difficult to find but easy to verify. This is the core idea behind Proof of Work.
In Bitcoin, the Proof of Work algorithm is called Hashcash. It’s the algorithm that miners race to solve in order to create a new block. In general, the difficulty is determined by the number of characters searched for in a string. The miners are then rewarded for their solution by receiving a coin—in a transaction.
Step 2: Our Blockchain as an API
We’re going to use the Python Flask Framework. It’s a micro – framework and it makes it easy to map endpoints to Python functions. This allows us talk to our blockchain over the web using HTTP requests.
We’ll create three methods:
- /transactions/new to create a new transaction to a block
- /mine/ to tell our server to mine a new block.
- /chain/ to return the full Blockchain.
The Transactions Endpoint
This is what the request for a transaction will look like. It’s what the user sends to the server.
Since we already have our class method for adding transactions to a block, the rest is easy. Let’s write the function for adding transactions.
The Mining Endpoint
Our mining endpoint is where the magic happens, and it’s easy. It has to do three things:
- Calculate the Proof of Work
- Reward the miner (us) by adding a transaction granting us 1 coin
- Forge the new Block by adding it to the chain
Note that the recipient of the mined block is the address of our node. And most of what we’ve done here is just interact with the methods on our Blockchain class. At this point, we’re done, and able to start interacting with our blockchain.
Step 3: Interacting with our Blockchain
You can use plain old cURL or Postman to interact with our API over a network.
- Fire up the server:
- Let’s try mining a block by making a GET request to http://localhost:5000/mine:
You also can create a new transaction by making a POST request to http://localhost:5000/transactions/new with a body containing our transaction structure. And if you aren’t using Postman, then you can make the equivalent request using cURL.
Step 4: Consensus
This is very cool. We’ve got a basic Blockchain that accepts transactions and allows us to mine new Blocks. But the whole point of Blockchains is that they should be decentralized. And if they’re decentralized, how on earth do we ensure that they all reflect the same chain?
This is called the problem of Consensus, and we’ll have to implement a Consensus Algorithm if we want more than one node in our network.
Registering new Nodes
Before we can implement a Consensus Algorithm, we need a way to let a node know about neighbouring nodes on the network. Each node on our network should keep a registry of other nodes on the network. Thus, we’ll need some more endpoints:
- /nodes/register to accept a list of new nodes in the form of URLs.
- /nodes/resolve to implement our Consensus Algorithm, which resolves any conflicts – to ensure a node has the correct chain.
We’ll need to modify our Blockchain’s constructor and provide a method for registering nodes:
Note that we’ve used a set() to hold the list of nodes. This is a cheap way of ensuring that the addition of new nodes is idempotent – meaning that no matter how many times we add a specific node, it appears exactly once.
Implementing the Consensus Algorithm
As mentioned, a 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 chain on the network is the de-facto one. Using this algorithm, we reach Consensus amongst the nodes in our network.
The first method valid_chain() is responsible for checking if a chain is valid by looping through each block and verifying both the hash and the proof.
resolve_conflicts() is a method which loops through all our neighbouring nodes, downloads their chains and verifies them using the above method. If a valid chain is found, whose length is greater than ours, we replace ours.
Let’s register the two endpoints to our API, one for adding neighbouring nodes and the another for resolving conflicts:
At this point you can grab a different machine if you like, and spin up different nodes on your network. Or spin up processes using different ports on the same machine. I then mined some new Blocks on node 2, to ensure the chain was longer. Afterward, I called GET /nodes/resolve on node 1, where the chain was replaced by the Consensus Algorithm.
Finally, go get some friends together to help test out your Blockchain.