Bitcoind
coin.h 中的序列化如何工作?
我專門講這個:
/** 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). * * Example: 0104835800816115944e077fe7c803cfa57f29b36bf87c1d358bb85e * <><><--------------------------------------------><----> * | \ | / * version code vout[1] height * * - version = 1 * - code = 4 (vout[1] is not spent, and 0 non-zero bytes of bitvector follow) * - unspentness bitvector: as 0 non-zero bytes follow, it has length 0 * - vout[1]: 835800816115944e077fe7c803cfa57f29b36bf87c1d35 * * 8358: compact amount representation for 60000000000 (600 BTC) * * 00: special txout type pay-to-pubkey-hash * * 816115944e077fe7c803cfa57f29b36bf87c1d35: address uint160 * - height = 203998 * * * Example: 0109044086ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4eebbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa486af3b * <><><--><--------------------------------------------------><----------------------------------------------><----> * / \ \ | | / * version code unspentness vout[4] vout[16] height * * - version = 1 * - code = 9 (coinbase, neither vout[0] or vout[1] are unspent, * 2 (1, +1 because both bit 2 and bit 4 are unset) non-zero bitvector bytes follow) * - unspentness bitvector: bits 2 (0x04) and 14 (0x4000) are set, so vout[2+2] and vout[14+2] are unspent * - vout[4]: 86ef97d5790061b01caab50f1b8e9c50a5057eb43c2d9563a4ee * * 86ef97d579: compact amount representation for 234925952 (2.35 BTC) * * 00: special txout type pay-to-pubkey-hash * * 61b01caab50f1b8e9c50a5057eb43c2d9563a4ee: address uint160 * - vout[16]: bbd123008c988f1a4a4de2161e0f50aac7f17e7f9555caa4 * * bbd123: compact amount representation for 110397 (0.001 BTC) * * 00: special txout type pay-to-pubkey-hash * * 8c988f1a4a4de2161e0f50aac7f17e7f9555caa4: address uint160 * - height = 120891 */
我真的不明白 nCode 是如何工作的。我們來看第二個例子:
第一位被設置為表明它是一個 coinbase 交易。到目前為止
nCode = 01
。vout[0] 和 vout[1] 被花費,這意味著我們加 1,因為至少有 1 個未花費的輸出。所以位遮罩是0001 0001,等於0x11。所以我們已經有了一個大於 0x09 的數字。這到底是怎麼
nCode = 0x09
計算出來的?
(注意:我將使用與評論不同的位編號,
0..B
而不是1..2^B
,因為我發現自己更容易閱讀)
0x9
在官能團中分離的二進製表示是bit# ...6543 21 0 --------- 0001 00 1
- 位 0 被設置,因為這是一個 coinbase
- 第 2 位和第 1 位為 0,因為 vout[0] 和 vout[1] 都用完了
- 位 3+ 僅包含二進制數
1
。由於未設置位 1 和 2,因此這些位編碼 N-1。N=(9>>3)+1=2
. 這裡的 N 是後續位向量中的字節數。後面的兩個字節是
04
and40
,編碼數字 0x440,即設置了位 2 (1<<4=0x04
) 和 14 (1<<14=0x4000
) 的數字。如範例中所述,這意味著vout[2+2]
並且vout[14+2]
未使用。你怎麼會在 0x11 結束?