在区块链的世界里,以太坊曾以其独特的“工作量证明”(Proof of Stake, PoW)机制构建了一个庞大而活跃的去中心化网络,虽然以太坊已于“合并”(The Merge)后正式转向权益证明,但理解其挖矿源代码,对于掌握区块链共识机制、加密货币底层原理以及网络安全的历史演进,依然具有不可替代的价值,本文将带领读者深入以太坊挖矿源代码的内部,探秘矿工们是如何将算力转化为以太币的。
要理解源代码,首先要理解其背后的算法,与比特币使用的SHA-256算法不同,以太坊采用的是Ethash算法,Ethash的设计初衷是为了实现“ASIC抗性”,即让普通用户也能通过消费级显卡(GPU)参与挖矿,从而避免算力被少数专用矿机垄断。
Ethash算法的核心是两个数据集:

挖矿过程简述如下: 矿工将一个区块头数据(包括前一区块哈希、时间戳、难度等)与一个随机数结合,进行哈希运算,这个哈希运算需要同时访问Cache和DAG,如果计算出的哈希值小于一个由当前网络难度决定的目标值,则挖矿成功,该区块被广播到网络,矿工获得区块奖励和交易手续费。
ethash模块以太坊的官方客户端(如Go语言实现的go-ethereum或C 实现的ethereum)都包含了完整的挖矿实现,以go-ethereum(通常称为Geth)为例,其挖矿的核心逻辑主要集中在ethash和miner两个模块中。
我们首先来看ethash模块,它负责实现Ethash算法本身,关键文件路径通常在core/ethash/目录下。
ethash.go - 算法核心与缓存管理 这个文件是Ethash算法的“心脏”,它定义了Ethash结构体,负责管理Cache和DAG的生命周期,其中最重要的函数是GetHash,它接收一个区块头和一个Nonce(随机数),执行真正的哈希计算。

// GetHash returns the hash of an header's pow block
func (ethash *Ethash) GetHash(header *types.Header, nonce uint64) (hash common.Hash) {
// ... 将区块头和Nonce组合,并调用核心计算函数 ...
} cache.go - Cache的生成与加载 Cache的生成是计算密集型的,但一旦生成就可以在多个挖矿线程间共享。cache.go中的generateCache函数负责根据当前的“epoch”(每个epoch包含30,000个区块,约5-7天)生成Cache数据,为了提高效率,它会将Cache缓存起来,避免重复计算。
dataset.go - DAG的生成与访问 DAG比Cache庞大得多,因此它不能全部加载到内存中。dataset.go定义了如何按需生成DAG的各个部分(称为“full datasets”),当需要访问DAG的某个部分时,它会根据一个索引计算出该部分的数据,这个过程被称为“计算DAG节点”。
挖矿过程中,GPU驱动程序会通过特定的接口(如OpenCL或CUDA)访问这些由Go代码提供的数据生成函数,从而在硬件层面完成海量的并行计算。
miner模块如果说ethash模块是“发动机”,那么miner模块就是“驾驶员和导航系统”,它负责整个挖矿流程的控制、任务分发和结果验证,关键文件路径在miner/目录下。

miner.go - 挖矿工作的协调者 Miner结构体是挖矿的核心控制器,它负责创建和管理工作线程(worker),接收新区块头,并将挖矿任务分发给这些线程,当挖矿成功时,它会验证结果,并通知共识层将新区块提交到链上。
worker.go - 挖矿任务的执行者 worker是真正执行循环挖矿的实体,它会从miner那里获取最新的挖矿任务(包含当前区块头),然后在一个无限循环中,不断地尝试不同的Nonce值,调用ethash.GetHash进行计算,这个过程被称为“哈希率竞赛”。
worker的一个重要功能是哈希率报告,它会定期统计尝试Nonce的速度,并向外界报告,这也就是我们常说的“算力”(Hash Rate)。
cpuminer.go - CPU挖矿的实现 以太坊虽然鼓励GPU挖矿,但也提供了CPU挖矿的实现。cpuminer.go展示了如何在CPU上执行Ethash算法,虽然效率远低于GPU,但它对于测试和开发非常有用,这个文件清晰地展示了挖矿算法是如何与硬件解耦的——无论CPU还是GPU,都遵循相同的Ethash规则。
直接编译运行官方客户端进行挖矿对普通用户并不友好,市面上出现了如PhoenixMiner、NBMiner、T-Rex等流行的第三方矿工软件,这些软件的源代码虽然不公开,但其工作原理与以太坊官方源码紧密相关:
eth_getWork和eth_submitWork)与Geth等全节点通信。
eth_getWork:矿工向节点请求一个“挖矿任务”,即一个包含区块头、难度和DAG“种子”的数据包。eth_submitWork:当矿工在自己的GPU上通过暴力尝试找到一个有效的Nonce后,它会将区块头、Nonce和结果哈希一起提交给节点,由节点验证并广播。尽管以太坊已从PoW转向PoS,但其挖矿源代码依然是一座宝贵的知识宝库,它向我们展示了: