I am looking at the specific block at height 680175.

Via bitcoin-cli getblock 00000000000000000004dbd66fa71fdcd62658bf8c8e2e153521257ad5858c71 0 I obtained the serialized, hex-encoded block data. According to the section Serialized Blocks the txn_count starts at Byte #81. Following the description of CompactSize Unsigned Integers I get:

In [115]: int.from_bytes(byte_arr[80:81], "little", signed=False)
Out[115]: 253

In [116]: tnx_count = byte_arr[81:83]
     ...: tnx_count = int.from_bytes(tnx_count, "little", signed=False)

In [117]: tnx_count
Out[117]: 1702

There are indeed 1702 transactions which can be verified via ./bitcoin-cli getblock 00000000000000000004dbd66fa71fdcd62658bf8c8e2e153521257ad5858c71 2 in the attribute nTx.

Now I know that the rest of the block data is the transactions' part. According to the section Raw Transaction Format the first 4 bytes are the version:

In [118]: tnx_part = byte_arr[83:]

In [119]: version = tnx_part[:4]

In [120]: int.from_bytes(version, "little", signed=False)
Out[120]: 1

This seems to be correct, too. So, the next bytes determine the number of tx_in count, but there I get 0 which is false. And the input of the coinbase transaction does not start with a 32-byte null:

In [121]: int.from_bytes(data[4:5], "little", signed=False)
Out[121]: 0

In [122]: data[4:10]
Out[122]: bytearray(b'\x00\x01\x01\x00\x00\x00')

Am I missing something? The input of the coinbase transaction seems not to match the description.

  • You want to read BIP144 which introduces an extended serialized transaction format that includes segregated witness data. It is characterized by an apparent 0 txin count. – Pieter Wuille Apr 24 at 20:41

Segwit changed the transaction format. This new format is specified in BIP 144. This new format is actually a modification to the original transaction format. The changes are just additions to it.

Specifically, what you are missing is that the field immediately following the version number is a single 0 byte (referred to as the marker byte), instead of the input count. This was done specifically to make a transaction appear as if it has no inputs to a legacy transaction parser. Following this marker byte is a flag byte, which currently is a single 1 byte. Then you have the input count, inputs, output count, and outputs as was previously. The last change is that following the outputs, instead of the lock time, there are multiple arrays containing the witness data for inputs. Lastly the locktime ends the transaction as previously.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.