Hi Devs,
Recently, I've been getting a lot of questions about OP_AMOUNT. It's also come up in the context of "CTV is unsafe because it can't handle differing amounts". Just sharing some preliminary thinking on it:
It could come in many variants:
OP_PUSHAMOUNT
OP_AMOUNTVERIFY
OP_PUSHAMOUNTSPLIT
OP_SPLITAMOUNTVERIFY
If we want to do a NOP upgrade, we may prefer the *VERIFY formats. If we want to do a SUCCESSX upgrade, we could do the PUSH format.
The SplitAmount format is required because amounts are > 5 bytes (51 bits needed max), unless we also do some sort of OP_UPGRADEMATH semantic whereby presence of an Amount opcode enables 64 bit (or 256 bit?) math opcodes.
And could be applied to the cross product of:
The Transaction
An Input
An Output
The fees total
The fees this input - this output
This Input
"This" Output
A lot of choices! The simplest version of it just being just this input, and no other (all that is required for many useful cases, e.g. single sig if less than 1 btc).
There are some decent use cases for amount checking.
For instance, one could create a non-recursive covenant that there must be an output which exactly matches the sats in the input at the same index. This could be used for colored coins, statechains, TLUV/EVICT based payment pools, etc.
Another use case could be to make a static address / descriptor that disables low security spends if more coins are the input.
Yet another could be to enable pay-what-you-want options, where depending on how much gets paid into an address different behaviors are permitted.
Lastly, as noted in BIP-119, you can make a belt-and-suspenders value check in CTV contracts to enable a backup withdrawal should you send the wrong amount to a vault.
Overall, I think the most straightforward path would be to work on this only for tapscript, no legacy, and then spec out upgraded math operations, and then OP_PUSHAMOUNT is pretty straightforward & low technical risk. Unfortunately, the upgraded math and exact semantics are highly bikesheddable... If anyone is interested in working on this, I'd be happy to review/advise on it. Otherwise, I would likely start working on this sometime after I'm spending less effort on CTV.
Blockstream liquid has some work in this regard that may be copyable for the math part, but likely not the amount opcode:
https://github.com/ElementsProject/elements/blob/master/doc/tapscript_opcodes.md However, they chose to do only 64 bit arithmetic and I personally think that the community might prefer wider operations, the difficulty being in not incidentally enabling OP_CAT as a size, bitshift, and add fragment (or proving that OP_CAT is OK?).
Cheers,
Jeremy