Merkleize/bitcoin

Implement `CTV_FLAG_DEDUCT_OUTPUT_AMOUNT`

Closed this issue · 1 comments

Idea: add a new flag to the current specs for OP_CHECKCONTRACTVERIFY used with outputs (so without CCV_FLAG_CHECK_INPUT):

Currently, there are only two possible behaviors defined for CCV for an output (that is, the when CCV_FLAG_CHECK_INPUT is not in the flags):

  • CCV_FLAG_IGNORE_OUTPUT_AMOUNT: no check on the amount
  • default: the output must account for the amount of the input; if multiple inputs have a CCV towards the same output (and without CCV_FLAG_IGNORE_OUTPUT_AMOUNT), the output' s amount must be at least equal to their sum

We can make the opcode more flexible by adding an additional flag: CCV_DEDUCT_OUTPUT_AMOUNT = 4 (incompatible with CCV_FLAG_IGNORE_OUTPUT_AMOUNT).

If present, then:

  • the amount of the output must be no less than the amount of the input.
  • the amount is subtracted from the input amount, and the difference is used for deferred checks if future calls to OP_CHECKCONTRACTVERIFY are performed in the same script.

To be defined: should the deducted amount persist across inputs, or only stored during the current input's evaluation? It does not seem to matter for the use cases I have in mind (vaults and CoinPools unilateral exits), so it might suffice to keep the semantics simpler and per-input.

Vaults

OP_VAULT allows to instantly "revault" part of the input amounts, so that it is available for spending without waiting for the timelock.

The current vault implementation here does not support this feature.
CCV_DEDUCT_OUTPUT_AMOUNT allows to implement this missing feature, allowing CCV-based vaults that are a drop-in replacement for OP_VAULT.

<0: skip data tweak>
<revault_output_index>
<-1: current internal key>
<-1: current taptree>
<CCV_DEDUCT_OUTPUT_AMOUNT> OP_CHECKCONTRACTVERIFY

<ctv_hash (coming from the witness)>
<unvaulting_output_index>
<unvaulting_output_pubkey (or NUMS)>
<unvaulting_output_taptree>
<0: default flags> OP_CHECKCONTRACTVERIFY

CoinPools

In protocols like CoinPools, it is necessary that a party is able to unilaterally withdraw from the pool, by subtracting their balance from the UTXO. CCV_DEDUCT_OUTPUT_AMOUNT would allow to support this use cases without worrying about 64-bit arithmetics in Script.

This was implemented.