BIP-34 claims that in coinbase transactions, the scriptSig should contain the block height. It says the format of this is “serialized CScript”, i.e. a byte indicating the length of the number (
n), and then
n bytes in little-endian format.
This works if you look at e.g. the most recent block as of this writing—block 640037—whose coinbase scriptSig begins with these 4 bytes:
0x03 indicates the length, and then we have
(0x25=37 * 256^0) + (0xc4=196 * 256^1) + (0x09=9 * 256^2), or
37 + 50176 + 589824 = 640037.
For obvious reasons mainnet and testnet will never need to encode heights 1-16 in their coinbase. But regtest nodes will. When I run a fresh regtest node (
v0.19.1) and generate a couple blocks, I get coinbase scriptSigs that look like this:
height 1: 0x510101 height 2: 0x520101 ... height 16: 0x600101
Clearly it’s not serialized CScript, at least in the format described in BIP-34. If it were, those first bytes would indicate data lengths of 81, 82, and 96 respectively, clearly ridiculous. The actual encodings of 1, 2, and 16 in serialized CScript are
0x0110. It looks to me like the format is
height+80 followed by
0x0101. And for some reason this only persists for the first 16 blocks, as 17’s scriptSig is
I tried looking through the bitcoin source code, but I don’t write much C++ so it’s hard to tell what’s going on. No documentation—in the source (as far as I can tell) or the PR for BIP-34 or in the BIP itself seems to indicate that heights 1-16 would have a different format from every other height.
Why is this happening?