Transactions
從鏈狀態解析交易的 UTXO
我正在通過讀取鏈狀態數據庫對 UTXO 集進行一些分析。
/** pruned version of CTransaction: only retains metadata and unspent transaction outputs * * Serialized format: * - VARINT(nVersion) * - VARINT(nCode) * - unspentness bitvector, for vout[2] and further; least significant byte first * - the non-spent CTxOuts (via CTxOutCompressor) * - VARINT(nHeight) * * The nCode value consists of: * - bit 1: IsCoinBase() * - bit 2: vout[0] is not spent * - bit 4: vout[1] is not spent * - The higher bits encode N, the number of non-zero bytes in the following bitvector. * - In case both bit 2 and bit 4 are unset, they encode N-1, as there must be at * least one non-spent output).
當 UTXO 的數量很少時,解析器工作得很好。但是對於以下 tx(有 2501 個輸出),它失敗了:
2540b961f4a0b231db3bc5a23608307394eae037d8afd0462e9b794e02f00000
對於 key
'c' + 2540b961f4a0b231db3bc5a23608307394eae037d8afd0462e9b794e02f00000
,chainstate 中的(去混淆的)值如下所示:01907050e140254150443a0c280004...
01
版本在哪裡9070
,nCode
它告訴它是否是一個 coinbase tx、 的未花費vout[0]
,vout[1]
以及 的後續未花費位向量的長度vout[2:]
。通過查看 blockchain.info,有 2501 個輸出,所以(2501 - 2)/8 = 312
後面應該有字節。但是,解析9070
為 varint,刪除最後一個位,+1 只給我2288 / 8 + 1 = 287
. (我得到了 2288(0x90 - 0x80 + 1) * 0x80 + 0x70
,這是比特幣協議中使用的 MSB-128 varint。)我在這裡錯過了什麼嗎?究竟如何解析 varint?
你是對的,但是你沒有正確解釋結果。該值確實是
287
,即(2288 >> 3) + 1
,但這並不意味著位向量包含287 bytes
,而是它包含287 non-zero bytes
,因此在解析位向量時,只有在找到非零值時才應該減少字節計數器。在這裡,您有一段處理此問題的程式碼(在本例中n
為287
):# If n is set, the encoded value contains a bitvector. The following bytes are parsed until n non-zero bytes have # been extracted. (If a 00 is found, the parsing continues but n is not decreased) if n > 0: bitvector = "" while n: data = utxo[offset:offset+2] if data != "00": n -= 1 bitvector += data offset += 2
請注意,這只是程式碼的一部分。我最近用 Python 編寫了一個完整的解碼器,你可以在github上查看程式碼。