加密货币使用的哈希算法的演进历史,大致是:从比特币(Bitcoin)的SHA256,到莱特币(Litecoin)的Scrypt,然后是以太坊(Ethereum)的Ethash,达世币(Dash)的X11,以及后来的X13,X15,X17。
X16R是这个演进过程中的下一代算法。改变算法的目的是为了减小专用硬件对挖矿生态的影响。
比特币最初的设计是希望全世界各地的普通电脑进行挖矿,随着比特币价值的增加,专为并行化处理设计的硬件开始显示出优势。
于是,挖矿进入GPU时代。
当挖矿的经济效益进一步提升后,使用可编程硬件在经济上变得可行,例如比CPU和GPU更有优势的现场可编程门阵列(FPGA),再下一步,便是制造专门为挖矿定制的芯片。
专用集成电路(ASIC)成为挖矿的主宰,使用其他技术的挖矿设备将变得不切合实际。
最终,随着设备的不断升级挖矿进入了更快和能效比更高的ASIC时代。
不幸的是,这种转变带来了挖矿中心化的问题。
虽然任何人都可以订购这些ASIC设备,但是地理位置上更靠近生产商的人可以享受到物流时间短的好处。电力是挖矿成本的重要部分,能够获得便宜的电力是非常重要的。
中国拥有大量ASIC矿机生产商,并且在某些省份可以获得廉价电力,这必将导致挖矿集中在这里。
对抗
减少ASIC矿机影响的一个解决方案是使用内存密集型的哈希算法。莱特币的Scrypt和ZCash使用的Equihash就是采用了这种思路。虽然有矿工使用ASIC矿机运算Scrypt,但相对于SHA256算法下ASIC对GPU的优势,这种优势并不大。目前还没有针对Equihash的ASIC矿机出现。
另一种方法是将多种哈希算法串联起来,一个哈希算法的输出将作为下一个哈希算法的输入。达世币(最早被称为DarkCoin),采用了这种思路,设计了X11算法。X11把11种哈希算法串联起来使用,来加大ASIC开发的难度。
这种方法一度阻止了ASIC的出现,但是,目前也有了多家厂商在生产X11算法的矿机。
与X11类似,一些其他币种使用了X13,X15,甚至是X17,X17串联了17种哈希算法。
固定顺序串联哈希算法的做法,依然可以设计出ASIC。串联更多的哈希算法,可以增加开发ASIC的难度。像X11一样,X13、X15、X17都是使用固定的哈希算法串联顺序,只是改变了哈希算法的数量和种类。
这类算法很可能越来越快的被突破,ASIC制造商只需要逐个实现每一种哈希算法,并根据需要组合它们。
曙光
X16R算法使用不断打乱哈希算法串联顺序的方法来解决这个问题。
X16R选用的哈希算法是X15中已经经过验证的15种,外加SHA512。但是16种哈希算法的串联顺序,是基于前一个区块的哈希值动态改变的。
这种动态改变顺序的做法,并不能使设计ASIC成为不可能。但是,这需要ASIC对额外的输入做更多适配。这些操作对CPU和GPU来说,可以轻松完成。动态改变顺序的做法也可以防止ASIC生产商通过简单的拓展X11和X15矿机的方法,生产出X16R矿机。
X16R的16种哈希算法的串联次序,由前一区块哈希值的最后8字节(十六进制表示的16位)决定。
涉及的哈希算法如下:
0=blake
1=bmw
2=groestl
3=jh
4=keccak
5=skein
6=luffa
7=cubehash
8=shavite
9=simd
A=echo
B=hamsi
C=fugue
D=shabal
E=whirlpool
F=sha512
例如:
前一区块的哈希值为:
0000000000000000007e8a29f052ac2870045ae3970270f97da00919b8e86287
最后8字节是:0x7da00919b8e86287
每一个十六进制位决定一种哈希算法,下一区块X16R的哈希算法排序为:
cubehash(7)
shabal(d)
echo(a)
blake(0)
blake(0)
simd(9)
bmw(1)
simd(9)
hamsi(b)
shavite(8)
whirlpool(e)
shavite(8)
luffa(6)
groestl(2)
shavite(8)
cubehash(7)
一些哈希算法比其他哈希算法需要更长的计算时间,如上表所示。
计算时间上的差异,将在挖掘区块时,通过算法的随机搭配而被平均。
启示
X16R算法的测试平台是渡鸦币(Ravencoin),渡鸦币在比特币发布九周年纪念日,即2018年1月3日启动。渡鸦币是X16R的参考实现,定义了哈希算法的数量、种类、顺序、以及前一区块中,用于决定哈希算法顺序所使用的字节。
在比特币的基础上,渡鸦币修改了发行规则、区块时间和PoW算法。
X16R的思路可以拓展到包括Scrypt、Equihash和其他ASIC抵抗算法,以确保允许任何人使用现成的空闲计算机挖矿。对每种加密货币来说,哈希算法的顺序、种类、数量都可以非常容易的改变,以阻止ASIC厂商像X11算法一样,设计出可以挖掘一类加密货币的矿机。
思考
为什么X16R这种动态改变哈希算法顺序的做法可以抵抗ASIC呢?
我们前面提到,X11这种靠堆算法数量的做法最终被ASIC攻克,因为只要币价足够高,厂商就会投入人力物力去把11种哈希算法逐个用ASIC实现,最后再组合起来。
运行过程中,每个哈希算法模块,可以流水线运行。每个时刻,都可以做到100%的芯片利用率,就像下面这样。
对11种哈希算法的X11来说,ASIC可以提供11种哈希函数的电路,每时每刻,这11个哈希函数的电路都在工作,同时处理11个任务的不同部分。
而X16R在每一个区块进行PoW计算时,增加了很多挑战:
每种哈希算法被调用的次数不确定
哈希函数的排序不确定
对于预先设计好的ASIC矿机来说,一旦芯片流片,包含了多少种哈希函数,每种哈希函数有多少计算资源就是确定的。
对X16R来说,由于前一区块Hash值的后8字节,可以认为是完全随机的,我们可以计算出对每个区块,涉及哈希函数种类数和概率如下:
涉及哈希函数种类 概率 1 8.673617379884035e-19 2 4.263126310299903e-13 3 1.3008292880367645e-09 4 4.0680219586149147e-07 5 3.114800294252984e-05 6 0.0008548354163772504 7 0.010257933523243057 8 0.060249156768226245 9 0.1847133772998888 10 0.30522511853905976 11 0.273508450268678 12 0.13029987021900835 13 0.03130843802212624 14 0.0034140224047796153 15 0.00013610720550616406 16 1.1342267125513672e-06
加权平均下,每个区块运算时,平均涉及10.3种哈希函数,假设每种哈希函数的硬件实现需要的芯片面积相同,则芯片利用率约为64.4%,这是平均利用率的上限,也就是说,无论何时,芯片上都会有36%左右的电路是被浪费掉的。
同时,由于每种哈希函数在运算中被使用的次数不确定,顺序也不确定,想设计出高效的流水线就更加困难。
如果想更好的增加流水线的并行度,就要有更多冗余的运算单元,芯片利用率更低。
如果想提高芯片利用率,势必就会加剧资源争用,降低并行度,影响性能。
这一切只是增加了难度,当币价足够高时,ASIC还是可以获得一定的优势。
然而,只要相对于GPU,这种优势不是十分巨大,对减轻算力中心化的趋势,还是有帮助的。
集成电路其实是由晶体管构成若干门电路,门电路通过组合实现各种功能。
有没有人想到,如果有一种器件,可以根据需要,动态的组合这些门电路,来实现各种功能,不就可以每时每刻都充分利用整个芯片了吗?
FPGA就属于这种器件。
X16R虽然可以抵抗ASIC,但是对FPGA几乎无能为力。每当上一个区块产生,下一个区块使用的哈希函数种类,每种哈希函数调用的次数,哈希函数调用的次序也就确定了。
FPGA可以快速重新编程,为每种哈希函数分配好使用的门数量,便可以充分利用芯片资源,进行运算。