Hi list, In this post, I'm digging on OP_CHECKCONTRACTVERIFY (OP_BIP 443) and how it can be leveraged to design UTXO-sharing schemes like CoinPool, and the limits of the primitive in this regard. ### CoinPool: Main Operations In this section, I'm reminding the main operations of a coinpool (for more in-depth reminders, see [0], [1], [2]). Basically, a coinpool is a multi-party construction designed to improve the onboarding and transactional scaling of bitcoin users by orders of magnitude. To work in an efficient way, it requires some consensus changes, e.g a TAPROOT_LEAF_UPDATE_VERIFY or OP_MERKLE_SUB [3] (the primitive matters less than the level of expressivity brought by the primitive). A coinpool instance is defined by a set of public keys and the associated balances, which are debited and credited during pool operation. State is maintained by an on-chain UTXO and a set of pre-signed transactions encoding the users' balances. Off-chain transfers between pool accounts require replacing old pre-signed txn and all the pool participants have to approve. Once the off-chain pool state has hit the chain, all the users can recursively and non-interactively withdraw their funds, one by one. This recursive update of the state pool is the mechanism on which to draw attention in the present post, and especially in which measure it can be (imperfectly) reproduced with OP_CHECKCONTRACTVERIFY. Let's say you have a pool of four (A,B,C,D) [4] Funding UTXO script is a multisig of ABCD. Each update transaction has a Eltoo-encoded nLockime. In the output of each update transaction, each participant with a balance has an exit path. Any withdraw transaction can consume an update tx exit path. The MERKLESUB (or TLUV) ensure that the withdraw output is the similar script with 3 modifications: - the withdrawing participant balance has been subtracted from the pool balance amount - the withdrawing participant point has been subtracted from the curve point constituting the internal point - the withdrawing participant script has been subtracted from the tree of scripts This mechanism allows the participants to withdraw from the update tx output in any-order, i.e without having to know at setup who is the first that is going to exit the off-chain construction. This is ensuring reasonable fault-tolerance of the construction, where one bad party cannot force a massive on-chain footprint, of which the cost would be burden by all the pool participants (and the chain txn logs be unnecessarily inflated). ### A CoinPool built with OP_CCV The proposed opocode OP_CHECKCONTRACTVERIFY, in my understanding, works in the following way. When evaluating an OP_CCV, the interpreter is excpecting 5 elements on the stack: - : the selected verification mode - : the tweaked taptree - : the verified naked key - : the verified input or output index - : a buffer of arbitrary data length By selecting the accurate mode (i.e `CCV_MODE_CHECK_OUTPUT`), one can ensure that an output is encumbered by an expected taptree and an expected internal public key. The output amount and its update can be selected with the combinatory `CCV_MODE_CHECK_OUTPUT_DEDUCT_AMOUNT`. Going back to CoinPool design, any order recursive mechanism for the withdrawals can be implemented with CCV in the following way. At each update tx, the participants builts a withdraw tx for each participant and multi-sign it. The output in the update has all the branches of the `taptree`. When a pool participant wishes to withdraw, it gives the `updated_taptree` in the witness of the withdraw transaction as a CCV argument. The multi-signature ensures that the pre-image `update_taptree` matches the expected withdraw output. The multi-signature can also ensure the amount matches the off-chain balance. However, this approach is limited for one step, as otherwise the pool participant would have to generate a withdraw tx for each combination. While this workable for small sized pool, this is a practical exponential limit for a high number of participants (from previous measures around the 11th or 12th participant). ## Open Design Questions This is an open design question if CCV can be combined with other opcodes, where introspection would be done on the argument to deduce from it what should be the triplet (pubkey, tree, amount) for the withdraw tx output based on the input state. From laying out the question, there are 2 obvious observations for the bitcoin script experts (a) if this hypothetical introspection phase can be rendered unforgeable by any of the participant to the pool and (b) if a contrario a templated approach a la MERKLESUB and OP_TLUV is not more efficient witness space wise. This short analysis is limited to the usage of OP_CCV for the precise case of UTXO-sharing like CoinPool, and its design trade-offs might be more fruitful and is more adapted for other use-cases. Cheers, Antoine OTS hash: 15a8f04022265a0258e51ca54d98285bc9e33df0342f5700cd91e750febbe4de [0] https://gnusha.org/pi/bitcoindev/CALZpt+FqAWCAqCLF2HsajL84sOvst_X9_34bb_tvUxLFw=HTAA@mail.gmail.com/ [1] https://gnusha.org/pi/bitcoindev/CALZpt+E+eKKtOXd-8A6oThw-1i5cJ4h12TuG8tnWswqbfAnRdA@mail.gmail.com/ [2] https://github.com/ariard/coinpool-gitbook/blob/master/coinpool-v0.1.pdf [3] https://gnusha.org/pi/bitcoindev/20210909064138.GA22496@erisian.com.au/ [4] https://gist.github.com/ariard/713ce396281163337c175d9122163e8f -- You received this message because you are subscribed to the Google Groups "Bitcoin Development Mailing List" group. To unsubscribe from this group and stop receiving emails from it, send an email to bitcoindev+unsubscribe@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/bitcoindev/CALZpt%2BFfC6hnN1i32OJVJ-VKvg0Z%3DtbpNB-97ZZ_7TMaLj8E9g%40mail.gmail.com.