Programming

BlockChain 101 (C#)

I experiment and at times I do come up with some cool solutions, but I 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 tremedously difficult. To optimize, you may want to run parallel job and there is no way to guess due to unguessability 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

  1. Send new records/transactions to add to current block
  2. Query for the BlockChain
  3. 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!

I am a curious mind, always building and experimenting, trying things to decode their inner design. Kind of a small scale inventor ;-) I like to help people realise their passion.

5 Comments

  • ramteja tadishetti

    Nice post, if you are wondering whether your chain which has tiny blocks of 10 transactions will be valid or not , then yes PoW blockchains always assume that longest chain is the valid blockchain. The only problem overhere is mining a block, in general probability of a miner mining a block in a given interval is proportional to his/her relative mining power . So its not trivial to mine block.
    Rewards to miners – Generally miners include a transaction in a block which transfers agreed coinbase reward to themselves .
    PoW in general is so costly. There are another set of approaches like Proof of Stake which decide the valid blockchain. Casper is one such approach in Ethereum
    There are some cryptocurrencies like zero coin which do not leak any info even though transactions are public. AFAIK they rely on zero knowledge proofs.

    • Achindra

      Thanks Ram. About small blocks, my concern is that the miners decide which transaction to include in their block and hence a miner is free to create small block and mine more frequently or start mining before others. Since Winner is decided on the size of chain and hence won’t there be an undue advantage if one miner starts before others?
      Also that if a miner can be selective about recording transactions, how is it guaranteed that all transactions eventually make into the ledger?

      • ramtejatadishetti

        Yeah there will be undue advantage for one miner if he starts early than the rest of the world since it gives him more time which is some what proportional to more PoW but this applies until he publishes his block. The moment he publishes all will start from the newer chain.
        Also a miner could act maliciously by avoiding publishing blocks to main chain and release them at once i.e selfish mining which invalidates the blocks on another chain since newly published chain is longer ( I think you mentioned small blocks for this reason)
        Miner could be selective about recording transactions. Generally miner charges some fee for committing a transaction on blockchain. If he doesn’t care to commit them on public ledger, he won’t be gaining his fee .

        • Achindra

          Exactly!
          If we are dealing with a ledger of transaction (real money) and I am rogue miner (anyone can be a miner). I can purposefully drop or add (malicious transactions) and continue to work to find my ‘opportunity’ to spoil a transaction chain.
          Rogue miner here won’t be concerned about losing small fee because his “rogue” client will be paying for this jugglery.
          A rogue miner may want to add transactions favoring him i.e. add false transaction where some money is transferred to him. That’s more money than what one might lose in dropping fees from selective transactions!
          Does this mean Blockchain transactions are “immutable” is a false claim?

  • ramteja tadishetti

    No, they are indeed immutable i.e given some probabilistic bounds.
    ” A rogue miner may want to add transactions favoring him i.e. add false transaction where some money is transferred to him ” this is not possible since transaction does not actually work like balances in bank account . We could think transaction are functions in which we have input like UTXO ( unspent transaction output) i.e the amount that could be used in a transaction, public keys of receivers and hash of entire transaction , which returns ouput UTXO . The hash of the entire transaction stops the miner to execute malicious transactions ie changing the address. If we really want to execute a fake transaction then we need to make sure hash collision occurs with a given public key which is kind of hard to make it happen.
    Putting it all together to make a new transaction we need UTXO , transaction Faking both UTXO, transaction is not possible in general.

Leave a Reply

Your email address will not be published. Required fields are marked *