[dlc-dev] SIGHASH_ANYPREVOUT allows significant improvement in DLC transferability
Richard Myers
remyers at yakshaver.org
Sat Feb 26 09:44:11 CET 2022
Hi Nadav,
Thanks for sharing your analysis of Swetark's proposal. I believe it's interesting to explore what design space opens up for both transferable and non-transferable DLCs with APO.
Could you share the links you were referring to with "other proposals for DLC transfers [1]" and "benefit of using DLCs over federated escrows [2]" ?
I have been wondering if the eltoo system for replacing transactions off chain might be applied to DLCs. Others have pointed out how using APO you can avoid recomputing the CET everytime a lightning channel (and the CET's prevout) changes.
Swetark's scheme also made me wonder if channel factories[1] could be useful here. A multi party channel manages a set of 2:2 sub-channels between members of the federated group. Off chain changes to the set of 2:2 sub-channels requires n:n to sign, but the 2:2 sub-channels can be dropped to chain and settled individually when the federation settles the entire multi party channel. The federated channel might be settled with a pre-signed timeout transaction and/or when one of the n:n becomes unresponsive.
Perhaps a channel factory that settles automatically at contract expiry is a good model. As long as the federation members sign updates periodically then individual 2:2 contracts can be exchanged off chain between members, but either way the last state of 2:2 contracts and CET outputs will settle on chain at contract expiry.
-- Richard
[1] https://bitcoinops.org/en/topics/channel-factories
-------- Original Message --------
>> 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/20220226/2aa66a47/attachment-0001.htm>
More information about the dlc-dev
mailing list