|
难度
难度是一个用于显示找到一个比系统定义的目标更低的哈希有多难的值。
Bitcoin network 具有全球 block 难度。有效区块必须在该目标下具有一个 hash 。 Mining 矿池也有一个设定股票的下限的pool-specific共享特征。
目录
运行原则[编辑 | 编辑源代码]
在比特币[网络中所有区块都面临全球困难。对于被认定为合法的区块它必须具有低于设定目标的hash值。
每 2016 个区块都会改变难度。该计算使用以下公式:
难度 = 难度_1_目标 / 当前_目标
其中目标为一个 256-bit 的数字。
难度_1_目标可以取不同值。传统上,它是一个哈希函数,其前32位等于0,而其余均为1(它也被称为pdiff或矿池难度)。比特币协议作为一种具有浮点和有限精度的类型提供了目标。不同的比特币客户通常基于这些数据来决定难度。
区块存储困难[编辑 | 编辑源代码]
每个区块包含一个十六进制目标的压缩版本(称为“位”)。
使用以下公式可以从任何区块中获取目标。例如如果在一个区块中填充的目标显示为0x1b0404cb,它的十六进制版本将如下所示:
0x0404cb * 2**(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000
此域最大值为0x7fffff 而最小值为 0x008000。
最大可能的目标 (难度等于1) 定义为以十六进制数字的形式出现的0x1d00ffff:
0x00ffff * 2**(8*(0x1d - 3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000
接下来是一种简单的计算难度的方法。它使用泰勒级数的修改版本到对数,并依赖于日志来转换难度计算。
#include <iostream>
#include <cmath>
inline float fast_log(float val)
{
int * const exp_ptr = reinterpret_cast <int *>(&val);
int x = *exp_ptr;
const int log_2 = ((x >> 23) & 255) - 128;
x &= ~(255 << 23);
x += 127 << 23;
*exp_ptr = x;
val = ((-1.0f/3) * val + 2) * val - 2.0f/3;
return ((val + log_2) * 0.69314718f);
}
float difficulty(unsigned int bits)
{
static double max_body = fast_log(0x00ffff), scaland = fast_log(256);
return exp(max_body - fast_log(bits & 0x00ffffff) + scaland * (0x1d - ((bits & 0xff000000) >> 24)));
}
int main()
{
std::cout << difficulty(0x1b0404cb) << std::endl;
return 0;
}
最大、当前和最小难度[编辑 | 编辑源代码]
当前难度可以通过使用比特币命令行'getDifficulty'而找到。
由于目标函数没有最大难度的最小值,因此只能近似计算如下: 最大目标 / 1 (由于 0 会使方程无限大) ,其为一个不合适的数字 (~2 至 224)。
最小困难仅对等于 1。
难度变化[编辑 | 编辑源代码]
根据发现之前的2016个区块的时间每2016个区块的难度都有变化。如果每10分钟发现一个区块 (事实上最初准备用于放射的) 发现2016个区块需要整整2周。如果前2016个 区块超过2周才被发现则难度将被降低, 并且如果他们被更快挖掘出来则会提高。花费更多(更少)时间来找前2016个区块 难度将会更低 (高)。
挖掘一个区块哈希需要低于目标 (proof-of-work)。 哈希是一个介于 0 和 2*256-1之间的随机数。
转换为 1的难度: 0xffff * 2**208
对于难度 D: (0xffff * 2**208)/D
为找到对应难度D区块而需解决的哈希函数数量: D * 2**256 / (0xffff * 2**208) 或仅为: D * 2**48 / 0xffff
难度是设定的就好像我们以每10分钟发现一个区块的速度发现前2016个区块。
据此我们每600秒计算一次 (D * 2**48 / 0xffff) 哈希。
我们网络针对前2016个区块的的哈希率 为: D * 2**32 / 0xffff / 600.
不算显著的精度损失我们可以将其简化为: D * 2**32 / 600. 当难度 1时大概是7 Mhash/s.
找到一个单独区块的平均时间可通过该公式计算: 时间= 难度 * 2**32 / 哈希率 其中'难度' 为比特币网络当前难度水平并且'哈希率' 是矿工每秒发现的哈希量。
什么是当前难度?[编辑 | 编辑源代码]
Current difficulty, 正如比特币getDifficulty的输出。
什么是最大难度?[编辑 | 编辑源代码]
没有最小目标。最大难度大概为: 最大目标 / 1 (由于0将导致无穷),其为非常巨大数字(约为 2^224)。
实际最大难度是当current_target=0时, 但如果发生这种情况,我们将无法计算难度。 (幸运的是它永远不会发生,所以没关系。)
网络难度能否降低?[编辑 | 编辑源代码]
是的它可以。
什么是最小难度?[编辑 | 编辑源代码]
当目标达到最大允许值时,最小难度为1。
什么网络哈希率会带导致定难度?[编辑 | 编辑源代码]
根据找到前2016个区块的time ,每2016个区块的难度将被调整。 按照每10分钟一个区块的预期速率,2016个区块需整整两周才能找到。如果找之前2016个区块花费超过两周时间,难度会降低。如果花费少于两周,难度增加。难度的 change 与找到前2016个区块的时间多于或少于两周成正比。
找一个区块哈希必须少于目标。哈希实际上是介于 0 到2**256-1之间的一个随机数字。难度1 的偏移量是
0xffff * 2**208
而对于难度 D 为
(0xffff * 2**208)/D
因此找到一个难度D的 block,我们需要计算出的预期哈希数量
D * 2**256 / (0xffff * 2**208)
或仅为
D * 2**48 / 0xffff
难度按照每10分钟一个的速度找到前2016个区块而设定, 因此我们600秒内计算的哈希为 (D * 2**48 / 0xffff) 。 这意味着网络哈希率为
D * 2**48 / 0xffff / 600
超过前2016个区块。 可进一步简化为
D * 2**32 / 600
无过多精度损失。
当难度 1时,每秒大约 7 Mhashes 。
写作的时候,难度为22012.4941572,这意味着在之前的2016个区块中平均网络哈希率是
22012.4941572 * 2**32 / 600 = 约每秒 157 Ghashes。
我预计多久能生产一个区块?[编辑 | 编辑源代码]
([https://www.bitcointalk.org/index.php?topic=1682.0永久性问题)
找一个区块的平均时间可通过计算近似为: 时间 = 难度 * 2**32 / 哈希率 其中难度为当前难度,哈希率是您的矿工每秒计算哈希,且时间为您找到区块之间的平均秒数。
例如,当难度为 20000时,使用 Python 我们计算生成一个区块的平均时间采用 1Ghash/s 挖掘平台:
$ python -c "print 20000 * 2**32 / 10**9 / 60 / 60.0" 23.85
发现其平均需不到24小时。
- 任何一个粉碎哈希的人都和其他人一样有相同的机会“获胜”。该数字游戏是您的硬件每秒可以做多少次尝试。
- 您需要知道难度 (以上) 以及您的 khash/sec 速率 (客户报告)。
- Mining Hardware Comparison 有一些数据可能帮助您预测到您能获得什么。
- 访问计算器或自己进行数学运算,
- 请记住它仅是个概率! 没有保证您每N天都会赢。