[区块链从原理到实现]- 以太坊挖矿原理及实现

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gx_1983/article/details/82659455

[区块链从原理到实现]-索引

[区块链从原理到实现]- 以太坊挖矿原理及实现

本文章主要介绍了以太坊区块链的挖矿流程.
分为以下几个部分说明:

  • 什么是挖矿
  • 静态代码分析
  • 挖矿流程分析

什么是挖矿

以太坊的挖矿类似于现实生活中在金矿的矿山上挖矿.
现实生活中在矿山中挖金矿有几个角色可以与以太坊区块链的挖矿过程很好的对应.

  • 以太坊区块链 : 链就是一个金矿,里面有多少金子是由以太坊的源代码来定义的.
  • 区块 : 区块对应现实中从金矿挖出来的金子(每挖出一个区块,挖出区块的节点都会有一定的奖励,正是因为这个奖励才促使大家都参与到挖矿的行为中来.)
  • 矿工 : 参与以太坊网络挖矿的节点称为矿工.矿工通过执行"挖矿"这一动作使得以太坊持续不断的产生新的区块,每个区块包含在一段时间内的交易.区块不断的被挖掘并被所有节点确认,从而保证了以太坊网络的交易被确认并上链.
  • 挖矿 : 所谓挖矿即节点利用自己的算力,通过计算产生区块的过程.目前的以太坊公网采用的共识机制为POW(Proof Of Work)工作量证明机制,节点使用这个机制产生区块的过程叫做"挖矿"非常形象,因为在PoW的过程中,节点并没有与其他节点协商,而只是单纯的凭借自己的算力计算出符合标准的数值,一旦算出的结果符合标准那么就说这个节点挖出了一个块.
  • 共识算法 : 节点间达成协商一致的一种分布式算法,目前除了PoW还有其他共识机制,例如:PBFT/IBFT(拜占庭容错算法),PoS(Proof Of Stack)权益证明,DPOS(Delegated Proof Of Stack)股份授权证明,PoA(Proof of Authority)权威证明,POB(Proof Of Burn)等等各种共识算法,这些共识算法的侧重点不同,都是为了解决各自领域的问题,通过一定的手段达成节点间的共识.后续文章会对目前流行的共识算法做说明总结.

静态代码分析

挖矿相关的代码都在miner文件夹下.
这里写图片描述

  • agent.go: agent代码实现,agent对象负责与共识模块交互.

  • miner.go: miner对象控制挖矿过程的开始,结束及参数转换等.

  • remote_agent.go: 没有深入分析,remote_agent继承了agent.

  • unconfirmed.go: unconfirmed模块负责存储已经上链但是未经过后续6个块确认的块,从代码中来看,unconfirmed模块影响挖矿即出块过程,其代码逻辑只负责日志输出,用于提醒用户.

  • worker.go: worker对象也是挖矿过程中的重要对象,其负责与agent交互,负责给agent提供生成块需要的原始数据,然后接收agent返回来的已经经过共识,可以上链的块.
    共识协议相关代码如下,后续专门文章分析各种共识算法的实现:
    这里写图片描述

  • clique: ethereum的POA实现.

  • ethash: ethereum的POW实现.

  • istanbul: 此为wanchain链新添加的IBFT(PBFT)共识实现,在ethereum不包括此文件夹.

  • misc: 未关注.

  • consensus.go: 共识接口定义.

  • errors.go: 共识相关error定义.

  • protocol.go: protocol接口实现.

挖矿流程分析

以太坊挖矿整体流程如下图所示:
这里写图片描述
下面按照流程图说明以太坊挖矿的过程:

  • 运行以太坊客户端程序geth(或者运行wanchain的gwan),启动节点.
  • 调用eth.New()函数创建ethereum对象.
  • eth的New()函数调用函数CreateConsensusEngine()创建共识算法引擎.
    • 如何确定需要使用哪种共识算法引擎? (后续确认)
  • 共识算法引擎创建完成之后eth.New()接着调用函数miner.New()创建miner对象,miner对象负责控制挖矿的过程,与其他模块交互,控制挖矿过程的启动及停止等.
  • 在miner.New()函数中调用newWorker()函数创建了一个worker对象,然后调用NewCpuAgent()函数创建了一个cpuAgent对象.其中worker负责给cpuAgent发送出块需要的数据,cpuAgent才是实际与共识引擎交互负责出块的对象,在其内部调用共识引擎的各种接口来出块,最终cpuAgent把产生的新块返回给worker对象,然后worker对象发送新块上链的通知并同时向它的peer广播新块消息.
  • worker对象创建之后会创建一个协程go worker.wait(),此协程负责接收cpuAgent返回给worker的新块,进行新块的处理同时调用commitNewWork()函数发送新的出块请求给cpuAgent对象.
  • cpuAgent对象创建之后会创建一个协程go self.update(),此协程负责接收从worker对象发送过来的出块请求,cpuAgent()对象收到新的出块请求之后创建一个协程go self.mine()用于对新区块进行挖掘(对每个新区块的出块请求都会新创建一个协程来执行出块的动作.)
  • worker对象有一个recv通道,用于从cpuAgent接收挖矿的返回结果;cpuAgent的通道workCh用于从worker对象接收发送过来的用于出块的原始数据,cpuAgent的returnCh指针在cpuAgent创建之后会被赋值为worker对象的recv通道,这样worker和cpuAgent的交互通道就关联了起来:worker把原始数据发送给cpuAgent的workCh通道,cpuAgent把出块结果放到worker的recv通道返回给worker对象.
  • 图示中蓝色的箭头表示代码的静态流程,即个对象的创建逻辑.
  • 图示中黄色的箭头表示消息流向,黄色和蓝色箭头结合起来后挖矿流程就形成了一个闭环.
  • 紫色箭头关联的逻辑为挖矿的开始流程,执行miner.start()开始挖矿, cpuAgent在miner.start()之后才开始监听workCh通道,等待接收组装区块的原始数据的.

总结

上述部分分析了以太坊挖矿的原理及实现. 在本部分的挖矿流程示意图中共识机制部分只涉及到了共识的接口,并没有对各种共识内部进行深入分析.在后续章节会多各种共识机制的原理及流程进行详细分析.

---- END ----

猜你喜欢

转载自blog.csdn.net/gx_1983/article/details/82659455