Difficulty
在 C++ 中驗證比特幣目標(難度)值的最有效方法是什麼
我有兩個價值觀
1. h = hash of the block (32 bytes long in memory representation - not hex) 2. bits (uint32_t)
為了使計算更容易,我們創建了一個函式難度,使得:
auto d = difficulty(bits)
現在創建這樣一個難度函式的最佳方法是什麼,我認為應該返回一個 256 位的值?
然後我正在考慮將 h 和 d 值都轉換為 uint64_t 類型的數組,並比較 msb(第 255 位)中的所有 4 個元素以確保條件成立。
還有更好的比較方法嗎?
Bitcoin Core 有自己的
arith_uint256
類用於計算 256 位無符號整數。arith_uint256
可以arith_uint256::SetCompact
在文件中找到將“位”(所謂的緊湊格式)轉換為的程式碼arith_uint256.cpp
。所以你總是可以直接使用它的程式碼。這可能是一個好主意,因為如果您的版本與他們的行為有任何不同(例如舍入錯誤),您可能不同意比特幣核心關於塊的有效性。如果您的版本在廣泛使用的客戶端中,這將分叉區塊鏈。
我提出了以下版本,對於我定義的少數測試案例似乎可以正常工作。
首先,我們需要一個輔助函式來列印給定二進制數據的十六進制值:
void hexdump(unsigned char *data, int len) { int c = 0; while (c < len) { cout << hex << std::setw(2) << std::setfill('0') << static_cast<int>(data[c++]); } printf("\n"); }
現在讓我們定義接受 block.bits 並將其轉換為記憶體中的 256 位值的實際函式:
bool convert_bits(uint32_t bits, uint64_t* value, int val_len = 4) { assert(val_len == 4); assert(value != NULL); if (val_len != 4 || value == NULL) { return false; } // if bits = 0x1b0404cb, hex target = 0x0404cb * 2**(8*(0x1b - 3)) uint32_t x = 8 * ((bits >> 24) - 3); // number of zero bits on right uint64_t val = bits & 0x00FFFFFF; // Number of maximum bits required for val is 24. assert(x <= (256 - 24)); if (x > (256 - 24)) { return false; } int startq = (3 - int(x / 64)); int endq = (3 - int((x + 24) / 64)); int shift = ((3 + endq) * 64 - x); if (startq != endq) { shift = 64 - shift; } value[startq] = htobe64(val << shift); value[endq] = htobe64(val >> shift); return true; }
現在讓我們測試一下上面的函式:
int main() { uint64_t num[4] = { 0, 0, 0, 0 }; if(convert_bits(0x1b0404cb, num)) { hexdump((unsigned char *)num, sizeof(uint64_t) * 4); } return 0; }
這列印: 00000000000404cb000000000000000000000000000000000000000000000000