Bitcoin-Core
python中的比特幣鏈狀態數據庫解析給出錯誤的值
我正在嘗試為 python 中的交易的特定輸出索引解碼chainstate db,以供學習。交易 ID:4d4a4c6ca4f3c91e69563199943336d3279fad71c9e8d9c1708ef9dc6ac16000 出索引 = 1822
chainstate_db = plyvel.DB(os.path.join(os.getenv('HOME'),".bitcoin/chainstate"), compression=None) def getObfuscationKey(): value = chainstate_db.get(b'\x0e\x00' + b'obfuscate_key') print('obfuscation key = %s' % value) obfuscation_key = value[1:] return obfuscation_key def applyObfuscationKey(data: bytes): obfuscation_key = getObfuscationKey() new_val = bytes(data[index] ^ obfuscation_key[index % len(obfuscation_key)] for index in range(len(data))) return new_val def b128_varint_decode(value: bytes, pos = 0): n = 0 while True: data = value[pos] pos += 1 n = (n << 7) | (data & 0x7f) # 1111111 if data & 0x80 == 0: return (n, pos) n += 1 def txout_decompress(x): # x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9 if x == 0: return 0 x -=1 # x = 10*(9*n + d - 1) + e e = x % 10 x /= 10 n = 0 if e < 9: # x = 9*n + d - 1 d = (x % 9) + 1 x /= 9 # x = n n = x*10 + d else: n = x+1 while e: n *= 10 e -= 1 return n ... def getChainstateData(txn_hash_big_endian: bytes, out_index: int): key = b'C' + txn_hash_big_endian + b128_varint_encode(out_index) value = chainstate_db.get(key) value = applyObfuscationKey(value) code, pos = b128_varint_decode(value) height = code >> 1 coinbase = code & 0x01 print('height = %d, coinbase = %r' % (height, coinbase)) decoded_varint_amount, pos = b128_varint_decode(value, pos) amount = txout_decompress(decoded_varint_amount) print('amount = %d' % amount) if __name__ == '__main__': getChainstateData(binascii.unhexlify('0060c16adcf98e70c1d9e8c971ad9f27d3363394993156691ec9f3a46c4c4a4d'), 1822)
我得到以下結果:高度 = 355833,coinbase = 0 數量 = 12353
當我在比特幣核心守護程序中執行 getrawtransaction 時,我得到的金額為 12200。
./bitcoin-cli getrawtransaction 4d4a4c6ca4f3c91e69563199943336d3279fad71c9e8d9c1708ef9dc6ac16000 true
對於索引 1822,我得到:
{ "value": 0.00012200, "n": 1822, "scriptPubKey": { "asm": "OP_DUP OP_HASH160 c40c4870c3874cafb3385dca3731d637ac51110d OP_EQUALVERIFY OP_CHECKSIG", "hex": "76a914c40c4870c3874cafb3385dca3731d637ac51110d88ac", "reqSigs": 1, "type": "pubkeyhash", "addresses": [ "1JscA3193KByPvFv4X6nNEV2SGjdXVcVq6" ] } },
所以我無法弄清楚的程式碼肯定有問題。我認為問題出在
txout_decompress(x)
方法。但這很奇怪,因為我在比特幣核心中直接使用了方法
uint64_t 解壓量(uint64_t x)
在
src / 壓縮器.cpp
將其轉換為python後。請幫我解決這個問題。
經過調查,我發現*txout_decompress(x)*中的 x 不是導致答案不同的整數,因此在除法期間我將其類型轉換為 int 並且它起作用了。所以更正的程式碼:
def amount_decompress(x: int): # x = 0 OR x = 1+10*(9*n + d - 1) + e OR x = 1+10*(n - 1) + 9 if x == 0: return 0 x -=1 # x = 10*(9*n + d - 1) + e e = x % 10 x = int(x / 10) n = 0 if e < 9: # x = 9*n + d - 1 d = (x % 9) + 1 x = int(x / 9) # x = n n = x*10 + d else: n = x+1 while e: n *= 10 e -= 1 return n