<blockquote>
<p>I always suspected that I had lost the miner's address.</p>
</blockquote>
<p>True, you have the BIP-141 witness commitment (an OP_RETURN) but you do not have an output that pays the miner.</p>
<p>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).</p>
<p>So I guess you want <code>outCount=unhexlify('02')</code> and when you construct <code>coinbase=</code> ... append a second set of  <code>+amount2+scriptSize2+script2</code> before <code>+lockTime</code></p>

CC BY-SA 4.0
2023-12-13T11:06:14.050Z
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
CC BY-SA 4.0
2023-12-13T11:06:24.130Z
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
CC BY-SA 4.0
2023-12-13T13:53:08.283Z
(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](https://bitcoin.stackexchange.com/q/107872/13866)
RedGrittyBrick
CC BY-SA 4.0
2023-12-13T13:56:31.180Z
Thanks for your patience. I get it
Jack Green
CC BY-SA 4.0
2023-12-13T09:40:45.883Z
2023-12-13T09:47:46.133Z
2023-12-13T09:47:46.133Z
RedGrittyBrick
<p>BIP141 adds a new rule called &quot;witness commitment&quot;. The document says: &quot;The commitment is recorded in a scriptPubKey of the coinbase transaction.&quot; 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：</p>
<pre><code>def makeCoinbase()-&gt;None:
    global coinbase,tmpl
    version=pack('&lt;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('&lt;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()
    })
</code></pre>
<p>The variable tmpl is the template obtained using the &quot;getblocktemplate&quot; 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:</p>
<pre><code>{
    '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'
}
</code></pre>
<p>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.</p>

<mining-theory><coinbase-transaction><witness-commitment>
How to create coinbase? How to use witness?
Jack Green
# How to create coinbase? How to use witness?

(Asked by: username_0 on 2023-12-13)

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.

**Tags:** mining-theory, coinbase-transaction, witness-commitment


---

## 1 answers

### Answer by username_1 on 2023-12-13. Score: 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`

> **Comments:**
> **username_0**: 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?  
> **username_0**: 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  
> **username_1**: (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](https://bitcoin.stackexchange.com/q/107872/13866)  
> **username_0**: Thanks for your patience. I get it  

---

