1. 步骤说明:

step1. createNewBlock生成一个新块
step2. 轮循nounce,计算hash以符合难度值
step2.1 先循环增加CoinBase交易的Script 的nounce
step2.2 再循环CBlockHeader中的nounce来计算hash

2. 代码:

step2 大循环

while (true) {
//step1 std::unique_ptr<CBlockTemplate> pblocktemplate(BlockAssembler(empty_mempool, Params()).CreateNewBlock(::ChainstateActive(), coinbase_script));CBlock* pblock = &pblocktemplate->block;IncrementExtraNonce(pblock, pindexPrev, nExtraNonce);int64_t nStart = GetTime();arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);uint256 hash;uint32_t nNonce = 0;while (true) {// Check if something foundif (ScanHash(pblock, nNonce, &hash)) {if (UintToArith256(hash) <= hashTarget) {// Found a solutionpblock->nNonce = nNonce;assert(hash == pblock->GetHash()); break;}}// Check for stop or if block needs to be rebuiltboost::this_thread::interruption_point();// Regtest mode doesn't require peers//if (vNodes.empty() && chainparams.MiningRequiresPeers())//break;if (nNonce >= 0xffff0000)break;if (empty_mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - nStart > 60)break;if (pindexPrev != ::ChainstateActive().m_chain.Tip())break;// Update nTime every few secondsif (UpdateTime(pblock, chainparams.GetConsensus(), pindexPrev) < 0)break; // Recreate the block if the clock has run backwards,// so that we can use the correct time.if (chainparams.GetConsensus().fPowAllowMinDifficultyBlocks)    {// Changing pblock->nTime can change work required on testnet:hashTarget.SetCompact(pblock->nBits);}}
...

step 2.1 先循环增加CoinBase交易的Script 的nounce

自2012年以来,比特币挖矿发展出一个解决区块头结构的根本性限制的方案。在比特币的早期,矿工可以通过遍历随机数(Nonce)直到生成的哈希值小于target从而挖出一个区块。随着难度的增加,矿工经常在尝试了40亿个nonce值后仍然没有出块。然而,这很容易通过更新区块的时间戳并计算经过的时间来解决。因为时间戳是区块头的一部分,它的变化可以让矿工再次遍历nonce的值。然而,当挖矿硬件的速度超过了4GH/秒,这种方法变得越来越困难,因为随机数的取值在一秒内就被用尽了。随着ASIC矿机的出现并且超过了TH/秒的hash速率后,挖矿软件为了找到有效的块,需要更多的空间来储存nonce值。时间戳可以延伸一点,但如果把它移动得太过遥远(too far into the future),会导致区块变为无效。
区块头里面需要一个新的“改变”的源头。解决方案是使用coinbase交易作为额外随机值的来源,因为coinbase脚本可以储存2-100字节的数据,矿工们开始使用这个空间作为额外随机值的空间,允许他们去探索一个大得多的区块头值的范围来找到有效的区块。这个coinbase交易包含在merkle树中,这意味着任何coinbase脚本的变化将导致Merkle根的变化。8个字节的额外随机数,加上4个字节的“标准”随机数,允许矿工每秒尝试2^96(8后面跟28个零)种可能性而无需修改时间戳。如果未来矿工尝试完了以上所有的可能性,他们还可以通过修改时间戳来解决。同样,coinbase脚本中也有更多的空间可以为将来随机数的额外空间扩展做准备。

void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce)
{// Update nExtraNoncestatic uint256 hashPrevBlock;if (hashPrevBlock != pblock->hashPrevBlock) {nExtraNonce = 0;hashPrevBlock = pblock->hashPrevBlock;}++nExtraNonce;unsigned int nHeight = pindexPrev->nHeight + 1; // Height first in coinbase required for block.version=2CMutableTransaction txCoinbase(*pblock->vtx[0]);txCoinbase.vin[0].scriptSig = (CScript() << nHeight << CScriptNum(nExtraNonce));assert(txCoinbase.vin[0].scriptSig.size() <= 100);pblock->vtx[0] = MakeTransactionRef(std::move(txCoinbase));pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
}

step2.2. 再循环CBlockHeader中的nounce来计算hash

bool static ScanHash(const CBlockHeader* pblock,
uint32_t& nNonce, uint256* phash)
{// Write the first 76 bytes of the block header to a double-SHA256 state.CHash256 hasher;CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);ss << *pblock;assert(ss.size() == 80);hasher.Write((unsigned char*)&ss[0], 76);while (true) {nNonce++;// Write the last 4 bytes of the block header //(the nonce) to a copy of// the double-SHA256 state, and compute the result.CHash256(hasher).Write((unsigned char*)&nNonce, 4).Finalize((unsigned char*)phash);// Return the nonce if the hash has at least some //zero bits, caller will check if it has enough // to reach the targetif (((uint16_t*)phash)[15] == 0)return true;// If nothing found after trying for a while, return -1if ((nNonce & 0xfff) == 0)return false;}

. 将CBlockHeader中除nNonce的值都写入buf,. 既是写入到 CDataStream

class CBlockHeader
{public:// headerint32_t nVersion;uint256 hashPrevBlock;uint256 hashMerkleRoot;uint32_t nTime;uint32_t nBits;uint32_t nNonce;

class CBlockHeader
{SERIALIZE_METHODS(CBlockHeader, obj){ READWRITE(obj.nVersion, obj.hashPrevBlock, obj.hashMerkleRoot, obj.nTime, obj.nBits, obj.nNonce);}

.实际上算hash时先写入76bytes到CHash256 中,然后循环nNonce.

76bytes = 4bytes(nVersion)+  32bytes(hashPrevBlock) +
+32bytes(hashMerkleRoot)+4bytes(nTime)+4bytes(nBits)
= 76bytes

.CHash256 计算hash值:

hash.h
/** A hasher class for Bitcoin's 256-bit hash (double SHA-256). */
class CHash256 {private:CSHA256 sha;void Finalize(unsigned char hash[OUTPUT_SIZE]) {unsigned char buf[CSHA256::OUTPUT_SIZE];// 第一次SHA-256哈希计算sha.Finalize(buf);// 对上一步的计算结果再一次进行SHA-256哈希计算sha.Reset().Write(buf, CSHA256::OUTPUT_SIZE).Finalize(hash);}CHash256& Write(const unsigned char *data, size_t len) {sha.Write(data, len);return *this;}

Bitcoin 中的挖矿算法(3) 挖矿算法代码说明相关推荐

  1. Bitcoin 中的挖矿算法(1) 难度值前奏

    1. 什么是难度值? 假设有一个集合 [1,100],我们的目标是随机生成一个数字其值小于 50.需要尝试的次数平均为 2 次. 下面提高难度,假设目标是小于 20, 那么尝试成功为 20/100 = ...

  2. 区块链中的共识机制以及共识算法

    什么是共识 共识,从字面上来看,是在某方面达成一致.打个比方,一个部门最近来了几位新同事,部门主管为了欢迎新同事的加入,以能让新同事融入到新环境,提议下班后聚个餐,对于聚餐了,大伙对此举双手赞成,毕竟 ...

  3. 必看干货:如何在 JavaScript 中实现 8 种基本图形算法

    在本文中,我将实现8 种图算法,探索 JavaScript 中图的搜索和组合问题(图遍历.最短路径和匹配). 这些问题是从<Java编程面试要素>一书中借来的.本书中的解决方案是用 Jav ...

  4. 自动驾驶中常用的四类机器学习算法

    来源:智车科技 机器学习算法已经被广泛应用于自动驾驶各种解决方案,电控单元中的传感器数据处理大大提高了机器学习的利用率,也有一些潜在的应用,比如利用不同外部和内部的传感器的数据融合(如激光雷达.雷达. ...

  5. 编程面试过程中最常见的10大算法

    编程面试过程中最常见的10大算法 编程语言:C/C++ 1. 字符串 如果IDE没有代码自动补全功能,所以你应该记住下面的这些方法. toCharArray() // 获得字符串对应的char数组 A ...

  6. ARCore中根据屏幕坐标计算射线的算法

    ARCore中根据屏幕坐标计算射线的算法 ARCore中提供了根据屏幕坐标.视口大小及view. project矩阵计算从屏幕坐标发射一条射线的方法,此方法用于3D拾取. 1 class Ray { ...

  7. 运动想象系统中的特征提取算法和分类算法

    目录 特征提取算法 分类识别算法 本教程为脑机学习者Rose发表于公众号:脑机接口社区 .QQ交流群:903290195 特征提取算法 (1)时域方法:这是比较早期的EEG信号处理方法,主要通过提取E ...

  8. vins中imu融合_基于非线性优化算法—当视觉SLAM遇到VINS会碰撞出怎样的火花?

    今天来给大家分享一个视觉SLAM中比较综合且复杂的系统-VINS.VINS旨在通过融合两个传感器测量数据获得移动机器人的位姿和特征点在空间中的位置,在现代控制理论学科中属于最优估计问题.在移动智能机器 ...

  9. DDos攻击,使用深度学习中 栈式自编码的算法

    转自:http://www.airghc.top/2016/11/10/Dection-DDos/ 最近研究了一篇论文,关于检测DDos攻击,使用了深度学习中 栈式自编码的算法,现在简要介绍一下内容 ...

最新文章

  1. 激光雷达与汽车技术路线
  2. 面试官:BigDecimal一定不会丢失精度吗?
  3. 05用线程类Thread开启线程
  4. 基于面向服务体系架构(SOA)和面向资源体系架构(ROA)的业务组件模型
  5. java icon动态变换,以编程方式自动更改ImageIcon [Java]
  6. Win7系统防火墙设置方法
  7. screw (螺丝钉) ~ 简洁好用的数据库表结构文档生成工具
  8. vue中ref 的使用
  9. 【强烈推荐】蒋勋细说《红楼梦》
  10. java 新建pdf_java-如何关闭PDF文件以重新创建它? (正在...
  11. texstudio统计字数
  12. 用计算机怎么计算字节,计算器里面的字节、字、双字、四字
  13. 【Web】CSS(No.21)Css经典案例(三)《爱宠知识》
  14. 基于电商常识图谱的知识表示与应用
  15. CRMEB 商城分销功能
  16. html qq消息弹窗提醒,能不能让QQ消息不再讨厌 QQ HD mini消息弹窗提醒的优化方案...
  17. RBP的个人信息管理与个人资料
  18. HTTPS单向认证双向认证
  19. JS鼠标移入,移出事件
  20. BIM模型轻量化的方法总结

热门文章

  1. 8.公有继承 保护继承 私有继承
  2. 怎么一键排版_做了这么久的PPT!终于找到可以自动排版的插件了
  3. html制作花样链接卡页面_使用HTML5实现刮刮卡效果
  4. Java快速生成20亿数字_关于内存:Java-打印10亿到20亿
  5. wince模拟器访问网络_Windows 10X开发模拟器上手
  6. 综合布线的12大热点技术
  7. 7000更换控制器电源步骤_恒温恒湿试验箱几大故障的检查步骤及解决方法说明...
  8. Computer:现代计算机操作系统的四大基本特性(并发/共享/虚拟/异步)
  9. TF之DCGAN:基于TF利用DCGAN测试MNIST数据集并进行生成过程全记录
  10. DL之Mask R-CNN:2018.6.26世界杯阿根廷队VS尼日利亚比赛2:1实现Mask R-CNN目标检测