難度(Difficulty)python
難度是對挖礦困難程度的度量,即指:計算符合給定目標的一個HASH值的困難程度。比特幣網絡有一個全局的區塊難度,有效的區域必須有一個HASH值,該HASH值必須小於給定的目標HASH。礦池也會有一個自定義的共享難度用來設定產生股份的最低難度限制。ios
難度每過2016塊改變一次,計算公式:difficulty = difficulty_1_target / current_target。目標(target)是一個256位長的數值。算法
有許多不一樣測量難度的方法,獲得的difficulty_1_target可能不一樣。傳統地,它表示一個HASH值,前32位爲0,後續部分爲1(稱之爲:礦池難度或pdiff),比特幣協議把目標HASH表示成一個固定精度的自定義浮點類型,於是,比特幣客戶端用該值來估計難度(稱之爲:bdiff)。網絡
難度常常被存貯在區塊中,每一個塊存貯一個十六制的目標HASH的壓縮表達式(稱之爲:Bits),目標HASH能夠以預先定義的公式計算出來。例如:若是區塊中壓縮的目標HASH爲0x1b0404cb,那十六進制的目標HASH以下所示:ui
0x0404cb * 2^(8*(0x1b - 3)) = 0x00000000000404CB000000000000000000000000000000000000000000000000
於是目標HASH爲0x1b0404cb時,難度爲:編碼
0x00000000FFFF0000000000000000000000000000000000000000000000000000 /
0x00000000000404CB000000000000000000000000000000000000000000000000
= 16307.420938523983 (bdiff)
或者:spa
0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF /
0x00000000000404CB000000000000000000000000000000000000000000000000
= 16307.669773817162 (pdiff)
其中:0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 是挖礦機使用的最大目標HASH值。scala
而0x00000000FFFF0000000000000000000000000000000000000000000000000000則是比特幣網絡使用的浮點編碼類型,後面的位數被縮短。翻譯
下面是一個快速計算比特幣難度的方法,它的算法使用修改的泰勒序列(你能夠看wikipedia上的教程),而且依賴記錄來轉換難度計算。code
#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; } 若是要看以上通常難度計算的數字原理,如下是python代碼: import decimal, math l = math.log e = math.e print 0x00ffff * 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://blockexplorer.com/q/getdifficulty來獲得,下一個難度能夠經過http://blockexplorer.com/q/estimate來得到。難度的變化狀況能夠查看http://bitcoin.sipa.be/。
最大難度大約=maximum_target / 1 (由於0會致使無窮大),這是一個很是大的數值,大約2^224;當maximum_target爲最小1時,最小難度值爲1。
難度根據之前2016個區塊的產生時間,每2016塊改變一次。預計每隔10分鐘產生一個區塊,於是產生2016個區塊要花費2周時間。若是前2016個區塊的產生時間多於兩週,則難度會下降;不然難度就會增長。
爲了找到新區塊,該區塊的HASH值必須小於目標HASH傎,其實是一個在0到2^256-1之間的隨機數,難度1的偏移量是:
0xffff * 2^208
難度D的偏移量是
(0xffff * 2^208)/D
在難度D下,爲了找到新區塊,咱們預期要計算的HASH數量是
D * 2^256 / (0xffff * 2^208)
或者只是
D * 2^48 / 0xffff
難度的設定,是爲了以每10分鐘一個區塊的產生速度產生2016個區塊,於是咱們在600秒內計算 (D * 2^48 / 0xffff) 個HASH,這就意味着產生2016個區塊的網絡HASH速率(算力)是
D * 2^48 / 0xffff / 600
能夠進一步簡化爲:
D * 2^32 / 600
以上公式有較好的精度。
在難度1下,算力是7Mhashes/秒,譯者在翻譯這篇文章時難度是5,006,860,589,這就意味着之前2016個區塊被找到,其平均算力是:35.840PHash/s。
5,006,860,589 * 2^32 / 600 = 大約在35.840 PHash/s
發現一個區塊的平均時間,能夠用如下公式估計:
時間 = 難度 * 2^32 / 算力
其中,難度是當前的難度,算力你的礦機的計算能力,是hashes/s爲單位,時間是你找到的兩個區塊之間的平均時間。舉例:使用Python計算,算力爲1Ghashes/s的礦機,難度在20000時,產生一個新區塊的時間,(其中**表示指數):
$ python -c 「print 20000 * 2**32 / 10**9 / 60 / 60.0」
23.85
意思就是:找到一個新區塊要花費近1小時。
挖礦硬件對比,這裏有一些統計,能夠幫助你預測收入。
收支計算器1,收支計算器2,能幫你計算收支。
記住:這只是可能性,並不能保證你天天都能找到新區塊。建議加入礦池挖礦,經過共享區塊收益的方式,能獲得穩定長期的回報。