bitcoin-inquisition repo:
https://github.com/Merkleize/bitcoin/tree/checkcontractverifyTherefore, it also includes OP_CHECKTEMPLATEVERIFY, as in a
previous early demo for vaults [3].
Please check out the diff [4] if you are interested in the
implementation details. It includes some basic functional tests for
the main cases of the opcode.
## Changes vs the previous draft
These are the changes compared to the initial incomplete proposal:
- OP_CHECK{IN,OUT}CONTRACTVERIFY are replaced by a single opcode
OP_CHECKCONTRACTVERIFY (CCV). An additional `flags` parameter allows
to specify if the opcode operates on an input or an output.
This also allows inspection of other inputs, that was not possible
with the original opcodes.
- For outputs, the default behavior is to have the following deferred
checks mechanism for amounts: all the inputs that have a CCV towards
the same output, have their input amounts summed, and that act as a
lower bound for that output's amount.
A flag can disable this behavior. [*]
- A number of special values of the parameters were defined in order
to optimize for common cases, and add some implicit introspection.
- The order of parameters is modified (particularly, <data> is at the
bottom of the arguments, as so is more natural when writing Scripts).
## Semantics
The new OP_CHECKCONTRACTVERIFY takes 5 parameters from the stack:
<data>, <index>, <pk>, <taptree>, <flags>
The core logic of the opcode is as follows:
"Check if the <index>-th input/output's scriptPubKey is a P2TR
whose public key is obtained from <pk>, (optionally) tweaked with
<data>, (optionally) tap-tweaked with <taptree>".
The following are special values of the parameters:
- if <pk> is empty, it is replaced with a fixed NUMS point. [**]
- if <pk> is -1, it is replaced with the current input's taproot
internal key.
- if <index> is -1, it is replaced with the current input's index.
- if <data> is empty, the data tweak is skipped.
- if <taptree> is empty, the taptweak is skipped.
- if <taptree> is -1, it is replaced with the current input's root
of the taproot merkle tree.
There are two defined flags:
- CCV_FLAG_CHECK_INPUT = 1: if present, <index> refers to an input;
otherwise, it refers to an output.
- CCV_FLAG_IGNORE_OUTPUT_AMOUNT = 2: only defined when _CHECK_INPUT
is absent, it disables the deferred checks logic for amounts.
Finally, if both the flags CCV_FLAG_CHECK_INPUT and
CCV_FLAG_IGNORE_OUTPUT_AMOUNT are absent:
- Add the current input's amount to the <index>-th output's bucket.
After the evaluation of all inputs, it is verified that each output's
amount is greater than or equal to the total amount in the bucket
if that output (validation of the deferred checks).
## Comment
It is unclear if all the special values above will be useful in
applications; however, as each special case requires very little added
code, I tried to make the specs as flexible as possible at this time.
With this new opcode, the full generality of MATT (including the fraud
proofs) can be obtained with just two opcodes: OP_CHECKCONTRACTVERIFY
and OP_CAT.
However, additional opcodes (and additional introspection) would
surely benefit some applications.
I look forward to your comments, and to start drafting a BIP proposal.