Building A Blockchain In .NET Core - Basic Blockchain

Introduction

 
Blockchain technology is the foundation of Bitcoin, the most popular cryptocurrency in the world. With the popularity of Bitcoin, Blockchain has also got great exposure. People have now started to use Blockchain in other-than-cryptocurrency kinds of applications too. Looking at Satoshi Nakamoto's (the founder of blockchain) Bitcoin whitepaper, you could get confused about how bitcoin works. Today, I am going to build a blockchain from scratch to help everybody understand the mechanism of the blockchain.
 
What is Blockchain?
 
Blockchain is a database. What is a database? A database is an organized collection of data. Or, you can say, a data structure that stores the data. Therefore, Blockchain is just a data structure that stores the data. As the name hinted, there will be a chain of blocks. 
 
Chain of Blocks
 
Below is the architecture diagram of a basic blockchain.
 
Blockchain
 
This basic blockchain has a linked list that is composed of blocks. Each block has the following properties.
  • Index
  • Timestamp
  • Previous Hash
  • Hash
  • Data
The first block is a special block: genesis block. The genesis block is the only block that has no previous blocks and does not contain data.
 
Implementation
 
We will add two classes for this data structure: Block and Blockchain.
 
Block
  1. public class Block  
  2. {  
  3.     public int Index { get; set; }  
  4.     public DateTime TimeStamp { get; set; }  
  5.     public string PreviousHash { get; set; }  
  6.     public string Hash { get; set; }  
  7.     public string Data { get; set; }  
  8.   
  9.     public Block(DateTime timeStamp, string previousHash, string data)  
  10.     {  
  11.         Index = 0;  
  12.         TimeStamp = timeStamp;  
  13.         PreviousHash = previousHash;  
  14.         Data = data;  
  15.         Hash = CalculateHash();  
  16.     }  
  17.   
  18.     public string CalculateHash()  
  19.     {  
  20.         SHA256 sha256 = SHA256.Create();  
  21.   
  22.         byte[] inputBytes = Encoding.ASCII.GetBytes($"{TimeStamp}-{PreviousHash ?? ""}-{Data}");  
  23.         byte[] outputBytes = sha256.ComputeHash(inputBytes);  
  24.   
  25.         return Convert.ToBase64String(outputBytes);  
  26.     }  
  27. }  
Blockchain
  1. public class Blockchain  
  2. {  
  3.     public IList<Block> Chain { set;  get; }  
  4.   
  5.     public Blockchain()  
  6.     {  
  7.         InitializeChain();  
  8.         AddGenesisBlock();  
  9.     }  
  10.   
  11.   
  12.     public void InitializeChain()  
  13.     {  
  14.         Chain = new List<Block>();  
  15.     }  
  16.   
  17.     public Block CreateGenesisBlock()  
  18.     {  
  19.         return new Block(DateTime.Now, null"{}");  
  20.     }  
  21.   
  22.     public void AddGenesisBlock()  
  23.     {  
  24.         Chain.Add(CreateGenesisBlock());  
  25.     }  
  26.       
  27.     public Block GetLatestBlock()  
  28.     {  
  29.         return Chain[Chain.Count - 1];  
  30.     }  
  31.   
  32.     public void AddBlock(Block block)  
  33.     {  
  34.         Block latestBlock = GetLatestBlock();  
  35.         block.Index = latestBlock.Index + 1;  
  36.         block.PreviousHash = latestBlock.Hash;  
  37.         block.Hash = block.CalculateHash();  
  38.         Chain.Add(block);  
  39.     }  
  40. }  
After we have those two classes, we can create an instance of the new blockchain.
 
Blockchain
 
And, we can add blocks to it.
 
Blockchain
 
Given below is the code.
  1. Blockchain phillyCoin = new Blockchain();  
  2. phillyCoin.AddBlock(new Block(DateTime.Now, null"{sender:Henry,receiver:MaHesh,amount:10}"));  
  3. phillyCoin.AddBlock(new Block(DateTime.Now, null"{sender:MaHesh,receiver:Henry,amount:5}"));  
  4. phillyCoin.AddBlock(new Block(DateTime.Now, null"{sender:Mahesh,receiver:Henry,amount:5}"));  
  5.   
  6. Console.WriteLine(JsonConvert.SerializeObject(phillyCoin, Formatting.Indented));  
The Blockchain information will be serialized into JSON and the output in console.
 
Validation
 
One of the advantages of using blockchain is data security. Data security means that tampering with the old data and altering the method of securing new data is prevented by both the cryptographic method and the non-centralized storage of the data itself. However, blockchain is just a data structure in which data can be easily changed like this.
  1. phillyCoin.Chain[1].Data = "{sender:Henry,receiver:MaHesh,amount:1000}";  
Therefore, we need a way to validate the data. This is why I have added an IsValid method to the code.
  1. public bool IsValid()  
  2. {  
  3.     for (int i = 1; i < Chain.Count; i++)  
  4.     {  
  5.         Block currentBlock = Chain[i];  
  6.         Block previousBlock = Chain[i - 1];  
  7.   
  8.         if (currentBlock.Hash != currentBlock.CalculateHash())  
  9.         {  
  10.             return false;  
  11.         }  
  12.   
  13.         if (currentBlock.PreviousHash != previousBlock.Hash)  
  14.         {  
  15.             return false;  
  16.         }  
  17.     }  
  18.     return true;  
  19. }  
The IsValid method will check two things.
  • Each block’s hash to see if the block is changed
  • Previous block’s hash to see if the block is changed and recalculated
Then, we call the IsValid before the data tampering and after the data tampering to see if there are any data issues.
  1. Console.WriteLine($"Is Chain Valid: {phillyCoin.IsValid()}");  
  2.   
  3. Console.WriteLine($"Update amount to 1000");  
  4. phillyCoin.Chain[1].Data = "{sender:Henry,receiver:MaHesh,amount:1000}";  
  5.   
  6. Console.WriteLine($"Is Chain Valid: {phillyCoin.IsValid()}");  
How about the case when the attacker recalculates the hash of the tampered block?
  1. phillyCoin.Chain[1].Hash = phillyCoin.Chain[1].CalculateHash();  
The Validation result will still be false because the validation not only looks at the current block but also at the link to the previous block.
 
Now, what about the case when an attacker recalculates hashes of all the current block and the following blocks?
  1. Console.WriteLine($"Update the entire chain");  
  2. phillyCoin.Chain[2].PreviousHash = phillyCoin.Chain[1].Hash;  
  3. phillyCoin.Chain[2].Hash = phillyCoin.Chain[2].CalculateHash();  
  4. phillyCoin.Chain[3].PreviousHash = phillyCoin.Chain[2].Hash;  
  5. phillyCoin.Chain[3].Hash = phillyCoin.Chain[3].CalculateHash();                  
After all the Blocks are recalculated, the verification is passed. However, this is only passed on one node because Blockchain is a decentralized system. Tampering with one node could be easy but tampering with all the nodes in the system is impossible.
 

Summary

 
A Blockchain is a chain of blocks. It uses cryptography to ensure data integrity.  You can open and run the sample code in Visual Studio 2017. This is the first article in my "Building a Blockchain in .NET Core" series.