Hi Salvatore,

This also allows inspection of other inputs, that was not possible with the original opcodes.

I think cross-input inspection (not cross-input signature aggregation which is different) is opening a pandora box in terms of "malicious" off-chain contracts than one could design. E.g miners bribing contracts to censor the confirmation of time-sensitive lightning channel transactions, where the bribes are paid on the hashrate distribution of miners during the previous difficulty period, thanks to the coinbase pubkey.

See https://blog.bitmex.com/txwithhold-smart-contracts/ and https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-February/021395.html

I wonder if we might face the dilemma of miners censorship attacks, if we wish to have more advanced bitcoin contracts, though I think it would be safe design practice to rule out those types of concerns thanks to smart bitcoin contracting primitives.

I think this is a common risk to all second-layers vaults, lightning channels and payment pools.

> A flag can disable this behavior"

More than a binary flag like a matrix could be introduced to encode subset of introspected inputs /outputs to enable sighash_group-like semantic:
https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2021-July/019243.html

> 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.

Or even beyond a matrix, it could be a set of "tags". There could be a generalized tag for unstructured data, and another one for bitcoin transaction / script data types (e.g scriptpubkey, amount, nsequence, merkle branch) that could be fetched from the taproot annex.

> 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).

At the very least, I think for the payment pool, where you're fanning-out satoshis value from a subset of inputs to another subset of outputs, I think you would need more malleability here.

> 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.

I think this generic framework is interesting for joinpool / coinpool / payment pool, as you can check that any withdrawal output can be committed as part of the input scriptpubkey, and spend it on blessed-with-one-participant-sig script. There is still a big open question if it's efficient in terms of witness space consumed.

That said, I still think you would need at least ANYPREVOUT and more malleability for the amount transfer validation as laid out above.

Looking on the `DeferredCheck` framework commit, one obvious low-level concern is the DoS risk for full-nodes participating in transaction-relay, and that maybe policy rules should be introduced to keep the worst-CPU input in the ranges of current transaction spend allowed to propagate on the network today.

Thanks for the proposal,

Best,
Antoine



Le dim. 30 juil. 2023 à 22:52, Salvatore Ingala via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> a écrit :
Hi all,

I have put together a first complete proposal for the core opcodes of
MATT [1][2].
The changes make the opcode functionally complete, and the
implementation is revised and improved.

The code is implemented in the following fork of the
bitcoin-inquisition repo:

https://github.com/Merkleize/bitcoin/tree/checkcontractverify

Therefore, 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.

Best,
Salvatore Ingala


[*] - Credits go to James O'Beirne for this approach, taken from his
      OP_VAULT proposal. I cherry-picked the commit containing the
      Deferred Checks framework.
[**] - The same NUMS point suggested in BIP-0341 was used.


References:

[1] - https://merkle.fun/
[2] - https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-November/021182.html
[3] - https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2023-April/021588.html
[4] - https://github.com/bitcoin-inquisition/bitcoin/compare/24.0...Merkleize:bitcoin:checkcontractverify
_______________________________________________
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev