Coinbase outputs as Transaction outputs

Disclaimer: I’m not familiar with the code implementation so this builds from some random facts that were shared over time on keybase.

Right now the coinbase outputs and kernels are labeled as Coinbase which can be seen here

This means two things:

  1. Coinbase outputs are not a part of the anonymity set of transactions appearing in a block
  2. Coinbase outputs hence don’t any have anonymity which leaves miner outputs transparent for everyone to trace

Coincidentally, a youtube video was shared today (paper is also linked) that does some upper bound analysis on the UTXO amounts which is possible due to everyone being able to identify the coinbase outputs.

The reason why coinbase outputs are separate (afaik) is because of the maturity rule which prevents spending of coinbase outputs for a certain amount of time (not sure how much, a day maybe?). I’m not sure why this rule exists so if someone knows the answer please share.

Making outputs indistinguishable:

It would be worth thinking whether it would make sense to unify the outputs by making coinbase outputs have the same Transaction type which would and make them indistinguisable from transactions in the block (the same kernel+offset aggregation that protects the transactions also prevents users from finding out coinbase output from the kernel - unless there is only the coinbase output and kernel in a block).

Looking only at the blockchain data (ignoring p2p), the benefit of this would be that:

  1. each transaction output gains +1 output obfuscation on their outputs side
  2. miner coinbase gains +(N_outputs - 1) output obfuscation on their outputs side
  3. less information for chain analysis
  4. the protocol becomes simpler because coinbase output is no longer an edge case (I think)

It’s not all pretty because at the p2p layer, nodes might be able to guess that the output that did not appear in the transaction mempool is the coinbase output, but this is happening outside of the blockchain and might get non-consensus-breaking improvements over time… perhaps.

Open questions:

  1. What is the exact reasoning behind the coinbase maturity rule? Is it needed?
  2. Does this introduce any problems?
  3. Would it be worth it?

Thanks to @Kurt for starting the conversation about this idea

Edit: I’ve added a section that explains why coinbase output can’t be found out from the coinbase kernel.

1 Like

It is considered something of a necessity in bitcoin, but Ethereum appears to get by without it, as I find no mention in the Yellow paper:


good to put this all together here :slight_smile:
As i am assuming some people are not familiar with the interest and function of coinbase maturity (i am myself not familiar with it) feature i will not be original and copy a message on Stack Exchange which explains it quite well i think:

"Generated coins can’t be spent until the generation transaction has 101 confirmations. Transactions that try to spend generated coins before this will be rejected.

The reason for this is that sometimes the block chain forks, blocks that were valid become invalid, and the mining reward in those blocks is lost. That’s just an unavoidable part of how Bitcoin works, and it can sometimes happen even when there is no one attacking the network. If there was no maturation time, then whenever a fork happened, everyone who received coins that were generated on an unlucky fork (possibly through many intermediaries) would have their coins disappear, even without any sort of double-spend or other attack. On long forks, thousands of people could find coins disappearing from their wallets, even though there is no one actually attacking them and they had no reason to be suspicious of the money they were receiving. For example, without a maturation time, a miner might deposit 25 BTC into an EWallet, and if I withdraw money from a completely unrelated account on the same EWallet, my withdrawn money might just disappear if there is a fork and I’m unlucky enough to withdraw coins that have been “tainted” by the miner’s now-invalid coins. Due to the way this sort of taint tends to “infect” transactions, far more than 25 BTC per block would be affected. Each invalidated block could cause transactions collectively worth hundreds of bitcoins to be reversed. The maturation time makes it impossible for anyone to lose coins by accident like this as long as a fork doesn’t last longer than 100 blocks. If a fork does last longer than 100 blocks, then the damage caused by invalidated transactions would likely be a huge disaster. (However, something else would have to be seriously wrong with Bitcoin or the Internet for a fork to last this long.)"

My partial conclusion would be that not having the feature can cause some non-negligible damage to unfortunate users that bought those coins, and since coinbase outputs can be appended to other outputs, the potential loss of those users does not seem limited to the value of a coinbase reward, but can be arbitrarily larger.

For ethereum, maybe that the account-base system that they have protects naturally against the issue?
If not, I would argue it would be nice to understand more why they don’t use it, or how they prevent from damages, maybe at wallet level implementation ? “This coins are from a recent coinbase, I do not want them”

Nonetheless, by its intrinsic design, it seems Mimblewimble is the only model maybe that can allow for coinbase outputs indistinguishibility, so that it is an interesting problem to look at more closely probably

I’m not sure what to think about this rule - it feels good to save some cases but it feels wrong at the same time. At the end of the day, a receiver of coins will need to wait X blocks for confirmation. The smaller the X, the bigger the probability of coins disappearing (whether that be from a 51% attack or a reorg and coinbase outputs disappearing seems irrelevant). What this does is prevents some scenarios of random (small?) reorgs happening and people losing money due to not being careful. This is useful, but it seems like it comes at a cost of needing the coinbase being handled as an edge case and hence complecting the implementation to protect users that don’t really know how to protect themselves on a blockchain. I wouldn’t want anyone to lose money, but the solution to this is also to make sure they know how to protect themselves, or to protect them with a minimal “time protection” for all cases e.g. make each output spendable only after 10 blocks or something…

There was a line in keybase where you said you got the difference. But just to reiterate here, the difference is that a reorg with your txs with mature UTXOs makes your money go back to you (there may even be some mempool tricks that will get them included into the valid chain without any extra steps, otherwise send them again). When reorgs happen with immature coinbase UTXOs, everyone gets screwed and it could snowball… everyone who thought they had those coins are S.O.L. because those coins dont even exist (very different from the mature UTXO example before). The number of confirmations one uses to consider mature UTXOs spendable is much lower than the number of confirmations required to accept immature UTXOs as spendable. Would you want all transactions to be unspendable for a day? Or would you rather there be a coinbase maturity consensus rule? I prefer the latter. I do not believe a 10 block rule for coinbase to become mature would be sufficient to ensure security because of how different the risks are as stated above.

1 Like

Yes, I understand that the txs can be replayed with a friendly reorg. The part I’m most confused about is that a coincidental reorg is very very unlikely to be 10 blocks in Bitcoin. The only case I can think of right now is that a node graph is somehow partitioned for more than an hour (perhaps global network connectivity issues or some sort of a consensus failure). It makes more sense now that I think that these cases can occur, I didn’t think of them before.

@lehnberg digged out some useful links from past discussions:

Coinbase outputs being separate seems to have been a conscious decision to prevent certain attacks

1 Like

A deep reorg of more than 10 blocks is most likely the result of a double spending attack. These are almost exclusively targeted at exchanges, which require many more confirmations. Exchanges should be particularly cautious about confirming the spending of huge outputs, which are exactly what the attackers will try to doublespend.

A typical attack will rent enough hashpower to reorg a few hundred blocks (at a cost on the order of $10K in case of Grin) in order to double spend a few $100K or more (to make it worth the risk).
Without coinbase maturity, any reorged coinbases would still be subject to an exchange’s confirmation requirement before being able to be sold.

I don’t know how likely it is that a pool will send them off to an exchange right away. Some fraction will, some other fraction could be sold OTC, while the remaining fraction might be held by the pool for at least a while.
The fraction that does get sold would end up as collateral damage for coinbase buyers (and their descendents).

What coinbase maturity changes is who suffers the collateral damage (which is of the same order of $10K that the attacker spent on rent). Whether it is the mining pool exclusively, or in part some others they managed to sell the coinbase to during the attack.


One of the Beam dev has replied to this video

Not necessarily true. In fact, for bitcoin, the only fork that long since 2010 was because of a consensus bug in bitcoin v0.8 that caused a 24 block fork. The damage could’ve been even worse if the coinbase outputs were able to be spent right away.


Ethereum fixes the coinbase maturity by instead giving reward to orphan blocks, but less reward than longest chain block. I wonder how this tweak works, how can this not require trust. But they have to fix this issue since they have short block times

That doesn’t fix much, as uncle rewards are much smaller, and a reorg of depth 7 or more will eliminate all uncle rewards as well.

that fixes up to reorg of depth 5. i never said i liked the fix. bitcoin does it clean

No, whoever bought the main (non-uncle) reward from that small reorg is still S.O.L.

What does SOL mean? Yeah it seems half a fix. i guess they are happy with that, which is weird

Sore Out of Luck


1 Like

There is a good related thread here from zcash discussing the coinbase maturity rule -


So from the various comment here ii seems like the “coinbase maturity rule” attempts to minimize damage incurred during a reorg for a couple of different reasons -

  1. large reorg with explicit double spend attack
  2. large reorg due to consensus bug

I think @tromp (and others) has convinced me that (1) is an issue regardless of coinbase maturity.
(2) is still interesting and is more in line with minimizing the side effects and unintentional double spends (or non-spends) of anything derived from any coinbase outputs that end up re-org’d out of existence. That said, coinbase maturity does not appear to be any silver bullet here either. A large re-org is going to massively damaging whatever happens.

On the “pros” side of things -

  • simplicity - no coinbase as special case makes everything simpler
    • also potentially simplifies logic around “duplicate outputs” if we decide to support these
  • on-chain privacy as discussed above - every block gets an additional output/kernel aggregation (ignoring p2p tx analysis etc.)
  • less data - ideal scenario would remove the features byte from inputs/outputs

I do wonder how much privacy gains we actually see in practice with this. On-chain is clear but tx relay and txpool/stempool is far less clear. Anybody relaying txs is very likely currently to see majority of outputs in a block in tx form and would be able to identify the subset of outputs that would contain the coinbase output. In many cases this is likely a single output.

There are probably things a miner can do to potentially hide coinbase outputs though.
It feels like there is room in there for improvements over time.
The coinbase output is just a regular output now, so maybe it can be broadcast as part of a regular tx ahead of time. The miner aggregating and adjusting at block construction time somehow. Just thinking out loud, have not thought this through fully.
There is no separate coinbase validation any more - the validation rule is rolled up into the full block validation. Output - inputs must result in 60 grin new supply when summing against the kernels.
The miner would want to validate that they are indeed the sole recipient of those 60 grin and the remaining txs sum to 0 as expected, taking fees into consideration.


As we have discussed in Keybase, only non-financially driven reorg attacks are essentially of the same effect regardless if coinbase maturity is implemented or not, as the attacker might want to erase a bunch of transactions in this case (think Nation state).

(1) is an issue regardless of coinbase maturity is essentially false, since double spends attacks historically only attacks a given transaction and keep included all the others. The reason being that the attacker has strictly no reason to screw up the blockchain to optimize his profit for his double spend.

If I wanted to insulate myself from this I would look at the number of confirmations, not of the output I received, but of all the outputs involved in the tx where I received my funds.
If you send me grin via (A, B, C) -> D and I want some level of confidence that my funds are not going to subsequently disappear then I need to be aware of the current number of confirmations on A, B, C (the source of my funds).
And @tromp has made a pretty good argument that you want to be doing this anyway when receiving large amounts of funds, regardless of coinbase maturity.

But yes - there is a difference in terms of “collateral damage”. With no coinbase maturity rule then all outputs descended from affected coinbase are subject to something analogous to a successful double spend attack within the reorg period.
With the coinbase maturity rule we have today the double spend fallout is limited to those outputs explicitly targeted for attack. At least that is my understanding.