I am trying to build a coinbase for mining with the following steps:

1-Create dummy Input and output.

2-Pass them to CreateRawTransaction as collection/

3-Get a transaction back and fill the empty fields according to coinbase structure (specially set Txout’s Value to 12.5 bitcoin).

4-Serialized transaction into Hex string mode.

With above steps preformed in RegTest mode a new block created and 50 Bitcoins added to the wallet which seems to be correct but as far as I know a transaction should be signed, Is Coinbase excluded from signing procedure ? and why it’s add 50 bitcoins to account instead of amount which I specific set to 12.5 bitcoin ?

public async Task<string> BuildCoinbaseTransaction(string MinerAddress, uint Height)    
    string coinTxSerialized = string.Empty;    
    scriptData = Tools.RandomNumbers(rEngine);    
    string pubKey = await GetPublicKey(MinerAddress);    
    string scriptPubKey = CreateCoinbaseScript(pubKey);

    List<object> txi = new List<object>
    { new CoinIn { TxId = "0".PadLeft(64, '0'), Index = 0x0 } };

    List<object> txo = new List<object>
      { new Dictionary<string, double> { { MinerAddress, 0.00 } } };

    RPCResult<string> rpcResult = await cmd.CreateRawTransactionAsync(txi, txo);

    if (rpcResult.Error == null)    
        TotalReward = Math.Min(RewardCoins + CollectedFee, MaxCoinbaseValue);    

        string rawCoinbase = rpcResult.Result;        
        string decodedTx = await cmd.DecodeRawTransaction_CommandAsync(rawCoinbase);

        RPCResult<string> Transaction jsonTx= JsonConvert.DeserializeObject<RPCResult<string>>(decodedTx);    
        Transaction coinTx = jsonTx.Result;

        coinTx.Height = BuildHeight(Height);    
        coinTx.TxIn.FirstOrDefault().Coinbase = scriptData;    
        coinTx.TxIn.FirstOrDefault().Sequence = 0xFFFFFFFF;    
        coinTx.TxOut.FirstOrDefault().Value = TotalReward;    
        coinTx.TxOut.FirstOrDefault().ScriptPubKey.Assembely = scriptPubKey;    
        coinTx.Hex = coinTx.ToString();    
        coinTxSerialized = coinTx.Hex;    

        return coinTxSerialized;    


1 Answer 1


The coinbase transaction is constructed by the miner/mining pool operator and is not a transaction which can be broadcast to the mempool.

The amount of the coinbase output is strictly according to the block height, which begins with 50 BTC and halves every 150 blocks in regtest mode. When you create a new block in regtest mode, it will automatically generate a coinbase transaction, with the output spending to your specified coinbase wallet.

The input script of the coinbase has the [blockheight (4B)] and additional data, totally a maximum of 100B.


  • Previous TX hash: 00..00
  • Previous output index: max_value(ff..ff)
  • Input script: [blockheight (4B)] [additional arbitrary data]

The input is not signed because it does not spend from a UTXO. There are no locking conditions other than to be committed to a header with valid POW.

  • why are there scriptPubKey's in vout's of coinbase transactions?
    – Joe
    Aug 1, 2021 at 5:48
  • 1
    The scriptPubKey in coinbase vouts indicate the spending conditions of the mining reward: this way, the miner can indicate who can spend the mining fees/minted coins.
    – James C.
    Aug 2, 2021 at 12:31

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.