[dlc-dev] SIGHASH_ANYPREVOUT allows significant improvement in DLC transferability

Nadav Kohen nadavk25 at gmail.com
Thu Feb 24 23:14:40 CET 2022


Hi Swetark!

Thanks for the proposal, I'm always happy to see people thinking about ways
to improve DLC transferability, especially in the realm of reducing the
interactivity necessary! Here are my thoughts on your proposal.

The first thing I noticed is that you are using the old
Pay to `(Person j + Oracle) || (Person i & OP_CLTV)`
scheme which we've replaced with adaptor signatures to reduce complexity
and remove asymmetry between transactions signed by the parties involved, I
believe that this optimization also applies here and that the
implementation complexity of this scheme would be reduced through the use
of adaptor signatures.

My other concrete thought is that as it is currently proposed, it is
assumed that the party transferring into the DLC is always going to be
providing inputs and paying a premium but this should not be assumed, since
often times one would like to sell out of a DLC position after it has
become less valuable and one is willing to pay someone else to take the
position. In particular something more than simply making who adds an input
a variable is needed as is mentioned in security concern #1, if the person
currently in the DLC is paying to leave then they can extract a free option
(as it currently stands) from the person they are allegedly paying to take
their position. This likely requires that the handshake for transfers (in
terms of signatures) always ends with the person who has a new input on the
transformation transaction, which shouldn't be too hard to implement but is
important.

As for less concrete concerns, my current understanding is that the
proposal is essentially a big pre-computation scheme where every party that
might ever be involved in a DLC has to do a full setup of the DLC (in terms
of how much computation is needed) with every other party that might be in
the DLC, along with pre-signing every possible transfer between every
possible other two parties (the third being themselves). Assuming my
understanding is correct, then I think there are a few places where this
scheme really is interesting, namely if a single person wishes to enter
into a DLC, they don't care who with, and there exists some fixed group of
counterparty market makers. In this case this scheme could be practical for
sufficiently small contracts, or sufficiently patient users. But at the end
of the day, I am not seeing how this scheme can be used practically for P2P
novation, simply because the communication and computational complexity
seem quite large, the parties must all be known in advance, and the DLC
must remain static between transfers which likely leads to quite a bit of
capital inefficiency relative to other proposals for DLC transfers [1]
(although these require the static party to be online to authorize
transfers). As such, I think that this proposal has many interesting
applications for B2B interactions between DLC service entities, but that
the costs outweigh the non-interactivity benefits for generic P2P DLC
applications relative to the existing interactive transfer scheme (but who
knows, P2P may only constitute a minority of DLCs in the future).

One last higher level concern I have is that, as it is currently
constructed, I worry that the primary benefit of using DLCs over federated
escrows [2], privacy (especially from the oracle), is at risk of being lost
in the presence of such transfers; and it should be noted that in escrow
schemes transfers of the kind being achieved here are trivially
accomplished using the escrows to enforce contract rules if the static
party is offline. This privacy loss comes in two main forms (as far as I
can tell), one is that the transformation transactions form a chain of
easily recognizable transactions which can leak a lot of information since
they come with an obviously distinguishable output representing a premium
paid for the transfer, and if there are multiple transfers this along with
the final payout (and its timestamp, and all timelocks) can leak a lot of
information about the contract terms. Furthermore, aside from the public
footprint, all parties which may participate in the future are privy to the
entire contract details from the beginning which allows oracles and
surveillance organizations to simply be a member of these large pools (or
buy data from any single participant) in order to gain full access to the
DLC terms. This seems like a pretty major drawback which might be able to
at least be partially mitigated, at least enough to make the use of the
proposal preferable to simply using escrows in place of DLCs.

Please do let me know if I've misinterpreted your proposal in any part, and
I'm excited to follow your future work!

Best,
Nadav

On Mon, Feb 14, 2022 at 5:48 PM Shwetark Patel via dlc-dev <
dlc-dev at mailmanlists.org> wrote:

> # Intro to Transformable Discreet Log Contracts
>
> ## Introduction
>
> Discreet Log contracts are interesting, but one of the key issues is that
> they lock the two participants into the contract and do not allow for
> mutability, unless both participants are online, agree, and are willing to
> allow another participant into the contract. One of our key goals is to
> allow transferability of DLCs only requiring the person swapping in and the
> person swapping out to be online.
>
> ## Goals and Assumptions
> The assumption is very simple: There is a set of `N` participants whose
> public keys are known.
>
>
> The goal is essentially to simulate futures contract trading on Bitcoin;
> at the beginning, the DLC will be between two predetermined participants
> (WLOG say participants `0` and `1`). After that, the futures contract can
> be constantly traded between participants by one person swapping out and
> another swapping in, without interaction of the person staying in the
> contract. It is even possible to create cycles where we come back to the
> original two participants; for example, the following interaction is
> possible:
>
> 1. Persons [0, 1] are the original two participants.
>
> 2. Person 0 swaps out and Person 2 swaps in (In exchange for some amount
> of monetary transfer from Person 2 to Person 0), leading to Persons [1, 2]
> being the new participants.
>
> 3. Person 1 swaps out and Person 0 swaps in (In exchange for some amount
> of monetary transfer from Person 0 to Person 1), leading to Persons [0, 2]
> being the new participants.
>
> 4. Person 2 swaps out and Person 1 swaps in (In exchange for some amount
> of monetary transfer from Person 1 to Person 2), leading to Persons [0, 1]
> being the new participants. Notice that they were also the original
> participants in the contract.
>
> It is important to note that the contract does not have to end with the
> original two participants having control of the contract; in fact, in the
> above, if we just ended the process after step 3 where Persons [0, 2] have
> control over the contract, they would still be able to settle and get their
> money out.
>
> Another important detail is that the contract must have some type of
> expiration date (like a futures contract does) so that the DLC can be
> settled at some point.
>
>
> ## Signing
> We need to do some signing initially (just like regular DLCs require us to
> sign CETs before we put the funding transaction on chain). We have to sign
> two types of transactions here:
>
> ### Transformation Transactions
>
> For this part, we use `SIGHASH_ANYPREVOUT | ANYONECANPAY | SINGLE` to sign
> off on the spending condition and amount of the 0th input and the entire
> 0th output.
>
>
> For every pairwise distinct, unordered triple of people `(i, j, k)`,
> person `i` must sign the following transaction using `SIGHASH_ANYPREVOUT |
> ANYONECANPAY | SINGLE`:
>
> ---------------------------------------------------------------
>
> Input 0 script pubKey (well it's the script pubKey of the previous output
> to be more precise..): (Person `i & j` multi-sig)
>
> Input 0 amount: Same as funding TX amount
>
> ---------------------------------------------------------------
>
> Output 0 script pubKey: (Person `i & k` multi-sig)
>
> Output 0 amount: Same as funding TX amount
>
> ---------------------------------------------------------------
>
> The total number of transactions created here is `O(N^3)` (where `N` is
> the number of people).
>
> ### CETs
>
> For every pairwise distinct, unordered pair of people `(i, j)` and every
> oracle outcome, person `i` must sign the following transaction using
> `SIGHASH_ANYPREVOUT`:
>
> ---------------------------------------------------------------
>
> Input 0 script pubKey: (Person `i & j` multi-sig)
>
> Input 0 amount: Same as funding TX amount
>
> ---------------------------------------------------------------
>
> Output 0: Pay to Person `i`'s PKH (amount based on oracle outcome)
>
> ---------------------------------------------------------------
>
> Output 1: Pay to `(Person j + Oracle) || (Person i & OP_CLTV)` (amount
> based on oracle outcome)
>
> ---------------------------------------------------------------
>
> A minor detail here is that these CETs should have timelocks on them so
> they are only valid after the expiration date (this prevents someone from
> just putting a CET on chain if they are sure of the oracle outcome and
> preventing future transformation transactions).
>
> The total number of transactions created here is `O(N^2 * O)` (where `N`
> is the number of people and `O` is the number of outcomes).
>
> ## Put Funding TX on chain
>
> The next step is to create a single initial DLC funding transaction
> between two arbitrary parties (WLOG let's say Persons `0` and `1`) and put
> it on chain.
>
> ## Creating Transformation Transactions
>
> Let's say Persons `i` and `j` are currently in the contract (which implies
> a multisig between two exists at the moment). Let's say that person `j`
> wants to swap out and person `k` wants to swap in; in this case, both
> person `j` and `k` need to be online and interact, but person `i` does not
> need to be there. Person `j` and `k` will construct the following
> transaction:
>
> ---------------------------------------------------------------
>
> Input 0 script pubKey: (Person `i & j` multi-sig)
>
> Input 0 amount: Same as funding TX amount
>
> ---------------------------------------------------------------
>
> Input 1: Any UTXO spendable by Person `k`
>
> ---------------------------------------------------------------
>
> Output 0 script pubKey: (Person `i & k` multi-sig)
>
> Output 0 amount: Same as funding TX amount
>
> ---------------------------------------------------------------
>
> Output 1: Some agreed upon amount is sent to Person `j`'s PKH.
>
> ---------------------------------------------------------------
>
>
> Person `k` will then insert in Person `i`'s relevant Transformation
> Transaction signature (during the signing phase, Person `i` already created
> and published this signature) and sign themselves. They will then send the
> signed transaction to Person `j`, who can then sign and send the
> transaction into the mempool.
>
> Any number of these transformation transactions can be put on chain, one
> after another. As a result, ownership of the contract can constantly change.
>
> ## Final CET
>
> Once the final expiration time is reached, the oracle publishes the
> outcome and a CET can be put on chain by either party. WLOG assume that
> persons `i` and `j` are currently in the contract. Let's say that person
> `j` wants to be the one to publish the final settlement transaction. Person
> `j` will create and sign the following transaction:
>
> ---------------------------------------------------------------
>
> Input 0 script pubKey: (Person `i & j` multi-sig)
>
> Input 0 amount: Same as funding TX amount
>
> ---------------------------------------------------------------
>
> Output 0: Pay to Person `i`'s PKH (amount based on oracle outcome)
>
> Output 1: Pay to `(Person j + Oracle) || (Person i & OP_CLTV)` (amount
> based on oracle outcome)
>
> ---------------------------------------------------------------
>
> They will use Person `i`'s signature which already exists from the signing
> phase to complete the transaction. They will then send this to the mempool.
>
> ## Security Considerations
>
>
> There exist at least two interesting security considerations:
>
> 1. Say Person `i` and `j` are currently in the contract, and `k` wants to
> swap in for `j`. Person `k` signs a transformation transaction and sends it
> to `j`. Person `j` can now wait a while before they send the transaction
> into the mempool (to see if it is advantageous to do so). Person `k` has
> the option to respond to this by spending the UTXO they are using as an
> input,  but it could become some type of priority gas auction if they try
> to do this simultaneously.
>
> 2. Say the expiration time has passed, and someone wants to be a sore
> loser. They can keep sending transformation transactions to prevent a CET
> from being put on chain. The deterrent here is that they literally have to
> do this every single block and they lose the transaction fee, which adds up
> to pretty significant sums of money. This only delays the inevitable,
> however, because at some point the CET will be put on chain and everything
> will be settled.
>
> Would be interested if anyone has thoughts on this.
>
> dlc-dev mailing list
> dlc-dev at mailmanlists.org
> https://mailmanlists.org/mailman/listinfo/dlc-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailmanlists.org/pipermail/dlc-dev/attachments/20220224/42862fd6/attachment-0001.htm>


More information about the dlc-dev mailing list