BlockChain 101 (C#)

Achindra Bhatnagar
Achindra
Published in
6 min readMay 14, 2018

I experiment and some experiments produce cool solutions, but I often fail to find a “Problem”. People often ask, “you have achieved something great, but where are you going to use it?” And I am like, :-? will figure it out

In 2008, someone (or group) named Satoshi Nakamoto conceptualized blockchain as a core component of Cryptocurrency — Bitcoin. It served as a distributed public ledger (Although, first work dates back to 1991 as secure chain of blocks). Blockchain is an interesting technology with a lot of promise, driving a lot of buzz.

Blockchain 2.0 is where we start talking about new applications of distributed blockchain databases. And here, it becomes THE buzz. People are talking about blockchain as one solution that will bring total democracy and solve problems of trust. However, none has realized yet, or at least I can’t see it out there — “will figure out…” ;-)

Yet, it is an interesting technology to learn.

So what is Blockchain?

Blockchain is a distributed public ledger that records transactions and these records are immutable. A bunch of records (Transactions) form a block which are chained using Hashes. These records can contain transactions, files or anything else of your interest.

[Chain of Blocks of Things]

Block

Block is a container data structure. It has a header and a list of records. Something like -

class Block
{
public UInt64 BlockIndex { get; set; }
public DateTime UnixTimestamp { get; set; }
public String PreviousBlockHash { get; set; }
...
public List<Record> Records { get; set; } //Transactions
}

Each block has a hash of previous block (N-1) which makes it immutable, i.e. to tamper a block, you need to change the whole chain. Interesting, right! If someone changes a block (in turn it’s hash), all future blocks will have incorrect hashes!

It is like a linked list where each node has a hash of the previous node. Previous node has embedded hash of its predecessor thus the current hash uses the hash saved in previous node. This means that Hash in any given node is calculated over the hashes of all previous nodes. Thus, to replace a node you need to replace the hash from that node all the way to the current node. Hence, immutable!

(H) - A->B->C->...Node A = a + hash(b);
Node B = b + hash(c);
Node C = c + hash(d);

Transaction

A Transaction is a record that you want to log in this distributed ledger and make it irreversible. You can add any number of Transactions to a block that have not been added to another block before.

In Bitcoin, a new Block is created every 10 min. i.e all transactions in those 10 min are added to a block.

Let's say you are creating a Blockchain of command history. And, your commit interval is 10 min. Your record might look like -

class Record
{
public DateTime CommandTimeStamp { get; set; }
public String UserOnTerminal { get; set; }
public String CommandExecuted { get; set; }
}

BTW, First block in the chain is called a Genesis block.

I would maintain an internal list of Blocks forming my BlockChain and an internal list of Records/Transactions that I attach to a given block.

private List<Block>  _BlockChain  = new List<Block>();
private List<Record> _CurrRecords = new List<Record>();

Now we need a method to create and add a transaction (record) to a given block. This method will return the next block index that will hold this record.

public UInt64 AddRecord(DateTime timeStamp,
String user,
String command)
{
var Record = new Record
{
CommandTimeStamp = timeStamp,
UserOnTerminal = user,
CommandExecuted = command
};
_CurrRecords.Add(Record); // Return index of next block
return _BlockChain.Last().BlockIndex + 1;
}

What is Proof of Work?

Proof of Work or PoW is a complex mathematical problem, an attestation mechanism, to discovers a number that is difficult to find but easy to verify. (bla bla bla). For example, find a Public-Private key pair to encrypt a block such that the hash output has 20 trailing 0s. This makes finding such a key very difficult, however very easy to verify!

For our purpose, we will try to find a number that when hashed with PreviousBlockHash and previous ProofOfWork generate a hash that has trailing "C3".

private UInt64 GenerateProofOfWork(UInt64 PrevProofOfWork,
string PreviousBlockHash)
{
UInt64 proofOfWork = 0;
string hashBytes = Convert.ToString(PrevProofOfWork)
+ Convert.ToString(proofOfWork)
+ PreviousBlockHash;
while (!GetHash(hashBytes).EndsWith("C3"))
proofOfWork++;
return proofOfWork;
}

You see, finding this ProofOfWork is tremendously difficult. To optimise, you may want to run parallel job and there is no way to guess due to un-guessability of SHA.

Why C3? Well, just to show that putting a limit like this makes it so difficult. BitCoins require several 0s and that make it so more difficult.

borrowed from piotrpasich

Who is a Miner?

Miners are the nodes in the network that validate transactions, add them to the current block and then broadcast the block to all nodes in the network. Each Mining node needs to register itself with the network so they know about other nodes and other nodes know about them. They are the transaction managers.

Each node needs a unique identifier, I used a GUID.

public string MyMinerNodeId = Guid.NewGuid().ToString();
private HashSet<Uri> _MinerNodes = new HashSet<Uri>();
private void RegisterMiningNodes(Uri MinerId)
{
_MinerNodes.Add(MinerId);
}

When my server comes up, it will register all other mining nodes to send the blocks to. It will create a default block and start accepting new records/transactions.

On my mining node, you can

  • Send new records/transactions to add to current block
  • Query for the BlockChain
  • Request to mine a new block
public List<Block> GetBlockChain(Uri dummy)
{
// Go to Uri and fetch their blockchain
return _BlockChain;
}

I might create a new Block every 10 min and for that I'll have to mine a valid ProofOfWork. If I do succeed to find a PoW before others, I am to be rewarded! But what if someone else also reports a PoW when I do?

Problem of Consensus

A basic rule here is: if two mining nodes report PoW, the one with longest valid chain of blocks is winner.

So, the first thing is to validate if the block chain is valid. For that, we loop through each block and verify the Hash and the PoW. Remember, verifying PoW is a much easier job compared to its calculation.

private bool IsValidBlockChain(List<Block> chain)
{
int index = 1;
Block prevBlock = chain.First();
while(index < chain.Count)
{
Block block = chain.ElementAt(index);
if(block.PreviousBlockHash != FindHash(prevBlock))
{
return false;
}
string hashBytes = Convert.ToString(prevBlock.ProofOfWork)
+ Convert.ToString(block.ProofOfWork)
+ prevBlock.PreviousBlockHash;
if (!IsValidPoW(hashBytes))
{
return false;
}
prevBlock = block; index++;
}
return true;
}

Now, to resolve conflict, we shall download the BlockChain from all the nodes, validate their PoW and if there's one larger than ours, we'll replace ours with theirs. We already have an endpoint on the Miner (2) to get the complete chain from that node.

private bool ResolveConflict()
{
List<Block> tmpChain = _BlockChain;
foreach(Uri node in _MinerNodes)
{
List blockChain = GetBlockChain(node);
if((blockChain.Count > tmpChain.Count) &&
IsValidBlockChain(blockChain))
{
tmpChain = blockChain;
}
}
if(tmpChain != _BlockChain)
{
_BlockChain = tmpChain;
return true;
}
return false;
}

What's Next?

I don't understand yet, what if I create smaller blocks of 10 transactions each, Just because my chain is larger, won't I always win over those who are adding all transactions in last 10 min to one block?

I am yet to discover how miners are rewarded and how they make money from transaction fees. I suspect, on the name of 'trust no-authority', it is a very high cost we would end up paying to these miners to maintain a distributed ledger.

The PoW calculation is so costly that we end up burning a lot of CPU in its computation. Is it worth spending exhorbant amount of energy?

The other part of hype around block chain transactions is the anonymity buzz. However, transactions are open in block chain for scrutiny. Only the identity is not. And if identity can be established, what's left?

I'll share complete code and host my Miner somewhere on Azure. I will also create a client application through which you can post new records to these Miners.

Stay Tuned!

--

--