转载:比特币源码分析(二十二) - 挖矿和共识

https://blog.csdn.net/yzpbright/article/details/81231351

CalculateNextWorkRequired()方法:

unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
if (params.fPowNoRetargeting)
return pindexLast->nBits; // Limit adjustment step
// 计算生成最近的2016个区块实际花费了多少时间
int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
//这里需要限制调整的步长,即把实际花费的时间限制在0.5周和8周之间
if (nActualTimespan < params.nPowTargetTimespan/)//params.nPowTargetTimespan是2周,即20160分钟
nActualTimespan = params.nPowTargetTimespan/;
if (nActualTimespan > params.nPowTargetTimespan*)
nActualTimespan = params.nPowTargetTimespan*; // Retarget
const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
arith_uint256 bnNew;
bnNew.SetCompact(pindexLast->nBits);//旧的难度目标值
bnNew *= nActualTimespan;
bnNew /= params.nPowTargetTimespan; if (bnNew > bnPowLimit)
bnNew = bnPowLimit; return bnNew.GetCompact();
}

计算公式:新的难度目标值 = 旧的难度目标值 * 生成最近2016个区块所花费的实际时间 / 系统期望生成2016个区块的时间 
其中代码中:nBits 即 旧的难度目标值,nActualTimespa 即 生成最近2016个区块所花费的实际时间 , 
params.nPowTargetTimespan 即 系统期望生成2016个区块的时间 。

2.1.3.3难度目标的表示 
上面讲了难度目标的计算方法,这里再进一步讲一下难度目标的表示方法,难度目标值用nBits表示,nBits是一个无符号的32位整数,定义在src/chain.h的CBlockIndex类中:

    uint32_t nBits;

这个无符号整数的最高位的1个字节代表指数(exponent),低位的3个字节代表系数(coefficient),这个记法将工作量证明的target表示为系数/指数(coefficient/exponent)的格式。 
计算难度目标target的公式为:target = coefficient * 2^(8 * (exponent – 3)) 
例如在区块277,316中,nBits的值为 0x1903a30c,在这个区块里,0x19为指数,而 0x03a30c为系数,计算难度值:

target = 0x03a30c * 2^(0x08 * (0x19 - 0x03))
=> target = 0x03a30c * 2^(0x08 * 0x16)
=> target = 0x03a30c * 2^0xB0

按十进制计算为:

=> target = 238,348 * 2^176
=> target = 22,829,202,948,393,929,850,749,706,076,701,368,331,072,452,018,388,575,715,328

转化回十六进制后为:

=> target = 0x0000000000000003A30C00000000000000000000000000000000000000000000

上述过程就是由无符号的32位整数nBits转为难度值的详细步骤。

由无符号的32位整数nBits转为难度值的函数 
(如:0x1903a30c 转为 0x0000000000000003A30C00000000000000000000000000000000000000000000 ):

// This implementation directly uses shifts instead of going
// through an intermediate MPI representation.
arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
{
int nSize = nCompact >> 24;
uint32_t nWord = nCompact & 0x007fffff;
if (nSize <= 3) {
nWord >>= 8 * (3 - nSize);
*this = nWord;
} else {
*this = nWord;
*this <<= 8 * (nSize - 3);
}
if (pfNegative)
*pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
if (pfOverflow)
*pfOverflow = nWord != 0 && ((nSize > 34) ||
(nWord > 0xff && nSize > 33) ||
(nWord > 0xffff && nSize > 32));
return *this;
}

由难度值转为无符号的32位整数nBits的函数 
(如:0x0000000000000003A30C00000000000000000000000000000000000000000000 转为 0x1903a30c ):

uint32_t arith_uint256::GetCompact(bool fNegative) const
{
int nSize = (bits() + 7) / 8;
uint32_t nCompact = 0;
if (nSize <= 3) {
nCompact = GetLow64() << 8 * (3 - nSize);
} else {
arith_uint256 bn = *this >> 8 * (nSize - 3);
nCompact = bn.GetLow64();
}
// The 0x00800000 bit denotes the sign.
// Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
if (nCompact & 0x00800000) {
nCompact >>= 8;
nSize++;
}
assert((nCompact & ~0x007fffff) == 0);
assert(nSize < 256);
nCompact |= nSize << 24;
nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
return nCompact;
}

这两个方法定义在src/arith_uint256.h的 arith_uint256类中。

比特币nBits计算的更多相关文章

  1. 为什么用GPU挖比特币?

    http://www.leiphone.com/gpubitcoin.html 呵呵,这么红火的东东,不了解就长不了见识. 转一下两个东东,这挖矿机天天在算什么内容,还有,当前为什么GPU比CPU有优 ...

  2. php小数加减精度问题,比特币计算精度问题

    php小数加减精度问题,比特币计算精度问题 在php开发时,有小数加减的场景.结果发现不能够等于预想的值,bccomp比较二个高精确度数字.语法: int bccomp(string left ope ...

  3. 比特币pow算法介绍

    Proof Of Work 工作量证明 借鉴了 哈希现金(Hashcash)-1997年 英国密码学专家亚当.贝克(Adam Back) 用工作量证明系统解决了互联网垃圾邮件问题,它要求计算机在获得发 ...

  4. 比特币PoW

    比特币区块头结构 字段 大小(Byte) 说明 nVersion 4 区块版本号,表示本区块遵守的验证规则 hashPrevBlock 32 前一区块的哈希值,使用SHA256(SHA256(父区块头 ...

  5. 比特币_Bitcoin 简介

    2008-11   Satoshi Nakamoto  Bitcoin: A Peer-to-Peer Electronic Cash System http://p2pbucks.com/?p=99 ...

  6. 我被比特币撞了一下腰——记OKCoin试用体验

    本博客还有大量的.NET开源技术文章,您可能感兴趣: 1.开源Math.NET基础数学类库使用系列文章:链接 2.开源C#彩票数据资料库系列文章:链接 3.开源的.NET平台ORM组件文章:链接 4. ...

  7. GPU---并行计算利器

    转载请引用:GPU---并行计算利器 源于阿里巴巴CCO<猿来如此>分享 1 GPU是什么 如图1所示,这台PC机与普通PC机不同的是这里插了7张显卡,左下角是显卡,在中间的就是GPU芯片 ...

  8. 什么是比特币(bitcoin)

    一.什么是比特币? 比特币是一种由开源的P2P软件产生的电子货币,是一种网络虚拟货币.比特币使用遍布整个P2P网络节点的分布式数据库来记录货币的交易,并使用密码学的设计来确保货币流通各个环节安全性.比 ...

  9. 将P2P虚拟货币(比特币、莱特币....)的算力用于公共的分布式计算的猜想

    比特币最近几年非常火爆.发明者中本聪设计了一个特定的算法用于生成(发行)比特币,让各位玩家(矿工)用自己的CPU.显卡,或者更加专业的矿机,通过无聊的并行计算算出比特币的特定密码(挖矿).为了保证全网 ...

随机推荐

  1. ZZNU-OJ-2119 : 告辞,【卡特兰数列,组合数学】

    2119 : 告辞 时间限制:1 Sec 内存限制:256 MiB提交:428 答案正确:102 提交 状态 编辑 讨论区 题目描述 整个世界都在散发着恋爱的恶臭,只有spring依旧保持着单身贵族的 ...

  2. 《流畅的Python》 Sequence Hacking, Hashing and Slicing(没完成)

    序列修改,散列和切片 基本序列协议:Basic sequence protocol: __len__ and __getitem__ 本章通过代码讨论一个概念: 把protocol当成一个正式接口.协 ...

  3. js 同步 异步 宏任务 微任务 文章分享

    分享一篇 写的很好的 宏任务 微任务  同步异步的文章 文章原地址: https://juejin.im/post/59e85eebf265da430d571f89 这一次,彻底弄懂 JavaScri ...

  4. Linux使用帮助详解

    主要内容:                    whatis                    command --help                     man and info   ...

  5. 怎奈风云多变换,骚完一波还一波,记PHP mongodb驱动的2019年11月用法

    怎么,觉得pecl下一个扩展包,phpize make make install  php.ini里引用一下 mongodb.so就万事大吉了? Deeply Sorry!看到MongoDB\Driv ...

  6. python manage.py makemigrat Please select a fix: 1) Provide a one-off default now (will be set on all existing rows with a null value for this column) 2) Quit, and let me add a default in models.py

    更新models字段 出现的问题: $ python manage.py makemigrations None You are trying to add a non-nullable field ...

  7. 20、自动装配-@Autowired&@Qualifier&@Primary

    20.自动装配-@Autowired&@Qualifier&@Primary 自动装配:Spring 利用依赖注入(DI),完成对IOC容器中各个依赖关系赋值 20.1 @Autowi ...

  8. 2、组件注册-@Configuration&@Bean给容器中注册组件

    2.组件注册-@Configuration&@Bean给容器中注册组件 2.1 创建maven项目 spring-annotation pom.xml文件添加 spring-context 依 ...

  9. [Javascript] Nested generators

    To see how to call another generator inside a generator: function* numbers () { ; ; yield* moreNumbe ...

  10. SIGAI深度学习第九集 卷积神经网络3

    讲授卷积神经网络面临的挑战包括梯度消失.退化问题,和改进方法包括卷积层.池化层的改进.激活函数.损失函数.网络结构的改 进.残差网络.全卷机网络.多尺度融合.批量归一化等 大纲: 面临的挑战梯度消失问 ...