Blockchain in C # (.Net Core 3.1), Part 0

Strong greetings to everyone! The great and mighty Nukras is in touch from the Volgo-Vyatka economic region!

Inspired by this and this article, I, ̶k̶a̶k̶ ̶k̶o̶r̶e̶n̶n̶o̶y̶ ̶o̶d̶e̶s̶s̶i̶t̶ did not fail to cut an interesting idea. Therefore, meet Blockchain in C #, part number zero!

Since this article is, in fact, a sequel to the above articles, I will not dwell on explaining terms such as “blockchain”, “complexity”, “mining” and so on. In those articles, in principle, they told everything quite clearly.

Well, I will note in advance that I am familiar with programming at the level of junior brother, and in general a deer.

Go!

The first step is to define the “Block” class.

class Block
    {
        public Block(string ts, string dat, string hs, int nc) 
        {timestamp = ts; data = dat; hash = hs; nonce = nc; }

        public string timestamp;
        public string data;
        public string hash;
        public int nonce;
    }

In the “Block” class, we will store the time when the block was created, the data that we write to it, its hash and nonce value. I consider it unnecessary to store anything else in the block.

We will store the chain of blocks in a list:

public static List<Block> blockchain = new List<Block>();

And this list will be in the “Blockchain” static class:

static class Blockchain
{
  	public static List<Block> blockchain = new List<Block>();
}

In order to add blocks, let’s write the “AddBlock” method. This method will be located in the static class “Blockchain”, the entire mining process will take place here.

public static void AddBlock(string ts, string dat = "genesis", string prvHash = "")
{
  
}

What are “string dat =” genesis “and” string prvHash = “”? The fact is that in every self-respecting blockchain there must be a zero block. As a zero block, we will have a block in which the word “genesis” will be written, because I wanted to.

And written arguments with pre-assigned values ​​are optional arguments. in the “Main” method we have a line like this:

Blockchain.AddBlock();

This line is the first in the “Main” method, it is this line that creates a zero block, right at the start of the program, even if you wanted, for example, to load your wonderful blockchain from disk. What? Yes, it will be in article number two.

Programmers do not read

Why is all this necessary? Well, that’s necessary. You have no idea what agony I had to refuse from passing the “type” string to the AddBlock method and then checking which block we need to create – genesis or standard

Let’s continue our study of the method for adding a block!

int nonce = 0; //Число, которое будет менять блокчейн для соответствия сложности
string timestamp = Convert.ToString(DateTime.Now); //Время, когда блок отправили на расчет

I think there is no need to explain what it is

while (true)
{
	//Цикл расчета хэша 
}

Further in the loop:

string newHash = getHash(timestamp, dat, prvHash, nonce);

Here we pass the addition time, data, hash of the previous block and nonce value to the “getHash” method.

The “getHash” method:

static string getHash(string ts, string dat, string prvHash, int nonce)
        { 

            using (SHA256 hash = SHA256Managed.Create())
            {
                return String.Concat(hash
                    .ComputeHash(Encoding.UTF8.GetBytes(ts + dat + prvHash + nonce))
                    .Select(item => item.ToString("x2"))); ;
            }
        }

Since the getHash method is unlikely to return the desired hash on the first try, we will have to check it for the required number of zeros.

if (newHash.StartsWith(String.Concat(Enumerable.Repeat("0", difficulity))))
{
		Console.WriteLine("Ношол!!! {0}, nonce - {1}", newHash, nonce);
		blockchain.Add(new Block(timestamp, dat, newHash, nonce));
		break;
}
else //Иначе - считать со следующим значением nonce
{
		nonce++;
}

Wowowow! Take it easy, cowboy! What does all this mean?!

Explaining!

if (newHash.StartsWith(String.Concat(Enumerable.Repeat("0", difficulity))))

If at the beginning of the received hash there are zeros in the amount of difficulity, then we will do

blockchain.Add(new Block(timestamp, dat, newHash, nonce));
break;

What is difficulity? it is the number of zeros at the beginning of the block hash required to add the block to the blockchain. This is how we solve the problem of complexity in our blockchain project. By the way, the difficulty should change dynamically, but more on that later.

else //Иначе - считать со следующим значением nonce
{
		nonce++;
}

Otherwise, we add one to the nonce and start the hash calculation anew, getting a completely new value, and so on in a circle until we find the required value

The entire code of the “AddBlock” method looks like this:

public static void AddBlock(string dat = "genesis", string prvHash = "") //В эту функцию передаются все данные для создания блока 
        {
            int nonce = 0; //Число, которое будет менять блокчейн для соответствия сложности
            string timestamp = Convert.ToString(DateTime.Now);
            while (true)
            {

                string newHash = getHash(timestamp, dat, prvHash, nonce); //Вычисляем хэш, дополнительно передавая число сложности

                if (newHash.StartsWith(String.Concat(Enumerable.Repeat("0", difficulity))))
                {
                    Console.WriteLine("Ношол!!! {0}, nonce - {1}", newHash, nonce);
                    blockchain.Add(new Block(timestamp, dat, newHash, nonce));

                    break;
                }
                else //Иначе - считать со следующим значением nonce
                {
                    nonce++;
                }
            }

        }

Behind the scenes, I wrote a simple logic, right in the “Main” method, which would allow us to add a new block from the console and display all the blocks.

Test!

Genesis block is created immediately, on the thirty-third attempt.
Genesis block is created immediately, on the thirty-third attempt.

Let’s add a block!

And further!

It seems to work

What is a blockchain without a blockchain explorer? (Fortunately, it is extremely easy to write it)

int i = 0;
foreach(Block blc in Blockchain.blockchain)
{
		Console.WriteLine("{0}, {1}, {2}, {3}, {4}", i, blc.data, blc.hash, blc.timestamp, blc.nonce);
		i++;
}

This one just displays all the blocks. Demonstrating:

Everything is exactly like in a pharmacy

But what will happen if some gloomy genius decides to deceive everyone and replace the data in some block? For example, Sanya, who does not want to return a hundred square meters to the bank along with a dozen of blood? For this case, the “Verification” method was invented!

public static void Verification()
        {
            for (int i = 1; i != blockchain.Count; i++)
            {
                string verHash = getHash(blockchain[i].timestamp, blockchain[i].data, blockchain[i - 1].hash, blockchain[i].nonce);
                if(verHash == blockchain[i].hash)
                {
                    Console.WriteLine("Block {0} - OK", i);
                }
                else
                {
                    return;
                }
                
            }
            Console.WriteLine("All blocks are confirmed");
        }

Well, something like this. In this wonderful method, we take the data and time of the block, add its nonce value and the hash of the previous block to them, put it all in the “getHash” method and compare it with the hash of the current block. If everything is OK, take the next block and carry out the same manipulations. If not, stop checking. Test!

Blocks are added.  It's good
Blocks are added. It’s good
All blocks have been tested.  Fine
All blocks have been tested. Fine

Now let’s edit the third block, pretending that we are ̶m̶o̶n̶a̶r̶h̶i̶s̶t̶y̶

We managed to forge the block!  Perfectly!
We managed to forge the block! Perfectly!

And now the system administrator Valera decided to check what was happening on the server entrusted to him, and started verification:

The system administrator Valera fired unauthorized interference into the blockchain, now he can do about the same thing that all bus passengers dream of doing when they see the same hammer: break the glass and pull out the patch cords (I honestly looked for that meme, but did not find, maybe you will find )

On top of all this, it would be nice to add dynamically changing complexity, which we’ll do in article number one, and something like … a GUI? Fu, an abomination … I also want to push it all onto a server that will only store and provide the blockchain, users will have to calculate the hash, just like adult cryptocurrencies. But this is in the future.

Thank you all very much for reading my article, you can find the source code of the project at githabe, pick it for your pleasure!

I would be glad to hear criticism and suggestions, the first article, after all!

Well, of course, wait for the sequel, it is not far off! (I haven’t started yet, but that’s what everyone says …)

(Hey @ruvds would you borrow a servo for the third article?))

Similar Posts

Leave a Reply

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