与比特币相比,Zcash在挖掘算法上进行了修改。比特币使用的挖掘算法是SHA256,而Zcash使用的是Equihash。Equihash算法由Alex Biryukov和Dmitry Khovratovich共同发明,其理论基础是著名的计算科学和密码学问题3354广义生日悖论。
笔者希望用最流行的语言讨论Zcash如何使用Equihash算法实现挖掘过程。
接下来我来解释一下Zcash挖矿的一般流程。注:目前作者没有代码无法完全解释。
积木式头部
在执行挖掘算法之前,我们必须首先构建一个块头。Zcash的块头结构如下。这种结构类似于比特币的块头,区别在于随机数的位数。
图1 Z现金的块标题
n,块版本号,升级时会更改。
从上一个块中获得。
NBits,由全网计算能力决定,每生成一个新块调整难度(比特币每2016块调整一次),算法为DigiShield v3/v4。
NTime,基本上取机器当前的时间轴。
HashMerkleRoot,这个字段允许矿工自我调整。更改来自于添加或删除块中包含的交易,或更改顺序,或修改比特币基地交易的输入字段。
不,Zcash提供2 256个可能值,而比特币提供2 32个值。
总的来说,hashMerkleRoot和nNonce是可以发挥采矿自由度的地方。
Zcash块头构造的一般流程也和比特币类似:
1.选择要确认的交易。因为矿工可以从交易中获得手续费,所以一般在建块的时候会选择尽可能多的交易,但是不能超过容量限制(2M)。
2.确定比特币基地,如果区块建造成功,矿工将获得的收入(费用奖励)记录在这里。
3.构造Merkle树(聚合交易信息),生成随机数V,并写入其他参数
4.如图1所示构建块头。
把它变成一个广义的生日悖论问题。
我们通常把比特币的“挖矿”过程比作解决一个算法问题。这个算法问题的题目是通过块头的函数处理给出的。
比特币算法:对Block header的参数进行两次SHA256运算,得到一个256位的字符串,与一个期望值目标进行比较。如果这个值小于target,则挖掘成功,即sha256 (sha256(块头))target。否则,调整blockheader(修改随机数或Merkle树)并重复上述操作。
Zcash的算法:同样在块头建立后,Zcash不做不等式判断,而是以块头为输入,将挖掘问题转化为“广义生日悖论问题”。
什么是广义生日问题?
用计算机语言定义广义生日悖论:
随机生成由n个“n比特串{Xi}”组成的列表l,
图2
需要在这些字符串中找到2 k个特定的{Xij},以便:
通俗的表达:从这个列表L中找到2 k个相同的元素,也就是找到2 k个碰撞元素。
注:限于篇幅,本文只谈结论。如果读者有兴趣,可以自行查阅“生日相关内容”。
如何处理Block header得到一个“生日问题”
Zcash中有一个特殊的哈希函数Equihash生成器。Equihash生成器的功能是将输入和索引映射到长度为n位的输出。
让我 {1.N},取生成的块头和整数N和K作为输入,其中N和K的值由官方给出,并传递
函数过程,可以生成一个由n个“n位字符串{Xi}”组成的列表L。
图3
“广义生日悖论”的解决
为解决“广义生日问题”,数学上提出了许多著名的算法,瓦格纳算法就是其中之一。Zcash团队基于Wagner的算法,经过Alex Biryukov和Dmitry Khovratovich的优化,得到了一个名为“OptimisedSolve”的算法来解决上述问题。
从理论上讲,为了公平起见,用于“工作力证明”的算法一定是这个问题的最优算法,因为如果这个算法不是最优的,那么可能会有人发明并偷偷使用一个更好的算法来挖掘,在计算力相同的情况下,他的挖掘成功概率会比别人大。但是,如果我们仔细考察“OptimisedSolve”算法,我们不难发现它仍然具有优化的可能性。具体如何实现优化,本文不展开思考,作者后续文章会单独讨论这一点。
限于篇幅,不详细介绍“OptimisedSolve”算法的原理。有兴趣的话可以参考参考:《Equihash: Asymmetric Proof-of-Work Based on the Generalized Birthday Problem》。
求解过程:
以块头导出的“N位串”的列表L为“生日问题”的条件,利用改进的算法“OptimisedSolve”,可以从L中找到2 K个相同(碰撞){Xij},使得:
具体流程如图4所示。
图4
难度过滤。
到第三步,“生日问题”已经解决了。但是,并不意味着谁先构造并解决了一个“生日问题”,谁就赢得了“挖矿”。如果只把创造和解决一个“生日问题”作为胜利条件,可能会出现以下问题:
1.从概率的角度来看,生成的列表L中可能不存在2 k个完全相等的值,即碰撞次数小于2 k,这样一来,一些“矿工”构造的“生日问题”就无解了,所以当出现这种情况时,就必须重新构造“生日问题”。
2.单纯使用“OptimisedSolve”很难控制“挖掘”的难度,因为算法的运行时间服从泊松分布。
3.在内存足够的情况下,可以使用更复杂的技术迭代生成摊销成本更低的多个解,即运行这样的算法会降低单位内存的运行成本,这违背了公平“挖矿”的思想。
(Zcash希望实现公平的“开采”,即群众参与开采,而不是矿池垄断。)
所以和比特币一样,Zcash也应用了一种难度调整算法,叫做难度过滤器。
难度过滤器(表示为H)是一种算法,用于调整工作证书的时间和内存要求。得到“生日问题”的碰撞解{Xij}后,要检查难度过滤环节。只有通过考验,才能算是“挖矿成功”。具体流程如图5所示。
图5
1)难度过滤的三个判断条件
注:H(S)表示输入S通过难度过滤器H的算法过程的输出结果.
-生日算法条件:
-难度算法条件:
的结果有d个前导零。
-绑定算法条件:
的结果有n * L/(k-1)个前导零,对于所有满足条件的W和L都成立。
注意;前导零的数量指的是二进制数字串的第一位为零的位数(见图5)。
-生日算法条件表示用于判断上一过程得到的解是否是满足条件的碰撞;
-难度算法条件用于确定当前难度是否合理,并成为难度调整的依据;
-添加绑定算法可以防止有人发明算法:这种算法用足够的内存来摊销成本,使单位内存成本降低。
(这里只讨论结论,具体算法限于不讨论的篇幅)
2)判断过程
如果一个矿工构造的“生日问题”能够找到2 k个碰撞解,并且经过难度调整算法后,仍然满足三个条件,那么这个“矿工”就挖到了一个“矿”,也就是这个人成功建造了一个新的积木。
如果找不到足够多的解,或者三个条件都不能满足,那么“挖掘”就失败了。这时候矿工就需要修改随机数,从头开始新一轮的“挖矿”。
同样,这个过程也会成为Zcash挖矿难度调整的基础。每生成一个新块,难度会调整一次。
总结。
Zcash挖掘的一般流程是先构造输入条件(块头和各种参数),通过一个特定的函数将输入条件转化为“广义生日问题的一般形式”,用一个优化算法分析问题,判断得到的解的难易程度。如果算法条件和难度条件同时满足,则判定“挖矿”成功,否则调整随机数重新计算。
本文由雷英特约作者Carlos撰写,其钱包地址为15s 9 WUHTPLADSQVYAFYNIE 3k 1 wfguhdf 8。