I'm pretty sure that almost every developer in the world has heard of Blockchain, some wrongly consider it as Bitcoin and some may not know how it exactly works. So this post aims to explain what exactly Blockchain is and how to create a simple blockchain in ".Net Core" using C#, and to figure out how Blockchain really works at the end.
- Defining models (Transaction + Block)
- Using TransactionPool for storing raw Transactions
- Using hash algorithm in order to create immutability
- Creating a block mining unit which mine blocks after a period of time
- Using embedio in order to view our blockchain in a web browser
Literally, Blockchain is a chain of blocks which could be simply assumed as an immutable data structure. Immutability is one of the most prominent features of a blockchain, which leads us to build trust in completely unreliable environments.
This kind of immutability is achieved by using Cryptographic hashing algorithms, (in our case we use Double SHA256). which prevents data from being changed or deleted after data is added to the Blockchain.
As it's obvious in the following image; Two different hashes are stored in every block, one hash is calculated for the current block and the other, is for the previous one. so any change in a block invalidates every block after it.
First of all, as we are to use ".Net Core", it's necessary to install ".NET Core" 3.1 Framework (or any other preferred version).
You could find more about installation here.
After installation completes, we should create our project using dotnet CLI
dotnet new console Blockchain.
dotnet add package Newtonsoft.Json dotnet add package EmbedIO
Now that our project is ready, let's define our data models. Our first step is to define a model for transaction.
The From property identifies the sender of the money, the To property identifies the receiver of the money and the Amount represents the amount of money sent.
Let's create our next model, which is a Block's model. As we know, Each block contains data that will be written to the blockchain. Block data model has a list of transactions which are processed in the current block and two strings for storing hashes of the current Block(Hash) and the previous one(PrevHash). There are two other properties in every Block, Nounce is used for the mining algorithm and TimeStamp goes for DateTime of Creation of Block.
It's time to define our Transaction Pool class, which is used for storing unprocessed transactions during the time that a transaction is received and added to our blockchain. there are two methods in Transaction pool; one for adding raw Transactions (AddRaw), and the other one for getting all unprocessed transactions(TakeAll).
This is the time to define our main class which is BlockMiner class. First, we model out the blockchain itself which is simply a list of Blocks.
We should now define a function which is responsible for calculating hash of raw string data and returning the result as hashed string. As it's obvious we are using SHA256 algorithm since it has been used in other famous blockchains like Bitcoin.
So as we create our hashing function, now we have to find a way to calculate hash of our block. The primary problem we're facing here is to find a way to calculate a hash for the list of transactions existing in the ongoing block. As you may know already Merkle Tree is what comes into use here. You can learn more about it here
Notice that by using Merkle tree any little change in a transaction will lead to change in Block's hash and will effect every other Block after corresponding block.
We simply use discussed algorithm to calculate hash of all transactions in a block.
Now we need to write our mining function that tries to find appropriate Hash for our ongoing block (starts with specific amount of '0' at the start of hash). The way that we extract the appropriate hash is by incrementing nounce property defined in block and calculating the hash again and again until we reach our goal. Originally this kind of mining algorithms are called Proof of work which are very useful these days.
After our mining process is done we can simply add our mined block to the blockchain.
At this point, we need one extra function in BlockMiner class which is responsible for continuously mining Blocks and we need two final functions to start and stop the mining process.
Let's create our HTTP server using embedio which is a tiny, cross-platform, module based web server.
Our controller has four methods, three of them will be used for exposing blockchain data and the other one will be used for adding new transactions to blockchain.
Let’s try it out now.
Fire up your application from terminal using command below
you will see something like this in your terminal
Now, let’s send some POST requests to add blocks.
Now if you navigate to http://localhost:5449/api/blocks/latest or http://localhost:5449/api/blocks you will see mined blocks directly in your browser.