Mining Theory – How to make a coinbase? How to use witnesses?
BIP141 added a new rule called “witness appointments.” “Promises are written to the scriptPubKey of the Coinbase transaction,” the document states. I didn’t quite understand what it meant, so I directly placed ‘default_witness_commitment’ provided in the block template when creating Coinbase in the scriptPubKey location. Here is my code:
def makeCoinbase()->None:
global coinbase,tmpl
version=pack('<L',1)
inputCount=unhexlify('01')
txHash=unhexlify('0000000000000000000000000000000000000000000000000000000000000000')
preSequence=unhexlify('ffffffff')
eh=encodeHeight(tmpl('height')) #Don't worry about this function, it handles height
msg=eh+b'my message'
msgSize=pack('B',len(msg))
sequence=unhexlify('ffffffff')
outCount=unhexlify('01')
amount=pack('<Q',tmpl('coinbasevalue'))
script=unhexlify(tmpl('default_witness_commitment'))
scriptSize=pack('B',len(script))
lockTime=unhexlify('00000000')
coinbase=version+inputCount+txHash+preSequence+msgSize+msg+\
sequence+outCount+amount+scriptSize+script+lockTime
tmpl('transactions').insert(0,
'data':coinbase.hex(),
'txid':dblsha(coinbase)(::-1).hex()
)
The tmpl variable is the template obtained using the “getblocktemplate” command. I am testing my code in regtest. When you submit a block, Bitcoin Core creates a new block. And my balance increased. However, when I checked Coinbase for the newly created block, the results were as follows.
'txid': '9cb794f3292d1ece3af6c1d3055cf6fb26cf2126ff48b39b229bfec5ec651ec4',
'hash': 'de081b2a9552ac559d3501ed0669f675530fe9890e27d263c1aff65e678ddc4e',
'version': 1,
'size': 153,
'vsize': 126,
'weight': 504,
'locktime': 0,
'vin': (
'coinbase': '016c54686520477265617420476f642050616e',
'txinwitness': ('0000000000000000000000000000000000000000000000000000000000000000'),
'sequence': 4294967295),
'vout': (
'value': Decimal('50.00063100'),
'n': 0,
'scriptPubKey':
'asm': 'OP_RETURN aa21a9edb14717ddf39dacad0babfff4d8d951c076e95d11d2b1f328632c32f98c015d2c',
'desc': 'raw(6a24aa21a9edb14717ddf39dacad0babfff4d8d951c076e95d11d2b1f328632c32f98c015d2c)#psf60z3m',
'hex': '6a24aa21a9edb14717ddf39dacad0babfff4d8d951c076e95d11d2b1f328632c32f98c015d2c',
'type': 'nulldata'
),
'hex': '010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff13016c54686520477265617420476f642050616effffffff017ce8062a01000000266a24aa21a9edb14717ddf39dacad0babfff4d8d951c076e95d11d2b1f328632c32f98c015d2c0120000000000000000000000000000000000000000000000000000000000000000000000000'
As you can see, it only contains one vout. And that vout doesn’t contain any address. But if you look at Coinbase for a block on the main network, it always contains more than one vout, and the vout contains an address. My question is, am I building Coinbase the right way? If not, how do I fix it? Bitcoin Core did not report any errors, but I always suspected that I had lost the miner’s address.