主页 > imtoken钱包网址 > 以太坊共识 DAG 笔记

以太坊共识 DAG 笔记

imtoken钱包网址 2023-01-18 13:49:45

DAG分析 1. 什么是DAG? 2.例子

在这里插入图片描述

上图左右两张图都是DAG。 但它们不一样。 左图是IOTA的“Tangle”。 用户每发起一笔交易,都需要对之前的两笔交易进行验证。 后面的图片是普通的DAG,没有验证次数限制。

三:DAG与区块链的优缺点 发展方向: 4.以太坊中的DAG挖矿算法—ethash 1.挖矿原理 2.go-ethereum源码 1.调用miner.go中的New方法生成矿机。

/**
   利用区块链创建时候的一些配置,以及共识引擎consensus.Engine等参数先是生成一个矿工,然后
   让矿工注册一个cpu运算引擎,同时通过 update 来监听同步状态并更新挖矿状态
**/
func New(eth Backend, config *params.ChainConfig, mux *event.TypeMux, engine consensus.Engine) *Miner {
    miner := &Miner{
        eth:      eth,
        mux:      mux,
        engine:   engine,
        worker:   newWorker(config, engine, common.Address{}, eth, mux),
        canStart: 1,
    }
    miner.Register(NewCpuAgent(eth.BlockChain(), engine))
    go miner.update()
 
    return miner
}

case downloader.StartEvent:
            atomic.StoreInt32(&self.canStart, 0)
            if self.Mining() {
                self.Stop()
                atomic.StoreInt32(&self.shouldStart, 1)
                log.Info("Mining aborted due to sync")
            }

可以看出,如果当前正在同步区块,则需要停止挖矿操作,直到同步操作结束(同步成功或失败)。 如果挖矿操作已经执行以太坊挖矿原理,则挖矿操作将继续。

#####2。 在Register方法中调用worker的Agent接口中的Start方法,在agent.go中实现。 在agent.go中调用mine进行挖矿操作。

func (self *CpuAgent) mine(work *Work, stop <-chan struct{}) {
       //调用Seal接口,在sealer.go里实现,进行Ethash算法的实现
    if result, err := self.engine.Seal(self.chain, work.Block, stop); result != nil {
        log.Info("Successfully sealed new block", "number", result.Number(), "hash", result.Hash())
        self.returnCh <- &Result{work, result}
    } else {
        if err != nil {
            log.Warn("Block sealing failed", "err", err)
        }
        self.returnCh <- nil
    }
}

3、在sealer.go的矿机中挖矿,对比结果,判断是否挖矿成功。

 func (ethash *Ethash) Seal(chain consensus.ChainReader, block types.Block, stop <-chan struct{}) (types.Block, error) { }

  var (
            
        //target的计算方法是 256/difficulty 的一个int值
    target = new(big.Int).Div(maxUint256, header.Difficulty)
 
            //当前是第几块
    number  = header.Number.Uint64()
            //生成一个dataset,也就是我们说的搜索或是匹配空间
    dataset = ethash.dataset(number)
)

四、具体流程

1)通过number number获取当前区块的epoch(每30000个区块为一个epoch,时间窗口为125小时,约5.2天),以epoch为索引获取当前是否有数据集记忆

2)如果不是,首先检查内存中的total dataset是否大于dagsinmemory(默认为1),如果大于则需要删除最早的dataset

3)同时检查是否有预先生成的数据集缓存以太坊挖矿原理,数据是否存在于磁盘空间中。 如果有这个数据,并且和当前区块在同一个epoch,就用这个预先生成的数据集作为当前数据集。

3)同时检查是否有预先生成的数据集缓存,数据是否存在于磁盘空间中。 如果有这个数据,并且和当前区块在同一个epoch,就用这个预先生成的数据集作为当前数据集。

4)如果以上不满足,重新生成一个数据集。 如果在这个过程中,发现原来的预生成数据集是空的,或者它的epoch和当前区块的epoch不一致,就需要使用新生成的数据集作为预生成数据集,赋值

5)生成dataset后,使用keccak512算法,通过dataset生成1GB数据集DAG

6)接下来就是用hashimoto算法(基于Keccak256算法)不停循环计算出一个result值,然后和target比较。小于target则成功,否则继续

#####5.桥本函数

六、验证方式

我们的核心计算对应于 nonce 的加密值。 摘要方法桥本算法返回摘要和结果。

这一行的表达很简单。 主要意思是比较结果值和目标值。 如果小于等于0,则成功。

new(big.Int).SetBytes(result).Cmp(target) <= 0

target = new(big.Int).Div(maxUint256, header.Difficulty)

可以看出,target的定义是根据区块头中的难度值来计算的。 因此,这验证了我们在概念部分首先提到的,我们可以通过调整Difficulty值来控制pow计算的难度,生成正确nonce的难度,达到pow工作量可控的目的。