Transactions

從鏈狀態解析交易的 UTXO

  • May 11, 2017

我正在通過讀取鏈狀態數據庫對 UTXO 集進行一些分析。

我正在關注https://github.com/bitcoin/bitcoin/blob/d4a42334d447cad48fb3996cad0fd5c945b75571/src/coins.h#L19-L34提供的文件

/** 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版本在哪裡9070nCode它告訴它是否是一個 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,因此在解析位向量時,只有在找到非零值時才應該減少字節計數器。在這裡,您有一段處理此問題的程式碼(在本例中n287):

# 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上查看程式碼。

引用自:https://bitcoin.stackexchange.com/questions/53271