Blockchain explained using C# implementation | by Czako Zoltan | Towards Data Science

As I’ve promised, the next topic is Blockchain. In this article, I want to explain the main idea and I will give a simple C# implementation of a blockchain. This article will have a follow-up, an article in which I will explain how to use Bitcoin in .Net and I will give code examples resolving real world problems.
I don’t think so! When people are arguing about blockchain, they are always throwing words and phrases like Trust and Transparency, Cost Effectiveness, Unbreakable, Availability, Simplified Business and Decentralization. When you want to promote something, these are the buzzwords to use, everybody wants trust, cheap service, security etc. But these are just buzzwords, don’t fall in the trap of beautiful lies. I don’t want to argue that blockchain is very useful and a clever “thing”, but you can’t use it for everything.
Blockchain has advantages and also disadvantages, but if you read articles or watch tech news, most certainly you will hear just about the advantages of it, because there are people who can win lots of money because Bitcoin and other cryptocurrencies and these are based on blockchain.
In the next paragraphs, I will show some disadvantages of blockchain, but first let's see what is a blockchain and how does it work.
Ok, the first step to understand blockchain is to understand that Blockchain is NOT equivalent to Bitcoin or any other cryptocurrencies. Blockchain gained popularity, because of Bitcoin, you can think about these two things as raw gold, which is the Blockchain and coin (or jewelry) which is the Bitcoin.
Basically Blockchain is a data structure, just as arrays, list, trees or other data structures that you’ve learned at school or at work. What is cool about this data structure are two facts.
The first fact is that a change in any block invalidates every block after it, which means (in the case of cryptocurrencies) that you can’t tamper with historical transactions.
The second cool thing is that you only get rewarded if you’re working on the same chain as everyone else, so each participant has an incentive to go with the consensus.
Following the rules is mathematically enforced — no government or police force need to come in and tell you the transaction you’ve logged is false. Yes it is a very powerful idea, but nothing is perfect, you’ll see in the next chapters!
Let's suppose that we want to implement our own blockchain (just for educational purposes). The first step is to define what does a block mean. Talking in OOP, a block is an object, which has multiple properties. The basic properties of this object are the data (which can be anything, but for cryptocurrencies, the data is the transaction and a timestamp for history), the hash of the block (we will see how can we calculate this hash) and the hash of the previous block. In our implementation, we will add another interesting property, called in the literature nonce, which is used for mining new blocks (we will see how).
As you can see, this is a linear data structure, like a linked list, with two important properties, hash and previous hash. You can imagine the hash of the block as a fingerprint, which uniquely identifies the content of the block. If you change something inside the block will cause the hash to change (change detection). The previous hash creates a chain of blocks and makes the blockchain secure. If you change a block, the hash of the block will also change, so the next block will have invalid previous hash. So changing a block will make all the following blocks invalid. The first block is a special block because this cannot have a valid previous hash (there is no previous block). This block is called Genesis Block, and the previous hash is set to a string of one or more zeros.
Let's take an example! If we have the following chain
and we modify something in the second block, the hash will also change, like in the figure below.
The effect of this slight modification is that the following block will have an invalid previous hash, so all the following blocks will be invalid. But this is not enough to prevent tampering. You can say that, after altering the block, we will recalculate all the hashes for the following blocks. Yes, that would be a solution, this is why the creators of the blockchain invented some rules, making hard and time-consuming to recalculate valid hashes.
To make hash calculation a hard work, the inventors of blockchain introduced the so-called Proof-of-Work. Basically the proof-of-work is just an invented constraint to make calculation harder. This constraint says that the hash of each block must begin with X number of zeros. This makes the computation really hard because you don’t have a better solution than brute force, guess and check. So you have to check all the possibilities to find a hash which has X number of leading zeros. This is another example when we secure something using very hard calculations. So this is why the blockchain will have no value when the first real Quantum Computer will appear (Quantum Computers will have the power to recalculate all the hashes much faster than classical computers, see my other article about Quantum Computing)
Another way in which blockchains secures themselves is by being distributed. It uses a P2P network where everyone is allowed to join. When you join this network, you will receive a full copy of the blockchain (currently for Bitcoin the blockchain is approximately 200GB large). When somebody creates a new block, it will be sent to all the peers. Each peer will verify that the block was not tampered with and if not then it will be added to the chain otherwise it will be rejected. This way, in order to add a block to the chain, 51% of the peers must agree that the block was not tampered with.
So in order to “hack” the chain, you will have not only to recalculate all the hashes, but to fool more than 50% of the peers. This is (currently) impossible. This is why the blockchain is so secure, it is secured not by the government or other parties, but by hard mathematical problems, which is great, but not always.
Blockchains are constantly evolving. One of the most important development is the Smart Contracts. In short, these contracts are simple programs stored on the blockchain which can be used to exchange cryptocurrencies automatically.
However it is not recommended to implement your own blockchain, but to use existing ones, in this section I will implement a simple blockchain just for educational purposes. In the next article, I will show you how to use the existing blockchain of Bitcoin in .Net (using NBitcoin).
The first step is to define the structure of a block. The code for a block is the following:
public class Block{    private readonly DateTime _timeStamp;    private long _nonce;    public string PreviousHash { get; set; }    public List<Transactions> { get; set; }        public string Hash { get; private set; }        public Block(DateTime timeStamp, List<Transactions> transactions, string previousHash = "")    {        _timeStamp = timeStamp;        _nonce = 0;        Transactions = transactions;        PreviousHash = previousHash;        Hash = CreateHash();    }    public void MineBlock(int proofOfWorkDifficulty)    {        string hashValidationTemplate = new String('0', proofOfWorkDifficulty);                while (Hash.Substring(0, proofOfWorkDifficulty) != hashValidationTemplate)        {            _nonce++;            Hash = CreateHash();        }        Console.WriteLine("Blocked with HASH={0} successfully mined!", Hash);    }    public string CreateHash()    {        using (SHA256 sha256 = SHA256.Create())        {            string rawData = PreviousHash + _timeStamp + Transactions + _nonce;            byte[] bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(rawData));            return Encoding.Default.GetString(bytes);        }     }}
In my implementation I’ve used the following properties:
_timestamp: time of block creation (to have a history)PreviousHash: contains the hash of the previous block in the chainHash: hash of the block calculated based on all the properties of the block (change detection)Transactions: this is the data stored in the blocks; here I’ve used a list of transactions, just to have an example similar to cryptocurrencies_nonce: to mine a block, we have a rule (the proof-of-work) about hashes, the hash of a valid block must start with x number of zeros. This can be calculated only by brute force, so try all the possibilities. To have different hashes, we have to modify something in the input data of the hash function. Evidently we cannot modify the list of transactions, the previous hash or the timestamp, so we have to add an artificial property, which can be modified in each step. For simplicity, I’ve added a long value which will be incremented in each step. This value will be added to the input data of the hash function, this way we will get different hashes in each step.
_timestamp: time of block creation (to have a history)
PreviousHash: contains the hash of the previous block in the chain
Hash: hash of the block calculated based on all the properties of the block (change detection)
Transactions: this is the data stored in the blocks; here I’ve used a list of transactions, just to have an example similar to cryptocurrencies
_nonce: to mine a block, we have a rule (the proof-of-work) about hashes, the hash of a valid block must start with x number of zeros. This can be calculated only by brute force, so try all the possibilities. To have different hashes, we have to modify something in the input data of the hash function. Evidently we cannot modify the list of transactions, the previous hash or the timestamp, so we have to add an artificial property, which can be modified in each step. For simplicity, I’ve added a long value which will be incremented in each step. This value will be added to the input data of the hash function, this way we will get different hashes in each step.
In the constructor of the class, we initialize all the properties and using the CreateHash method we calculate the hash of the block based on all properties of the block. This way, if anything will change inside the block, it will have a different hash, so a change can be easily detected.
In the CreateHash method, we use SHA256 to create a hash based on all the properties of the block.
The MineBlock method will be used by the miners to create new valid blocks. The input parameter defines the difficulty of calculating new hashes. This parameter defines how many zeros must be at the beginning of the hash. This has exponential growth, so you should choose this number carefully. If you choose a very big number, it will take week, months or years to calculate a hash. For our example, we will use proofOfWorkDifficulty = 2. In this method, we have a simple while, which will run until we find a hash which has a number of leading zeros equal to the proofOfWorkDifficulty. In each step, we increase the value of the _nonce and recalculate the hash.
IMPORTANT: the list of transactions must be a private variable, I used it as a public variable, just because I wanted to have access to it, to modify the transactions, this way demonstrating change detection and chain validity/invalidity.
The Transaction class looks like this:
public class Transaction{    public string From { get; }    public string To { get; }    public double Amount { get; }    public Transaction(string from, string to, double amount)    {        From = from;        To = to;        Amount = amount;    }}
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.
The last class is the BlockChain class, see the code below.
public class BlockChain{    private readonly int _proofOfWorkDifficulty;    private readonly double _miningReward;    private List<Transaction> _pendingTransactions;    public List<Block> Chain { get; set; }    public BlockChain(int proofOfWorkDifficulty, int miningReward)    {        _proofOfWorkDifficulty = proofOfWorkDifficulty;        _miningReward = miningReward;        _pendingTransactions = new List<Transaction>();        Chain = new List<Block> {CreateGenesisBlock()};    }    public void CreateTransaction(Transaction transaction)    {        _pendingTransactions.Add(transaction);    }    public void MineBlock(string minerAddress)    {        Transaction minerRewardTransaction = new Transaction(null, minerAddress, _miningReward);        _pendingTransactions.Add(minerRewardTransaction);        Block block = new Block(DateTime.Now, _pendingTransactions);        block.MineBlock(_proofOfWorkDifficulty);        block.PreviousHash = Chain.Last().Hash;        Chain.Add(block);        _pendingTransactions = new List();    }    public bool IsValidChain()    {        for (int i = 1; i < Chain.Count; i++)        {            Block previousBlock = Chain[i - 1];            Block currentBlock = Chain[i];            if (currentBlock.Hash != currentBlock.CreateHash())                return false;            if (currentBlock.PreviousHash != previousBlock.Hash)                return false;        }        return true;    }    public double GetBalance(string address)    {        double balance = 0;        foreach (Block block in Chain)        {            foreach (Transaction transaction in block.Transactions)            {                if (transaction.From == address)                {                    balance -= transaction.Amount;                }                if (transaction.To == address)                {                    balance += transaction.Amount;                }            }        }        return balance;    }    private Block CreateGenesisBlock()    {        List transactions = new List<Transaction> {new Transaction("", "", 0)};        return new Block(DateTime.Now, transactions, "0");    }}
In this class we will have a list of blocks, which represents the blockchain (Chain property).
Because transactions have to be processed by the miners (by mining new valid blocks), we will have a list of pending transactions (_pendingTransactions property). Pending transactions will be added to the new blocks by the miners, this way transitioning from pending transactions to processed transactions.
Also here we will define the difficulty of mining a new block (_proofOfWorkDifficulty property) and a reward, which will get the miner who creates the new block. This is a fixed reward, but in reality there is another reward defined by the sender. This way the sender will persuade the miners to include his/her transaction in the mining process with priority. Choosing the right reward is also a tricky thing. If you choose a too low reward, your transaction will be added later. On the other hand, if you choose a too high reward, your transaction will still be added later, because miners will think that your transaction is very time consuming. They will try to finish all the current processing, so they won’t switch to work on your transaction until they finish all the current transactions. But choosing the right reward is another topic.
In the constructor, we initialize all the properties and we create the Genesis Block using the CreateGenesisBlock method. This creates a block with the previous hash set to zero and with empty transaction list.
We define the MineBlock method which can be used by the miners to mine new blocks. In this method, we firstly add a new transaction, the reward for the miner and after that we call the mine method of the block, to calculate a valid hash for that block. When we already have a valid block, we set its previous hash to the last block’s hash, this way creating a valid chain. Lastly, we clear the pending transactions, because those transactions were already added to a block, so those transactions are finished successfully.
NOTE: this isn’t a distributed implementation, so when the processing of the block is done, we immediately add it to the chain without further check. In reality, in the distributed system, there are lots of miners, so multiple miners will work on a block. Before updating our chain, we should have another validity check. The rule is to always accept the longest chain, so if multiple miners will offer us possible chains, we will accept the longest and the reward will be sent to the miner which wins this game.
The next method is IsValidChain, which is used to check the validity of the chain, to be sure that the chain was not hacked, was not tampered with. This is a very easy check, for each block we recalculate its hash, and if the currently calculated hash is different from the hash added to the block at creation, then it is obvious that the data inside the block was modified. Another check is to compare the current block’s previous hash property with the previous block’s hash property. If there is a difference, then it is obvious that the chain was tampered with. Otherwise, our chain is valid, we can be sure that it wasn’t hacked.
The last method is the GetBalance method, which is used to calculate the balance of a user of the blockchain. The user can be identified by his/her address. To calculate the current balance, we will iterate through all the blocks and through all the transactions. If the sender is the user for which we are calculating the balance, then we will subtract the amount from the balance otherwise if the user is the receiver, then we add the amount to the balance.
NOTE: you can add all kind of business logic to the blockchain, for example before sending you can check if the sender has enough money or not and reject the transaction if the sender doesn’t have enough money or you can define any logic that matches your current business.
The last step is to actually test our code. The next code section contains the main program used to create the blockchain, create transactions, check the validity of the blockchain, try to hack the blockchain and print the content of the blockchain to verify if its structure is correct or not
class Program{    static void Main()    {        const string minerAddress = "miner1";        const string user1Address = "A";        const string user2Address = "B";        BlockChain blockChain = new BlockChain(proofOfWorkDifficulty: 2, miningReward: 10);        blockChain.CreateTransaction(new Transaction(user1Address, user2Address, 200));        blockChain.CreateTransaction(new Transaction(user2Address, user1Address, 10));        Console.WriteLine("Is valid: {0}", blockChain.IsValidChain());        Console.WriteLine();        Console.WriteLine("--------- Start mining ---------");        blockChain.MineBlock(minerAddress);        Console.WriteLine("BALANCE of the miner: {0}", blockChain.GetBalance(minerAddress));        blockChain.CreateTransaction(new Transaction(user1Address, user2Address, 5));        Console.WriteLine();        Console.WriteLine("--------- Start mining ---------");        blockChain.MineBlock(minerAddress);        Console.WriteLine("BALANCE of the miner: {0}", blockChain.GetBalance(minerAddress));        Console.WriteLine();        PrintChain(blockChain);        Console.WriteLine();        Console.WriteLine("Hacking the blockchain...");        blockChain.Chain[1].Transactions = new List<Transaction> { new Transaction(user1Address, minerAddress, 150)};        Console.WriteLine("Is valid: {0}", blockChain.IsValidChain());        Console.ReadKey();    }    private static void PrintChain(BlockChain blockChain)    {        Console.WriteLine("----------------- Start Blockchain -----------------");        foreach (Block block in blockChain.Chain)        {            Console.WriteLine();            Console.WriteLine("------ Start Block ------");            Console.WriteLine("Hash: {0}", block.Hash);            Console.WriteLine("Previous Hash: {0}", block.PreviousHash);            Console.WriteLine("--- Start Transactions ---");            foreach (Transaction transaction in block.Transactions)            {                Console.WriteLine("From: {0} To {1} Amount {2}", transaction.From, transaction.To, transaction.Amount);            }            Console.WriteLine("--- End Transactions ---");            Console.WriteLine("------ End Block ------");        }        Console.WriteLine("----------------- End Blockchain -----------------");    }}
As you can see in this code, I’ve created a blockchain, then I’ve created two transactions. To finish the transactions, I’ve started to mine a block and after that I’ve printed out the balance of the miner, just to see if the miner has received the reward or not. Afterwards, I’ve added another transaction and I’ve mined another block. After that, I’ve printed out the structure of the chain and in the last few lines I’ve modified a block from the blockchain and I’ve checked the validity of the chain.
After running the program we get the following results:
As we can see in the picture, after each block mined, the miner has received the reward, so the rewarding system is correct. I’ve printed out the structure of the blockchain and as you can see, the blocks are correct, they contain all the transactions, in the same order as they were added in the code. The blocks also contains the transactions used to send the rewards to the miner. If we check the previous hashes and the hashes of the block, we can see that we have a valid chain, each hash starts with two zeros, as we defined in the proofOfWorkDifficulty field and each block’s previous hash contains the hash of the previous block. So the block is VALID. (the result of the validity check is in the first row).
In the next step, I’ve tried to hack the chain, but as you can see, after modifying the content of a block, the validity check fails, so we successfully detected the attempt to tamper our blockchain.
Everybody is talking about the advantages of blockchain, but what if these advantages are actually disadvantages? So what is the main problem with the blockchain?
Trust and Transparency
For almost anything people want to be valid, blockchain has been proposed as a solution. It’s true that tampering with data stored on a blockchain is hard, but it’s false that blockchain is a good way to create data that has integrity. Ok, lets explain with examples. When you want to buy something from an online shop, you are just hoping that the seller will actually send you the product. In the traditional system, you’re trusting Visa or Amazon or whatever you use that the seller will send you the bought product. So you trust a third-party to enforce the transaction and to actually receive the bought product. In blockchain there is no third-party, so you will actually trust the good nature of human, that the seller won’t lie to you and he/she will actually send the bought product. I think that this isn’t a very trustworthy system, I don’t trust people, mainly when we are talking about strangers, business and money.
Another good example:
“Keep your voting records in a tamper-proof repository not owned by anyone” sounds right — yet is your Afghan villager going to download the blockchain from a broadcast node and decrypt the Merkle root from his Linux command line to independently verify that his vote has been counted? Or will he rely on the mobile app of a trusted third-party — like the nonprofit or open-source consortium administering the election or providing the software? (see this article: Crappy Blockchain)
Unbreakable
Yes, but it’s just an ideal situation (just like communism, the idea was great, everybody should be equal, but each human is different, so how can we be equal? But this is another topic to discuss, I will have another posts category in which I will talk about philosophy), but in reality, there are lots of factors which can make the blockchain breakable. Just think about it, instead of relying on trust or regulation, in the blockchain world, individuals are on-purpose responsible for their own security precautions. And if the software they use is malicious or buggy, then there will be loopholes to hack that particular individual. Just a stupid example, a simple user, with no programming knowledge, will store the private key of his virtual wallet on his computer. Single point of failure, a hacker will hack his/her computer and stole the key. Actually the hacker didn’t hack the blockchain, he/she just created some valid transactions using the stolen private key. In this situation who will help you to rollback the transactions? Don’t forget that you cannot alter the history of the blockchain! In the traditional system, banks are providing security for their customers and if the security is broken, they will pay you back the stolen money. Every bank has insurance, so you won’t lose all the money for which you worked your entire life. So what do you think, will you trust your own skills to have prefect security and use blockchain or will you trust banks and insurance companies or other security specialists?
I don’t argue that the idea is great, yes, it is a nice and very useful concept, I like the inbuilt change detection, it is easy to detect attempts to hack the history of the chain, it is distributed, which is very useful, safe, no single point of failure in the blockchain, increased availability and it is based on the consensus of the peers. There is no middle man (which sometimes can be very painful and dangerous, will you trust a criminal just because he/she uses blockchain for trading?). But as you can see, too much freedom, too much control can be very dangerous for uninformed or unprepared users!
I really like coffee, because it gives me the energy to write more articles.
If you liked this article, then you can show your appreciation and support by buying me a coffee!
Become a writer on Medium: https://czakozoltan08.medium.com/membership
Crappy BlockchainHow does Bitcoin actually workCreate a blockchainBlockchain explained
Crappy Blockchain
How does Bitcoin actually work
Create a blockchain
Blockchain explained
SUBSCRIBE to my blog, because in the next article I will talk about how to use Bitcoin in .Net (using NBitcoin) and afterwards I will start a series of articles explaining all the popular AI algorithms using very intuitive and easy to understand examples. In the future I will discuss topics like software design, design patterns, parallel computing, cloud and I will also have a category for philosophy, discussing interesting ideas about the world, about the universe and about human nature.