当前位置: 首页 > 科技观察

使用C#

时间:2023-03-15 18:37:05 科技观察

编写自己的区块链挖矿算法什么是加密货币挖矿?加密货币的价值体现在它的稀缺性上。如果任何人都可以任意构造一个比特币,那么比特币就一文不值了,所以比特币的区块链让参与者完成一项“工作”,根据这项工作的最终结果,比特币也被分发出去,这个过程叫做“挖矿”。这类似于金矿工花一些时间工作并获得一点金子。挖矿原理如果你在百度/谷歌上搜索比特币挖矿原理,会被告知这只是一个复杂的数学问题,但过于笼统,过于简单。挖矿引擎是如何工作的是一个重要的知识点,所以我们需要了解一些密码学知识和哈希算法相关的知识,才能知道挖矿的基本原理。Hash/Hashing引入了人类可理解的输入的单向加密,比如HelloWorld,丢给一些加密函数(所谓的复杂数学问题),加密函数的算法越复杂,越难实现反向工程。比如SHA-256的例子,这个网站(链接:http://tool.oschina.net/encrypt?type=2)可以快速计算出哈希值,我们把“HelloWorld”哈希一下,看看会不会怎么样你得到:无论你尝试多少次,你都会得到相同的哈希值。在编程中,这称为幂等性。加密算法的一个基本特点是很难通过逆向工程获得明文结果,但验证其加密结果却非常容易。比如“HelloWorld”很难通过逆向得到他原来的明文结果。比特币使用的最重要的是DoubleSHA-256,即明文经过SHA-256计算一次后,再使用SHA-256再次计算哈希值。这里我们只使用SHA-256进行加密。工作量证明比特币的工作原理是让参与者散列字母和数字的随机组合,直到计算出的散列包含前导0。比如我们计算886的哈希值,可以得到如下结果:000f21ac06aceb9cdd0575e82d0d85fc39bed0a7a1d71970ba1641666a44f530,返回3个前缀为0的哈希值,但是我们怎么知道886计算的哈希结果产生3个0呢?答案是我不需要知道。我需要知道矿工给我的哈希值有多少个前导零,我不需要复杂的算法来验证整个哈希值的有效性。比特币有点复杂。它每10分钟生成一个新块。新区块的哈希值的难度可以动态调整,就像CLR的GC一样。它可以基于当前挖矿的人数。难度是动态调整的。挖矿的人多了,难度就会增加,人少了,难度就会降低。动手开发1.项目配置首先新建一个Asp.NetCore项目,然后选择EmptyProject(空项目)类型。建立完成后,无需配置。2.数据模型这里我们创建一个具体的块数据模型,使用Struct结构。publicstructBlock{///

///区块位置///publicintIndex{get;set;}//////区块生成时间戳///publicstringTimeStamp{get;set;}//////心率值///publicintBPM{get;set;}//////块SHA-256哈希值/////summary>publicstringHash{get;set;}//////上一个区块的SHA-256哈希值///publicstringPrevHash{get;set;}//////生成下一个区块的难度///publicintDifficulty{get;set;}//////随机值///publicstringNonce{get;set;}}难度是一个整数,它定义了我们想要获取哈希值的前导0的数量。前导0越多,生成正确的哈希值就越困难。我们现在从1开始。Nonce是每次计算区块哈希值所需要的随机值。3.工作量证明我们首先添加一个新的方法来验证生成的哈希值是否包含指定数量的前导0://////检查哈希是否有效//////哈希值///难度///publicstaticboolIsHashValid(stringhashStr,intdifficulty){varbytes=Enumerable.Range(0,hashStr.Length).Where(n=>n%2==0).Select(n=>Convert.ToByte(hashStr.Substring(n,2),16)).ToArray();varbits=newBitArray(bytes);for(vari=0;i///计算区块HASH值//////区块实例///完成的区块哈希值publicstaticstringCalculateHash(Blockblock){stringcalculationStr=$"{block.Index}{block.TimeStamp}{block.BPM}{block.PrevHash}{block.Nonce}";SHA256sha256Generator=SHA256.Create();byte[]sha256HashBytes=sha256Generator.ComputeHash(Encoding.UTF8.GetBytes(ccalculationStr));StringBuildersha256StrBuilder=newStringBuilder();foreach(byte@byteinsha256HashBytes){sha256StrBuilder.Append(@byte.ToString("x2"));}returnsha256StrBuilder.ToString();}这里我们加上Nonce随机值作为基础哈希生成然后我们在生成新块的时候,顺便挖一下://////生成新块//////旧块数据///心率///新区块publicstaticBlockGenerateBlock(BlockoldBlock,intBPM){BlocknewnewBlock=newBlock(){Index=oldBlock.Index+1,TimeStamp=CalculateCurrentTimeUTC(),BPMBPM=BPM,PrevHash=oldBlock.Hash,DifficultyDifficulty=Difficulty};//挖矿...for(inti=0;;i++){newBlock.Nonce=i.ToString("x2");if(!IsHashValid(CalculateHash(newBlock),Difficulty)){Console.WriteLine($"当前结果:{CalculateHash(newBlock)},正在计算中...");Task.Delay(1);continue;}else{Console.WriteLine($"当前结果:{CalculateHash(newBlock)},计算...");newBlock.Hash=CalculateHash(newBlock);break;}}//原代码//newBlock.Hash=CalculateHash(newBlock);returnnewBlock;}效果结论其实代码并不复杂,但这几十行代码却展示了区块链挖矿的本质。后面可以参考原文实现P2P和权益证明方法和智能合约。