There are a few limitations on the structure of the coinbase (reward) transaction in a block.
- There is only one input.
vin.size() == 1
(source) - It doesn't reference any previous output.
vin[0].prevout.IsNull()
(source) - The scriptSig is not too big.
vin[0].scriptSig.size() <= 100
(source) - The scriptSig is not too small.
vin[0].scriptSig.size() >= 2
(source)
I don't see the point of any of these. #1 and #2 enable BIP34, but they are not necessary to achieve the same outcome. The size constraints don't really limit anything, if a miner wants to make a large block they can just many many outputs in their coinbase, or many many transactions into their block.
Why isn't a coinbase transaction just a transaction which:
- Has at least one input that doesn't reference any previous outputs (for use in BIP34)
- Allowed to claim up to (block reward + fees) more than it can spend
In particular, the coinbase could optionally have further null inputs and could spend previous outputs.
I know for Bitcoin it's likely too late for these to change. Is this a case of over-designing, or are there security reasons for any of these constraints on the coinbase? Loosening constraint #2, in particular, makes me pause because of a bitcoin development mailing list email concerning how allowing the coinbase to spend prevouts would enable securely paying a miner to mine a chain reorganization in a particular way.
#1 and #2 enable BIP34
Actually, block height goes in the scriptSig, not the prevout.