Skip to content

Conversation

@tomt1664
Copy link
Member

@tomt1664 tomt1664 commented Dec 5, 2025

This ELIP describes a change to Elements that enabled the unblinded issuance of assets with a value greater than MAX_MONEY. The MAX_MONEY check is meant to ensure the total amount of pegged asset (i.e. Bitcoin) does not exceed 21 million, however it also prevents unblinded issuance of other assets that may exceed 21 million in value.

@apoelstra
Copy link
Member

Can youi clean up this PR's sequence of commits? Maybe that just means squashing everything.


===Abstract===

This document proposes a change to Elements to allow the unblinded issuance and reissuance of assets in amounts greater than the <code>MAX_MONEY</code> parameter (21 million) that is currently prevented. This is a hard-forking change, but can be safely released when combined with a new default policy config option that can prevent unblinded issuance transactions with amoutns greater than <code>MAX_MONEY</code> from being relayed and confirmed in blocks.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In f35d8c6:

that is currently prevented can be deleted.

typo amoutns

I don't buy the notion that it's "safe" to deploy a hardfork based on the belief that policy rules will prevent it triggering a chain fork. You should just say that we trust the functionaries not to split the chain until everybody has updated.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the comments.

Updated this to remove comment about safe deployment and clarified the functionaries responsibility.


===Motivation===

An important feature of the Elements platform is Confidential Assets, that enable any user to create tokens that represent external assets that can be transacted with strong privacy guarantees. Assets can be created in a special issuance transaction which also (optionally) creates a <code>reissuance_token</code> that enables additional issuances of the same original asset type. Both initial asset issuances and reissuances can be either blinded or unblinded, irrespective of whether further transfers of the asset are confidential. In a fully blinded issuance, the value (amount) of the issuance (and the reissuance token) remains hidden, however in an unblinded issuance (and reissuance) the amount of asset created is publicly verifiable. There are many situations where an unblinded issuance is needed, including for example transparency and legal requirements.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In f35d8c6:

nit: we use "Confidential Transactions" to refer to the amount/asset hiding and "Issued Assets" to refer to the ability to (re)issue assets. The term "Confidential Assets" is no longer used. In this case it looks like you mean to refer to CT.

Assets aren't created in a "special issuance transaction" but rather in any transaction whose input(s) have asset issuances attached.

The term "explicit" should be used in place of "unblinded".

You can reduced this paragraph and the next one to simply say that in Liquid, we limit asset issuances to MAX_MONEY, a requirement that was accidentally inherited from Bitcoin but which should not apply on Liquid to non-Bitcoin assets.

On the other hand, the motivation should explain why VerifyIssuanceAmount is special and why we don't need to remove the MoneyRange checks from the coinbase output checking, checking of output amounts and checking of fees.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated and reduced the length of the paragraphs.

MoneyRange still applies to explicit outputs, but the purpose of this ELIP is specifically to enable explicit issuances but assume that all further transfers can be confidential (which is default).
The fee (and total block fee) MoneyRange checks only apply if non-policy assets will be accepted for fees.


To enable the unblinded issuance and reissuance of assets other than the <code>pegged_asset</code> with values greater than <code>MAX_MONEY</code> (21 million) the <code>MoneyRange</code> check for explicit values in the <code>VerifyIssuanceAmount</code> consensus rule will be modified to only apply when the <code>asset</code> is <code>pegged_asset</code>.

To enable the inclusion of this consensus rule change in Elements releases without risking a network fork, a new policy rule preventing the unblinded issuance and reissuance of assets (and reissuance tokens) with values greater than <code>MAX_MONEY</code> before the the technical consensus hard fork is activated. This policy rule will be configurable but applied as default in all releases until the hard fork activation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In f35d8c6:

This is a confusing -- if the hardfork isn't activated then the policy rule is meaningless. I think by "the hardfork activation" you mean "the time when the policy rule is disabled" but that's tautological.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have changed this to state that functionaries will apply the policy until everyone upgrades.


In the function <code>VerifyIssuanceAmount</code> where <code>value</code> is explicit, the value is only checked for <code>MoneyRange(value)</code> when the <code>asset</code> is equal to the consensus parameter <code>pegged_asset</code>.

A new function <code>IsIssuanceInMoneyRange(tx)</code> returns true if a transaction has explicit issuance and reissuance values (and reissuance token values) are within <code>MoneyRange(value)</code>, otherwise false. This function is evaluated for transactions in <code>MemPoolAccept</code> if <code>fAcceptUnlimitedIssuances</code> is false. If this function returns false, the transaction is rejected with error message: <code>"issuance-out-of-range""</code>.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In f35d8c6:

Typo ""

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

https://github.com/ElementsProject/elements/pull/1445
https://github.com/ElementsProject/elements/pull/1507

==Test Vectors==
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In f35d8c6:

I get the motiation for these test vectors but in practice all nodes will reject all of these due to missing inputs. (And if you construct transactions that would be accepted then some joker will broadcast them and then they'll stop working.)

Maybe we still want to retain them, but we should provide instructions for using them.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updating these with instructions on how to set-up and use on regtest. Will push this later today.

@apoelstra
Copy link
Member

Done reviewing f35d8c6. I may be able to review this one again tomorrow or Wednesday since it's pretty short. Otherwise I will not be available until May.

@tomt1664 tomt1664 force-pushed the elip-21mil branch 2 times, most recently from b3cb89f to 4695cd7 Compare December 23, 2025 18:23
@apoelstra
Copy link
Member

ACK 4695cd7

You can have ELIP number 203.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants