如何計算新的“位”值?
每 2016 個塊需要計算新的比特值。計算它的公式是什麼?
bits
欄位代表什麼?首先,我們需要了解“位”欄位的含義。
位採用“緊湊”格式。這有點像浮點格式,但它表示大整數而不是任意實數。第一個字節表示所代表的數字佔用的字節數,接下來的一到三個字節給出數字的最高有效位。如果第 2 個字節的值大於 127,則該數字被解釋為負數。
要將正整數轉換為“緊湊”格式,我們:
- 將整數轉換為基數 256。
- 如果第一個(最重要的)數字大於 127 (0x7f),則添加一個零數字
- ‘compact’ 格式的第一個字節是上述 base 256 表示中的位數,包括前面的零(如果存在)
- 以下三個字節是上述表示的前三位。如果存在少於三個數字,則緊湊表示的最後一個字節中的一個或多個將為零。
範例 1 - 將 1000 轉換為“緊湊”格式
例如,要以“緊湊”格式表示 1000,我們轉換為基數 256:
1000 = (0x03)*256 + (0xe8)*1
所以我們有一個 2 位的 256 基數:
03 e8
第一個數字不大於 0x7f,因此我們不會在前面添加零數字:
03 e8
然後緊湊表示變為:
02 03 e8 00
範例 2 - 將最大目標轉換為“緊湊”格式
最低難度的目標是 2^(256-32)-1。讓我們以“緊湊”格式表示。首先我們將其轉換為base 256:
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
那是 28 個 0xff 數字。第一個數字大於 0x7f,所以我們在前面加上一個零數字:
00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
現在是 29 位數字。十六進制(29)= 0x1d。所以這個的“緊湊”表示是:
1d 00 ff ff
請注意,我們在那裡失去了很多“ff”數字。我們只保留了 2 個字節的精度,大小字節和前置零字節佔用了四個可用字節中的兩個。如果我們要從“緊湊”格式轉換回來以查看我們實際儲存的數字,我們會得到:
ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
這實際上是比特幣使用的最大目標。這就是難度為 1 設置塊雜湊目標的值。
欄位的值是如何
bits
計算的?現在我們知道了該
bits
欄位的含義,我們可以看看它的值是如何確定的。在官方客戶端中,該bits
值是由函式GetNextWorkRequired()
in計算的src/main.cpp
,它執行以下操作:
如果我們正在處理一個 2016 年倍數的區塊(每 2 週)
- 查看最後一個區塊的時間戳,以及它之前的 2015 區塊
- 計算這兩個時間戳的差異
- 如果差值大於 8 週,則設置為 8 週;這可以防止難度降低超過 4 倍
- 如果差值小於半週,則設置為半週;這可以防止難度增加超過 4 倍
- 將差值乘以目前目標(即目前
bits
從“緊湊”表示轉換為它表示的目標)- 將結果除以 2 週
- 如果結果大於最大目標 (
2^(256-32)-1
),則將其設置為最大目標- 將結果轉換為“緊湊”形式,並將其用作新
bits
值否則(我們正在研究一個不是 2016 倍數的區塊
如果我們在測試網上並且晚於 2012 年 2 月 15 日
如果距離上一個區塊被發現已超過 20 分鐘
- 設置
bits
為它的最高可能值,0x1d00ffff
表示難度為 1;這是“special-min-difficulty
規則”否則
- 設置
bits
為與最後一個非special-min-difficulty
規則塊中的相同否則(我們不在測試網上,或者是在 2012 年 2 月 15 日之前)
- 設置
bits
為與最後一個塊中的相同