0

BIP141 adds a new rule called "witness commitment". The document says: "The commitment is recorded in a scriptPubKey of the coinbase transaction." I didn't quite understand what that meant, Therefore, I directly placed the 'default_witness_commitment' provided by the block template in the scriptPubKey location when creating coinbase. Here's 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 variable tmpl is the template obtained using the "getblocktemplate" command.I'm testing my code in regtest. When I submit a block, Bitcoin Core does create a new block. And my balance did go up. However, when I checked coinbases in the newly generated block, the result was 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 contains only one vout. And that vout does not contain address. But I look at coinbase for blocks in the main network, and it always contains more than one vout, and the vout contains the address.My question is am I building coinbase the right way? If not, how do I fix it? Although the Bitcoin core did not report errors, I always suspected that I had lost the miner's address.

1 Answer 1

0

I always suspected that I had lost the miner's address.

True, you have the BIP-141 witness commitment (an OP_RETURN) but you do not have an output that pays the miner.

Currently it looks to me like you are burning the BTC 50 you assigned to the OP_RETURN vout. I think you should instead assign that value to a second vout that pays the miner through an appropriate locking script (scriptPubKey).

So I guess you want outCount=unhexlify('02') and when you construct coinbase= ... append a second set of +amount2+scriptSize2+script2 before +lockTime

4
  • I changed the code later, and as you said, I set two vouts. But I put reward in the first vout and witness in the second vout,like this: vout1=reward+scriptsize+script vout2=0+size(default_witness_commitment)+default_witness_commitment is this correct?
    – Jack Green
    Dec 13, 2023 at 11:06
  • And I also encountered another problem, I get the pukey and scriptpubkey of my address using the "getaddressinfo" command. address='bcrt1q95h0le6kknpnjp4c29cau03gvdyxd35zug30yr' pubKey='022847e92a4202b75e5799ed13d1a529dcfcafc5d594bdf1e2c2a14f462683aeb8' scriptPubKey='00142d2effe756b4c33906b85171de3e28634866c682' I found that by putting scriptpubkey into vout1 without any opcode, submitting the block and reviewing it, I could see the correct address. But if I add the opcode, the address in the generated new block is wrong, or there is no address. So I'm not sure if I should add an opcode
    – Jack Green
    Dec 13, 2023 at 11:06
  • (1) So far as I can see, BIP-141 doesn't specify a particular output index for the commitment. (2) In your scriptPubKey, 00 is OP_ZERO and 14 is OP_PUSHBYTES_20 (or similar, it doesn't have a standard name). So there are opcodes and adding more will just make the transaction nonstandard (and probably waste money). This is a standard P2WPKH locking script as you can see in answers to this question Dec 13, 2023 at 13:53
  • Thanks for your patience. I get it
    – Jack Green
    Dec 13, 2023 at 13:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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