资讯专栏INFORMATION COLUMN

以太坊源码分析:共识(3)Ethash

huashiou / 1782人阅读

摘要:在中,该随机数称为,它需要满足一个公式其中,去除区块头中生成的哈希值,见。固定值,生成的哈希值的最大取值。哈希值满足条件的概率是,矿工需要进行次的判断,才有可能找到一个符合条件的,当前以太坊难度为。

前言

Ethash实现了PoW,PoW的精妙在于通过一个随机数确定,矿工确实做了大量的工作,并且是没有办法作弊的。接下来将介绍:

Ethash的挖矿本质。

Ethash是如何挖矿的。

如何验证Ethash的随机数。

Ethash的挖矿本质

挖矿的本质是找到一个随机数,证明自己做了很多工作(计算)。在Ethash中,该随机数称为Nonce,它需要满足一个公式:

Rand(hash, nonce) ≤ MaxValue / Difficulty

其中,

hash:去除区块头中Nonce、MixDigest生成的哈希值,见HashNoNonce()

nonce:待寻找的符合条件的随机数。

MaxValue:固定值2^256,生成的哈希值的最大取值。

Difficulty:挖矿难度。

Rand():使用hash和nonce生成一个哈希值,这其中包含了很多哈希运算。

以上参数中,在得到区块头的hash之后,只有nonce是未知的。

公式的含义是,使用hash和nonce生成的哈希值必须落在合法的区间。利用下图介绍一下,Rand()函数结果取值范围是[0, MaxValue],但只有计算出的哈希值在[0, MaxValue / Difficulty]内,才是符合条件的哈希值,进而该Nonce才是符合条件的,否则只能再去寻找下一个Nonce。

以太坊可以通过调整Difficulty来调节当前挖矿的难度,Difficulty越大,挖矿的难度越大。当Difficulty越大时, MaxValue / Difficulty越小,合法的哈希值范围越小,造成挖矿难度增加。

哈希值满足条件的概率是 p = (MaxValue / Difficulty) / MaxValue = 1 / Difficulty,矿工需要进行1 / p = Difficulty次的判断,才有可能找到一个符合条件的Nonce,当前以太坊难度为3241847139727150。

如何挖矿

Ethash挖矿的主要思想是,开启多个线程去寻找符合条件的Nonce,给每个线程分配一个随机数,作为本线程的Nonce的初始值,然后每个线程判断当前的Nonce是否符合上面的公式,如果不符合,则把Nonce加1,再次进行判断,这样不定的迭代下去,直到找到一个符合条件的Nonce,或者挖矿被叫停。

接下来介绍挖矿的几个主要函数的实现,它们是:

挖矿的入口Seal函数。

挖矿函数mine函数。

挖矿需要的数据cache和dataset。

Rand()函数的实现hashimotoFull和hashimoto。

挖矿入口Seal()

Seal是引擎的挖矿入口函数,它是管理岗位,负责管理挖矿的线程。它发起多个线程执行Ethash.mine进行并行挖矿,当要更新或者停止的时候,重新启动或停止这些线程。

挖矿函数mine()

mine函数负责挖矿。Seal在启动每一个mine的时候,给它分配了一个seedmine会把它作为Nonce的初始值,然后生成本高度使用的dataset,然后把dataset, hash, nonce传递给hashimotoFull函数,这个函数可以认为是原理介绍中的Rand随机函数,他会生成哈希值Result,当Result <= Target的时候,说明哈希值落在符合条件的区间了,mine找到了符合条件的Nonce,使用Digest和nonce组成新的区块后,发送给Seal,否则验证下一个Nonce是否是符合条件的。

挖矿需要的数据cache和dataset

dataset用来生成Result,而cache用来生成dataset。至于如何使用dataset生成Resulthashimoto()中讲述,本节介绍如何生成dataset。

dataset和cache中存放的都是伪随机数,每个epoch的区块使用相同的cache和dataset,并且dataset需要暂用大量的内存。刚开始时cache是16MB,dataset是1GB,但每个epoch它们就会增大一次,它们的大小分别定义在datasetSizescacheSizes,dataset每次增长8MB,最大能达到16GB,所以挖矿的节点必须有足够大的内存。

使用cache生成dataset。使用cache的部分数据,进行哈希和异或运算,就能生成一组dataset的item,比如下图中的cache中黄色块,能生成dataset中的黄色块,最后把这些Item拼起来就生成了完整的Dataset,完成该功能的函数是generateDataset

dataset.generate()是dataset的生成函数,该函数只执行一次,先使用generateCache()生成cache,再将cache作为generateDataset()的入参生成dataset,其中需要重点关注的是generateDatasetItem(),该函数是根据部分cache,生成一组dataset item,验证PoW的nonce的时候,也需要使用该函数。

Rand()的实现hashimotoFull()和hashimoto()

hashimotoFull功能是使用dataset、hash和nonce生成Digest和Result。它创建一个获取dataset部分数据的lookup函数,该函数能够返回连续的64字节dataset中的数据,然后把lookup函数、hash和nonce传递给hashimoto

hashimoto的功能是根据hash和nonce,以及lookup函数生成DigestResult,lookup函数能够返回64字节的数据就行。它把hash和nonce合成种子,然后根据种子生成混合的数据mix,然后进入一个循环,使用mix和seed获得dataset的行号,使用lookup获取指定行的数据,然后把数据混合到mix中,混合的方式是使用哈希和异或运算,循环结束后再使用哈希和异或函数把mix压缩为64字节,把mix转为小端模式就得到了Digest,把seed和mix进行hash运算得到Result。

如何验证

PoW的验证是证明出块人确实进行了大量的哈希计算。Ethash验证区块头中的NonceMixDigest是否合法,如果验证通过,则认为出块人确实进行了大量的哈希运算。验证方式是确定区块头中的Nonce是否符合公式,并且区块头中的MixDigest是否与使用此Nonce计算出的是否相同。

验证与挖矿相比,简直是毫不费力,因为:

时间节省。验证只进行1次hashimoto运算,而挖矿进行大约Difficulty次。

空间节省。验证只需要cache,不需要dataset,也就不需要计算庞大的dataset,因此不挖矿的验证节点,不需要很高的配置。

接下来介绍验证函数VerifySeal(),以及根据cache生成DigestResulthashimotoLight()

验证函数VerifySeal

Ethash.VerifySeal实现PoW验证功能。首先先判断区块中的Difficulty是否匹配,然后生成(获取)当前区块高度的cache,把cache和nonce传递给hashimotoLight,该函数能根据cache, hash, nonce生成Digest和Result,然后校验Digest是否匹配以及Result是否符合条件。

hashimotoLight函数

hashimotoLight使用cache, hash, nonce生成DigestResult生成Digest和Result只需要部分的dataset数据,而这些部分dataset数据时可以通过cache生成,因此也就不需要完整的dataset。它把generateDatasetItem函数封装成了获取部分dataset数据的lookup函数,然后传递给hashimoto计算出Digest和Result。

FAQ

Q:每30000个块使用同一个dataset,那可以提前挖出一些合法的Nonce?
A: 不行。提前挖去Nonce,意味着还不知道区块头的hash,因此无法生成合法的Nonce。

Q:能否根据符合条件的哈希值,反推出Nonce呢?
A:不行。因为哈希运算具有不可逆性,不能根据摘要反推出明文,同理根据哈希值也无法推出Nonce。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/24396.html

相关文章

  • 以太源码分析共识(2)引擎

    摘要:前言是以太坊封定义的一个接口,它的功能可以分为类验证区块类,主要用在将区块加入到区块链前,对区块进行共识验证。辅助类生成以太坊共识相关的。被使用,是以太坊状态管理服务,当报告数据的时候,需要获取区块的信息。 前言 engine是以太坊封定义的一个接口,它的功能可以分为3类: 验证区块类,主要用在将区块加入到区块链前,对区块进行共识验证。 产生区块类,主要用在挖矿时。 辅助类。 接下...

    YuboonaZhang 评论0 收藏0
  • 以太源码分析Ethash共识算法

    摘要:当前和一样,采用基于工作量证明的共识算法来产生新的区块。源码解析生成通过方法生成,首先是生成,再从生成挖矿在挖矿与共识中提到了,共识算法通过实现接口,来实现挖矿算法也不例外。 Ethereum当前和Bitcoin一样,采用基于工作量证明(Proof of Work,PoW)的共识算法来产生新的区块。与Bitcoin不同的是,Ethereum采用的共识算法可以抵御ASIC矿机对挖矿工作的...

    EddieChan 评论0 收藏0
  • 以太POA共识机制Clique源码分析

    摘要:以太坊中除了基于运算能力的外,还有基于权利证明的共识机制,是以太坊的共识算法的实现,这里主要对的相关源码做一个解读分析。检查包头中包含的签名是否满足共识协议 以太坊中除了基于运算能力的POW(Ethash)外,还有基于权利证明的POA共识机制,Clique是以太坊的POA共识算法的实现,这里主要对POA的Clique相关源码做一个解读分析。 Clique的初始化在 Ethereum.S...

    Stardustsky 评论0 收藏0
  • 以太源码分析—挖矿与共识

    摘要:下面来看看具体是怎么实现接口的可以看到,启动了多个线程调用函数,当有线程挖到时,会通过传入的通道传出结果。可以看到在主要循环中,不断递增的值,调用函数计算上面公式中的左边,而则是公式的右边。 前言 挖矿(mine)是指矿工节点互相竞争生成新区块以写入整个区块链获得奖励的过程.共识(consensus)是指区块链各个节点对下一个区块的内容形成一致的过程在以太坊中, miner包向外提供挖...

    walterrwu 评论0 收藏0
  • 以太创世区块与链配置载入分析

    摘要:本文首发于深入浅出区块链社区原文链接以太坊创世区块与链配置载入分析,原文已更新,请读者前往原文阅读。以太坊允许通过创世配置文件来初始化创世区块,也可使用选择使用内置的多个网络环境的创世配置。再准备两个以太坊账户,以便在创世时存入资产。 本文首发于深入浅出区块链社区原文链接:以太坊创世区块与链配置载入分析,原文已更新,请读者前往原文阅读。 创世区块作为第零个区块,其他区块直接或间接引用到...

    姘搁『 评论0 收藏0

发表评论

0条评论

huashiou

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<