區塊鏈鼻祖比特幣之11:比特幣困難度

尹成發表於2018-04-27


什麼是比特幣的困難度?

Difficulty is a measure of how difficult itis to find a hash below a given target.

The Bitcoin network has a global block difficulty.Valid blocks must have a hash below this target. Mining pools also have apool-specific share difficulty setting a lower limit for shares.

比特幣困難度何時改變?

Every 2016 blocks.

困難度如何表示?

difficulty = difficulty_1_target /current_target

(target is a 256 bit number)

difficulty_1_target can be different forvarious ways to measure difficulty. Traditionally, it represents a hash wherethe leading 32 bits are zero and the rest are one (this is known as "pooldifficulty" or "pdiff"). The Bitcoin protocol represents targetsas a custom floating point type with limited precision; as a result, Bitcoinclients often approximate difficulty based on this (this is known as"bdiff").

困難度如何儲存在區塊中?

Each block stores a packed representation(called "Bits") for its actual hexadecimal target.The target can be derived from it via a predefined formula. For example, if thepacked target in the block is 0x1b0404cb, the hexadecimal target is

0x0404cb * 2**(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000

Note that the 0x0404cb value is a signedvalue in this format. The largest legal value for this field is 0x7fffff. Tomake a larger value you must shift it down one full byte. Also 0x008000 is thesmallest positive valid value.

困難度的計算?

The highest possible target (difficulty 1) isdefined as 0x1d00ffff, which gives us a hex target of

0x00ffff * 2**(8*(0x1d - 3)) = 0x00000000FFFF0000000000000000000000000000000000000000000000000000

It should be noted that pooled mining oftenuses non-truncated targets, which puts "pool difficulty 1" at

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

So the difficulty at 0x1b0404cb is therefore:

0x00000000FFFF0000000000000000000000000000000000000000000000000000 /
0x00000000000404CB000000000000000000000000000000000000000000000000 
= 16307.420938523983 (bdiff)

And:

0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /
0x00000000000404CB000000000000000000000000000000000000000000000000 
= 16307.669773817162 (pdiff)

Here's a fast way to calculate bitcoindifficulty. It uses a modified Taylor series for the logarithm (you can seetutorials on flipcode and wikipedia) and relies on logs to transform thedifficulty calculation:

#include <iostream>
#include <cmath>
inlinefloat fast_log(float val)
{
   int*const exp_ptr =reinterpret_cast<int*>(&val);
   int x =*exp_ptr;
   constint 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(unsignedint bits)
{
    staticdouble max_body = fast_log(0x00ffff), scaland = fast_log(256);
    returnexp(max_body - fast_log(bits &0x00ffffff)+ scaland *(0x1d-((bits &0xff000000)>>24)));
}
int main()
{
    std::cout<< difficulty(0x1b0404cb)<< std::endl;
    return0;
}

To see the math to go from the normaldifficulty calculations (which require large big ints bigger than the space inany normal integer) to the calculation above, here's some python:

importdecimal,math
l =math.log
e =math.e
print0x00ffff * 2**(8*(0x1d - 3)) / float(0x0404cb * 2**(8*(0x1b - 3)))
print l(0x00ffff * 2**(8*(0x1d - 3)) / float(0x0404cb * 2**(8*(0x1b - 3))))
print l(0x00ffff * 2**(8*(0x1d - 3))) - l(0x0404cb * 2**(8*(0x1b - 3)))
print l(0x00ffff) + l(2**(8*(0x1d - 3))) - l(0x0404cb) - l(2**(8*(0x1b - 3)))
print l(0x00ffff) + (8*(0x1d - 3))*l(2) - l(0x0404cb) - (8*(0x1b - 3))*l(2)
print l(0x00ffff / float(0x0404cb)) + (8*(0x1d - 3))*l(2) - (8*(0x1b - 3))*l(2)
print l(0x00ffff / float(0x0404cb)) + (0x1d - 0x1b)*l(2**8)

 




網址:http://www.qukuailianxueyuan.io/



欲領取造幣技術與全套虛擬機器資料

區塊鏈技術交流QQ群:756146052  備註:CSDN

尹成學院微信:備註:CSDN



相關文章