PoW的概念最早来自于比特币网络,和人们通常说的“挖矿”一词紧紧联系在一起。我们知道在现实生活中,黄金或其他稀有贵金属需要通过辛苦的挖矿劳动获得。在以太坊区块链网络中,数字货币一样是稀有资源,也是通过挖矿获得。
然而,与黄金和贵金属挖矿不同的是,数字货币的挖矿同时能起到构建、验证、请求和传播区块的目的,表达为:以太币挖矿 = 保障网络安全 = 计算验证以太坊通过PoW选择总难度最大的区块为有效区块。矿工节点负责生产区块,其他节点负责验证区块。任何加入以太坊网络的节点都可以成为矿工。矿工通过挖矿获得的收入大致与相对全网的归一化算力(hashrate)成正比。以太坊按照区块的数据形式来维护交易列表和最近状态。区块号和难度系数存储在区块头中。以太坊中的PoW算法也称为Ethash算法(即Dagger-Hashimoto算法的改进版)。
矿工节点通过快速计算试图找到一个合适的Nonce值,使得通过运算得到的结果低于特定的难度门限。PoW的要领在于除了枚举之外很难找到更好的方法来获得合适的Nonce值,而验证这个值是否满足要求是很容易的。因为hash函数的输出数字满足均匀分布,所以我们可以保证在平均意义上,得到合适Nonce值的时间与设定的难度值有关。
因此,网络可以通过调整难度系数来控制出块时间。难度系数是动态调整的,以保证全网的平均出块时间维持在15秒左右。这样的心跳周期保证了系统状态的正常同步,同时也排除了出现分叉或篡改历史数据的可能。除非攻击者能拥有全网算力的一半以上(即51%攻击)。Ethash算法的瓶颈在于内存读写性能,即矿工无法通过使用更快的硬件如ASIC、FPGA来提高挖矿。
以太坊网络节点可以使用CPU挖矿来获得以太币奖励。这种挖矿方式已经很难赚钱,因为GPU挖矿大致比CPU挖矿的效率高两个量级。但是,在Morden测试网络或者私有链上仍然可以通过CPU挖矿来获得以太币奖励,用于测试合约和交易。当用户使用命令行工具geth来接入以太坊网络时,并不会默认打开挖矿。通常需要使用—mine选项来开启CPU挖矿模式,使用—minerthreads参数来设置并行挖矿的线程数目。挖矿算法需要消耗大量内存,使用GPU挖矿时,每个GPU生成DAG时正常需要1~2G的RAM内存空间。如果程序返回“Error GPU mining. GPU memoryfragmentation? ”报错,则表示硬件无法获得足够的内存。GPU挖矿是基于OpenCL实现的,所以AMD的GPU会比同样规格的NVIDIA的GPU工作更快。ASIC和FPGA相对效率更低,因此不建议使用。
综上所述,以太坊使用的PoW算法变更了Dagger-Hashimoto算法的原有特性,设计思路遵循如下几点:通过扫描区块头的数据来计算种子值。根据种子输入能够得到16M字节尺寸的伪随机缓存。轻客户端会存储这段缓存。根据缓存能够得到1G字节尺寸的数据集,数据集中的每个元素依赖于缓存中的一小部分输入。全节点和矿工需要保存数据集。数据集所占空间随着时间推移线性增长。挖矿的过程就是从数据集中抽取随机切片并计算hash值的过程。区块验证则只需要很小的内存,通过缓存中的数据来生成特定的数据集切片。因此,验证节点仅需要存储缓存。