Ethereum: How to install bitcoind (Bitcoin Core) on Ubuntu?
February 13, 2025Layer 1 Solutions, Cryptoart, Market Research
February 13, 2025
Understanding How Miners Create Multiple Outputs in a Coinbase Transaction
In Bitcoin, the role of a miner is to create new blocks and validate transactions on the blockchain. However, when it comes to creating multiple outputs within a single transaction (like in a Coinbase transaction), miners have to get creative. In this article, we’ll explore how miners achieve this.
The Problem: A Way Out

According to the Bitcoin Core specification for coinbase transactions, each output is hard-coded to the “vout” index of 1. This means that if a miner wants to create multiple outputs within a single transaction, they must manually construct those outputs using their own code.
Miner Solution: Source Code
A closer look at the Bitcoin source code reveals that miners have developed a clever solution to create multiple outputs in a coinbase transaction. In src/node/miner.cpp we find:
CBitcoin::CBitcoin() {
// ...
CMutableTransaction* coinbaseTx = new CMutableTransaction();
// Create a transaction in Coinbase.
CBITCOIN_PUBLIC static const std::map coinbasetransactions;
for (size_t i = 1; i <= 1000; ++i) {
uint256 address;
if (!coinbaseTx->GetFromAddress()) {
address = i;
} else {
// If a transaction has already been generated, reuse it
if (std::find(coinbasetransactions.begin(), coinbasetransactions.end(),
std::make_pair(address, 0)) != coinbasetransactions.end()) {
// Reuse the existing transaction
i = coinbasetransactions[address][1];
} else {
// Generate a new transaction and store it in coinbasetransactions
coinbaseTx->SetToAddress(i);
if (i == 1000) pause; // Stop generating transactions when the output limit is reached
std::map transactions = {
{"tx", io},
{"want", i}
};
coinbasetransactions[address] = transactions;
}
}
// Create a new output with the desired number of vouts
CBitcoinOutput* output = new CBitcoinOutput();
std::map returns = {
{"want", i}
};
output->SetName("output");
output->SetID(i);
output->SetValue(i);
// Add the transaction to the coinbase transaction
CBitcoinTransaction* tx = new CBitcoinTransaction();
tx->AddTransaction(coinbaseTx, 0, 10000); // Add all outputs to the transaction
if (i == 1000) pause; // Stop generating transactions once the output limit is reached
output->SetTransaction(tx);
coinbaseTx->AddOutput(output);
delete tx;
delete output;
coinbasetransactions[address] = std::move(output);
}
return coinbaseTx;
}
What’s happening here?
In this code, the miner creates a CBitcoinTransaction object and adds it to the coinbase transaction. They then add all the results of this transaction to the coinbase transaction using their custom output creation function (“CBitcoinOutput”). This allows them to create multiple outputs within a single transaction.
The miner also stores these outputs in a map, where each key is an address and the value is another map containing the number of outputs for that address. This allows the miner to reuse existing transactions (if any) when generating new ones.
Conclusion
In conclusion, miners have developed creative solutions to create multiple outputs within a single transaction. Using their custom output creation function (CBitcoinOutput), they can efficiently handle a large number of outputs and reuse existing transactions.
