Return-Path: Received: from smtp3.osuosl.org (smtp3.osuosl.org [IPv6:2605:bc80:3010::136]) by lists.linuxfoundation.org (Postfix) with ESMTP id 62523C0001 for ; Wed, 10 Mar 2021 23:55:59 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp3.osuosl.org (Postfix) with ESMTP id 41E5B605F7 for ; Wed, 10 Mar 2021 23:55:59 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org X-Spam-Flag: NO X-Spam-Score: -4.197 X-Spam-Level: X-Spam-Status: No, score=-4.197 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no Received: from smtp3.osuosl.org ([127.0.0.1]) by localhost (smtp3.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VvwX15Uy_mar for ; Wed, 10 Mar 2021 23:55:57 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) by smtp3.osuosl.org (Postfix) with ESMTPS id 9AE47605F5 for ; Wed, 10 Mar 2021 23:55:57 +0000 (UTC) Received: from mail-io1-f48.google.com (mail-io1-f48.google.com [209.85.166.48]) (authenticated bits=0) (User authenticated as jlrubin@ATHENA.MIT.EDU) by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 12ANttqb028863 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NOT) for ; Wed, 10 Mar 2021 18:55:56 -0500 Received: by mail-io1-f48.google.com with SMTP id o9so19963615iow.6 for ; Wed, 10 Mar 2021 15:55:55 -0800 (PST) X-Gm-Message-State: AOAM531zEyJHLOG5m1XFlzeRiBAwPbX+js/QTt02b0oh8AKnOb5CjFQC YeahNOA6+GNnhEGxhiqDgJCMzQhyny3mN9hYUSQ= X-Google-Smtp-Source: ABdhPJyOfMU04Y+CZhCODS8O1t+mgw485iYXTceDKxC9bQH92x0DOrvrEPTCvUP7vTY1wSh3fYp1NEm8AsH3nbrep9c= X-Received: by 2002:a05:6602:1592:: with SMTP id e18mr4038780iow.49.1615420554772; Wed, 10 Mar 2021 15:55:54 -0800 (PST) MIME-Version: 1.0 From: Jeremy Date: Wed, 10 Mar 2021 15:55:43 -0800 X-Gmail-Original-Message-ID: Message-ID: To: Bitcoin development mailing list Content-Type: multipart/alternative; boundary="00000000000054881805bd3768d5" Subject: [bitcoin-dev] Delegated signatures in Bitcoin within existing rules, no fork required X-BeenThere: bitcoin-dev@lists.linuxfoundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Bitcoin Protocol Discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Mar 2021 23:55:59 -0000 --00000000000054881805bd3768d5 Content-Type: text/plain; charset="UTF-8" I'm aware that some folks (I think nullc, sipa, myself... maybe more?) are aware of how to do script delegation in Bitcoin today (without any modifications to Bitcoin), but realized in a conversation with Andrew P that the technique is not widely known. So I figured it made sense to do a brief explainer of how this works for the archives / so the technique is documented. If someone has other citations for this, please respond below. If you like cartoons follow along here: https://docs.google.com/presentation/d/1ikcthy3p-Ah59pJyss0TLEj-Q2FF6tv7BXhkORzErAE/edit#slide=id.p Technically what we are doing is delegating a UTXO to a specific UTXO, and not to a script. Suppose you have a coin on UTXO A. You would like to delegate it to script S. You can either scan the chain for any UTXOs bound to S or use some arbitrary coin B to create a transaction X with an output D that has script S (doesn't have to have any value, but let's say it has a nominal amount to avoid dust issues). Because tx X is not malleable, we don't need to actually broadcast it and spend B till we want to use the delegation, and it can be created (for the TXID) without B's owner being online. However you get the UTXO, and if it exists or not yet, let's call it D. *Note: if you're using a delegation script multiple times, you can optimize the creation step a bit* Now, using A, you sign a transaction with 2 inputs (one of them being D) and SIGHASH_NONE. This signs all of the inputs (but not their sequences!) but none of the outputs. Let's call this transaction stub G. Now, using S, you sign D's input on G with SIGHASH_ALL and the outputs you want to create (whatever they may be). Let's call the finished transaction F. Effectively, the holder of A has delegated the control of their coin to a specific instance of the script S. Once delegated, S may authorize almost any transaction they want (complicated if they want to sign a multiple input transaction; but there are good substitutes). Advanced Topics: *Revocation*: There are multiple ways to revoke, either moving A, moving D, refusing to sign and create D (when D is derived from B), etc. Because these are UTXO-bound they are revocable. (the cartoon may help here) *Cross input delegation*: A set of N coins may create a sighash_none transaction with 1 additional input for the delegating script *Partial Spending Authorizations*: Replacing sighash_none with sighash_single allows an input to specify a single change address (plug -- OP_CTV covenants can be thought of as a way to get around sighash_single to allow sighash_single to cover signing a set of outputs) *Delegation after time*: Because the lock_time field is covered, delegations can be set up to only be valid at some point in the future. Only a single sequence lock per delegated coin may be used directly. *Multiple Delegates: *By signing a txn with several delegate outputs, it is possible to enforce multiple disparate conditions. Normally this is superfluous -- why not just concatenate S1 and S2? The answer is that you may have S1 require a relative height lock and S2 require a relative time lock (this was one of the mechanisms investigated for powswap.com). *Sequenced Contingent Delegation*: By constructing a specific TXID that may delegate the coins, you can make a coin's delegation contingent on some other contract reaching a specific state. For example, suppose I had a contract that had 100 different possible end states, all with fixed outpoints at the end. I could delegate coins in different arrangements to be claimable only if the contract reaches that state. Note that such a model requires some level of coordination between the main and observing contract as each Coin delegate can only be claimed one time. *CTV Specific P2SH Non Coin Delegation: *OP_CTV allows for a similar form of delegation where by a Segwit P2SH address, as a part of the CTV committed data, can be used without binding it to any specific UTXO. With the addition of OP_CAT, it would be possible to both programmatically change the outputs (rather than just approving the fixed txn) and to dynamically select the script. *Redelegating: *This is where A delegates to S, S delegates to S'. This type of mechanism most likely requires the coin to be moved on-chain to the script (A OR S or S'), but the on-chain movement may be delayed (via presigned transactions) until S' actually wants to do something with the coin. There are obviously many other things you can do with delegation in general, the above are specific to how coin delegation is done. I'm probably missing some of the fun stuff -- please riff on this! Best, Jeremy -- @JeremyRubin --00000000000054881805bd3768d5 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
I'm aware that some folks (I think nullc, sipa, myself... maybe more?) are=20 aware of how to do script delegation in Bitcoin today (without any=20 modifications to Bitcoin), but realized in a conversation with Andrew P=20 that the technique is not widely known. So I figured it made sense to do a brief explainer of how this works for the archives / so the technique is documented. If someone has other citations for this, please respond=20 below.

If you like cartoons follow along here:


Technically what we are doing is delegating a UTXO to a specific UTXO, a= nd not to a script.


Suppose you have a coin on UTXO A. You would like to delegate it to script S.=20 You can either scan the chain for any UTXOs bound to S or use some=20 arbitrary coin B to create a transaction X with an output D that has=20 script S (doesn't have to have any value, but let's say it has a no= minal amount to avoid dust issues). Because tx X is not malleable, we don't= =20 need to actually broadcast it and spend B till we want to use the=20 delegation, and it can be created (for the TXID) without B's owner bein= g online. However you get the UTXO, and if it exists or not yet, let's= =20 call it D.

Note: if you're using a delegation script= multiple times, you can optimize the creation step a bit

Now, using A, you sign a transaction with 2 inputs (one of them being D) and SIGHASH_NONE. This signs all of the inputs (but not their sequences!)=20 but none of the outputs. Let's call this transaction stub G.
<= div style=3D"font-family:arial,helvetica,sans-serif;font-size:small;color:r= gb(0,0,0)" class=3D"gmail_default">
Now, using S, you sign D's input on G with SIGHASH_ALL and the outputs you= =20 want to create (whatever they may be). Let's call the finished=20 transaction F.

Effectively, the holder of A has delegated the control of their coin to a specific=20 instance of the script S. Once delegated, S may authorize almost any=20 transaction they want (complicated if they want to sign a multiple input transaction; but there are good substitutes).

Advanced Topics:=

Revocation: There are multiple ways to revoke, either moving A, moving D, refusing=20 to sign and create D (when D is derived from B), etc. Because these are=20 UTXO-bound they are revocable. (the cartoon may help here)
Cross input delegation: A set of N coins m= ay create a sighash_none transaction with 1 additional input for the delega= ting script
Partial Spending Au= thorizations: Replacing sighash_none with sighash_single allows an input to specify a single change address (plug -- OP_CTV covenants can be thought of as a=20 way to get around sighash_single to allow sighash_single to cover=20 signing a set of outputs)
Deleg= ation after time: Because the lock_time field is covered, delegations can be set up to=20 only be valid at some point in the future. Only a single sequence lock=20 per delegated coin may be used directly.
Multiple Delegates: By signing a txn with several delegate outputs, it is possible to enforce=20 multiple disparate conditions. Normally this is superfluous -- why not=20 just concatenate S1 and S2? The answer is that you may have S1 require a relative height lock and S2 require a relative time lock (this was one=20 of the mechanisms investigated for powswap.com).
Sequ= enced Contingent Delegation: By constructing a specific TXID that may delegate the coins, you can=20 make a coin's delegation contingent on some other contract reaching a= =20 specific state. For example, suppose I had a contract that had 100=20 different possible end states, all with fixed outpoints at the end. I=20 could delegate coins in different arrangements to be claimable only if=20 the contract reaches that state. Note that such a model requires some=20 level of coordination between the main and observing contract as each=20 Coin delegate can only be claimed one time.
CTV Specific P2SH Non Coin Delegation: OP_CTV allows for a similar form of delegation where by a Segwit P2SH address, as a part of the CTV committed data, can be used without binding it to=20 any specific UTXO. With the addition of OP_CAT, it would be possible to=20 both programmatically change the outputs (rather than just approving the fixed txn) and to dynamically select the script.
Redelegating: This is where A delegates to S, S delegates to S'. This type of mechanism= =20 most likely requires the coin to be moved on-chain to the script (A OR S or S'), but the on-chain movement may be delayed (via presigned=20 transactions) until S' actually wants to do something with the coin.

There are obviously many other things you can do with delegation in general,=20 the above are specific to how coin delegation is done. I'm probably=20 missing some of the fun stuff -- please riff on this!

Bes= t,

Jeremy

--00000000000054881805bd3768d5--