首页 > 编程知识 正文

以太坊eth挖矿详细教程,以太坊 挖矿 算法

时间:2023-05-03 13:53:33 阅读:204543 作者:1965

https://github.com/ethereum/go-ethereumhttps://eth.wiki/en/fundamentals/mining

dataset(DAG) 生成流程

blockNumber ---> seed ---> cache ---> dataset // 挖矿核心逻辑, 根据种子计算nonce// mine is the actual proof-of-work miner that searches for a nonce starting from// seed that results in correct final block difficulty.func (ethash *Ethash) mine(block *types.Block, id int, seed uint64, abort chan struct{}, found chan *types.Block) {// Extract some data from the headervar (header = block.Header() // 区块头hash = ethash.SealHash(header).Bytes() // 获取区块的hashtarget = new(big.Int).Div(two256, header.Difficulty) // target = 2^256 / difficultynumber = header.Number.Uint64() // 区块高度dataset = ethash.dataset(number, false) // 同步生成DAG数据(如果已经生成则直接读取))// Start generating random nonces until we abort or find a good onevar (attempts = int64(0)nonce = seed // 随机数powBuffer = new(big.Int))logger := ethash.config.Log.New("miner", id)logger.Trace("Started ethash search for new nonces", "seed", seed)search:for {select {case <-abort: // 什么情况下会终止呢? 应该是接收到其他矿工// Mining terminated, update stats and abortlogger.Trace("Ethash nonce search aborted", "attempts", nonce-seed)ethash.hashrate.Mark(attempts)break searchdefault:// We don't have to update hash rate on every nonce, so update after after 2^X noncesattempts++if (attempts % (1 << 15)) == 0 {ethash.hashrate.Mark(attempts)attempts = 0}// ================== Ethash的核心逻辑 =================// Compute the PoW value of this noncedigest, result := hashimotoFull(dataset.dataset, hash, nonce)if powBuffer.SetBytes(result).Cmp(target) <= 0 { // target 由 difficulty 决定,// Correct nonce found, create a new header with itheader = types.CopyHeader(header)header.Nonce = types.EncodeNonce(nonce)header.MixDigest = common.BytesToHash(digest)// Seal and return a block (if still needed)select {case found <- block.WithSeal(header): // 通知找到了noncelogger.Trace("Ethash nonce found and reported", "attempts", nonce-seed, "nonce", nonce)case <-abort:logger.Trace("Ethash nonce found but discarded", "attempts", nonce-seed, "nonce", nonce)}break search}nonce++ // 继续尝试}}// Datasets are unmapped in a finalizer. Ensure that the dataset stays live// during sealing so it's not unmapped while being read.runtime.KeepAlive(dataset)} 验证PoW的有gjdds

// verifySeal checks whether a block satisfies the PoW difficulty requirements,// either using the usual ethash cache for it, or alternatively using a full DAG// to make remote mining fast.func (ethash *Ethash) verifySeal(chain consensus.ChainHeaderReader, header *types.Header, fulldag bool) error {// If we're running a fake PoW, accept any seal as validif ethash.config.PowMode == ModeFake || ethash.config.PowMode == ModeFullFake {time.Sleep(ethash.fakeDelay)if ethash.fakeFail == header.Number.Uint64() {return errInvalidPoW}return nil}// If we're running a shared PoW, delegate verification to itif ethash.shared != nil {return ethash.shared.verifySeal(chain, header, fulldag)}// Ensure that we have a valid difficulty for the blockif header.Difficulty.Sign() <= 0 {return errInvalidDifficulty}// Recompute the digest and PoW valuesnumber := header.Number.Uint64()var (digest []byteresult []byte)// 全节点// If fast-but-heavy PoW verification was requested, use an ethash datasetif fulldag {dataset := ethash.dataset(number, true)if dataset.generated() {digest, result = hashimotoFull(dataset.dataset, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())// Datasets are unmapped in a finalizer. Ensure that the dataset stays alive// until after the call to hashimotoFull so it's not unmapped while being used.runtime.KeepAlive(dataset)} else {// Dataset not yet generated, don't hang, use a cache insteadfulldag = false}}// 轻节点// If slow-but-light PoW verification was requested (or DAG not yet ready), use an ethash cacheif !fulldag {cache := ethash.cache(number) // 使用dag缓存代替DAG文件size := datasetSize(number)if ethash.config.PowMode == ModeTest {size = 32 * 1024}// 进行一次hashmoto运算digest, result = hashimotoLight(size, cache.cache, ethash.SealHash(header).Bytes(), header.Nonce.Uint64())// Caches are unmapped in a finalizer. Ensure that the cache stays alive// until after the call to hashimotoLight so it's not unmapped while being used.runtime.KeepAlive(cache)}// 判断mixHash是否一致// Verify the calculated values against the ones provided in the headerif !bytes.Equal(header.MixDigest[:], digest) {return errInvalidMixDigest}// result是否小于 targettarget := new(big.Int).Div(two256, header.Difficulty)if new(big.Int).SetBytes(result).Cmp(target) > 0 {return errInvalidPoW}return nil}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。