使用c#编写自己的区块链挖矿算法

  

  

一个加密货币的价值体现在它的稀缺性上,如果任何人都可以任意构造一个比特币,那么比特币就毫无价值,所以比特币的区块链会让参与者完成一项“工作”,根据这个工作的最终结果还分发比特币,这个过程就被叫做“挖矿”。这就类似于一个黄金矿工花一些时间来工作,然后获得一点黄金。

  

  

如果你百度/谷歌搜索比特币挖矿的原理的话,都会给你说是计算一个复杂的数学问题而已,但是这么说的话太笼统而且也太简单。采矿引擎如何工作这是一个重要的知识点,所以我们需要了解一些密码学知识和哈希算法相关的知识,才能知道挖矿的基本原理。

  

  

单向加密人类能够理解的输入,例如Hello World,并将其扔到某个加密函数(即所谓的复杂的数学问题),加密函数的算法越复杂,逆向工程就越困难。

  

例如一个SHA - 256的例子,这个网站(链接:http://tool.oschina.net/encrypt& # 63;类型=2)可以很快的计算散列值,让我们来散列“Hello World”看看会得到什么结果:

  

使用c#编写自己的区块链挖矿算法

  

不管你试验几次都会得到一样的散列值,在编程中这种被称之为幂等性。

  

加密算法的一个基本特性就是,它们很难通过逆向工程来得到明文结果,但是十分容易验证他们的加密结果,例如这里的“Hello World”很难通过逆向工程得到他的原明文结果,比特币采用的是双sha - 256也就是将明文通过sha - 256计算过一次之后,再拿sha - 256针对散列值再次进行计算,在这里我们只使用sha - 256来进行加密。

  

  

比特币通过让参与者散列随机的字母与数字的组合,直到计算出来的散列包含前导0。

  

例如我们计算886的散列值可以得到如下结果:

  000 f21ac06aceb9cdd0575e82d0d85fc39bed0a7a1d71970ba1641666a44f530

  

它返回了3个0作为前缀的散列值,但是我们怎么知道886年计算出来的散列结果产生了3个0呢?

  

答案是我并不需要知道。我需要知道矿工给我的散列值前导有几个零就好了,并不需要复杂的算法来验证整个散列值的有效性。

  

比特币则稍微复杂一点,它每隔10分钟生成一个新的区块,新区块的散列值的难度它可以动态调整,就类似于CLR的GC一样,它可以根据目前挖矿的人数来进行难度动态调整,如果挖矿的人多的话,则调高难度,少则调低。

  

  

<强> 1。项目配置

  

首先新建一个Asp。网络核心项目,然后选择空项目(空项目)类型,建立完成后无需进行任何配置。

  

<强> 2。数据模型

  

这里我们来创建一个具体的区块数据模型,使用的是结构结构体。

        公共结构体块   {///& lt; summary>///区块位置///& lt;/summary>   公共int指数{得到;设置;}///& lt; summary>///区块生成时间戳///& lt;/summary>   公共时间戳字符串{;设置;}///& lt; summary>///心率数的值///& lt;/summary>   公共int BPM{得到;设置;}///& lt; summary>///区块sha - 256散列值///& lt;/summary>   公共字符串哈希{得到;设置;}///& lt; summary>///前一个区块sha - 256散列值///& lt;/summary>   公共字符串PrevHash{得到;设置;}///& lt; summary>///下一个区块生成难度///& lt;/summary>   公共int{困难;设置;}///& lt; summary>///随机值///& lt;/summary>   公共字符串Nonce {;设置;}   }      

困难是一个整形,他定义了我们希望得到哈希前导0的数量,前导0越多,生成正确的散列值就越困难,我们现在从1开始。

  

Nonce则是每次计算块散列值所需要的随机值。

  

<强> 3。工作证明

  

我们首先添加一个新的方法来验证生成的散列值是否包含指定数量的前导0:

     ///& lt; summary>///校验哈希是否有效///& lt;/summary>///& lt;参数name=" hashStr祝辞散列值& lt;/param>///& lt;参数name="困难"祝辞难度& lt;/param>///& lt; returns> & lt;/returns>   公共静态bool IsHashValid(字符串hashStr, int困难)   {   var字节=可点数的。范围(0,hashStr.Length)   其中(n=比;n % 2==0)   .Select (n=比;Convert.ToByte (hashStr。Substring (n, 2)、16))   .ToArray ();   var=new BitArray碎片(字节);   (var=0;我& lt;困难;我+ +)   {   如果(位[我])返回false;   }   返回true;   }      

然后我们更改了之前区块散列的生成方法:

使用c#编写自己的区块链挖矿算法