Implementing Covenants with OP_CHECKSIGFROMSTACKVERIFY
8 messages, 2 to 7 Nov 2016. Started by Russell O'Connor.
Russell O'Connor (3), Johnson Lau, Dan Robinson, Ryan Grant, Tim Ruffing, Jeremy Rubin
Hi all,
It is possible to implement covenants using two script extensions: OP_CAT and OP_CHECKSIGFROMSTACKVERIFY. Both of these op codes are already available in the Elements Alpha sidechain, so it is possible to construct covenants in Elements Alpha today. I have detailed how the construction works in a blog post at < https://blockstream.com/2016/11/02/covenants-in-elements-alpha.html>. As an example, I've constructed scripts for the Moeser-Eyal-Sirer vault.
I'm interested in collecting and implementing other useful covenants, so if people have ideas, please post them.
If there are any questions, I'd be happy to answer.
Interesting. I have implemented OP_CHECKSIGFROMSTACKVERIFY in a different way from the Elements. Instead of hashing the data on stack, I directly put the 32 byte hash to the stack. This should be more flexible as not every system are using double-SHA256
https://github.com/jl2012/bitcoin/commits/mast_v3_master <https://github.com/jl2012/bitcoin/commits/mast_v3_master>
Quoted text (16 lines)
> On 3 Nov 2016, at 01:30, Russell O'Connor via bitcoin-dev <bitcoin-dev@lists•linuxfoundation•org <mailto:bitcoin-dev@lists.linuxfoundation.org>> wrote: > > Hi all, > > It is possible to implement covenants using two script extensions: OP_CAT and OP_CHECKSIGFROMSTACKVERIFY. Both of these op codes are already available in the Elements Alpha sidechain, so it is possible to construct covenants in Elements Alpha today. I have detailed how the construction works in a blog post at <https://blockstream.com/2016/11/02/covenants-in-elements-alpha.html <https://blockstream.com/2016/11/02/covenants-in-elements-alpha.html>>. As an example, I've constructed scripts for the Moeser-Eyal-Sirer vault. > > I'm interested in collecting and implementing other useful covenants, so if people have ideas, please post them. > > If there are any questions, I'd be happy to answer. > > -- > Russell O'Connor > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists•linuxfoundation•org <mailto:bitcoin-dev@lists.linuxfoundation.org> > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
Right. There are minor trade-offs to be made with regards to that design point of OP_CHECKSIGFROMSTACKVERIFY. Fortunately this covenant construction isn't sensitive to that choice and can be made to work with either implementation of OP_CHECKSIGFROMSTACKVERIFY.
On Wed, Nov 2, 2016 at 11:35 PM, Johnson Lau <jl2012@xbt•hk> wrote:
Quoted text (35 lines)
> Interesting. I have implemented OP_CHECKSIGFROMSTACKVERIFY in a different > way from the Elements. Instead of hashing the data on stack, I directly put > the 32 byte hash to the stack. This should be more flexible as not every > system are using double-SHA256 > > https://github.com/jl2012/bitcoin/commits/mast_v3_master > > > On 3 Nov 2016, at 01:30, Russell O'Connor via bitcoin-dev < > bitcoin-dev@lists•linuxfoundation•org> wrote: > > Hi all, > > It is possible to implement covenants using two script extensions: OP_CAT > and OP_CHECKSIGFROMSTACKVERIFY. Both of these op codes are already > available in the Elements Alpha sidechain, so it is possible to construct > covenants in Elements Alpha today. I have detailed how the construction > works in a blog post at <https://blockstream.com/2016/ > 11/02/covenants-in-elements-alpha.html>. As an example, I've constructed > scripts for the Moeser-Eyal-Sirer vault. > > I'm interested in collecting and implementing other useful covenants, so > if people have ideas, please post them. > > If there are any questions, I'd be happy to answer. > > -- > Russell O'Connor > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists•linuxfoundation•org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > > >
Really cool!
How about "poison transactions," the other covenants use case proposed by Möser, Eyal, and Sirer? (I think OP_CHECKSIGFROMSTACKVERIFY will also make it easier to check fraud proofs, the other prerequisite for poison transactions.)
Seems a little wasteful to do those two "unnecessary" signature checks, and to have to construct the entire transaction data structure, just to verify a single output in the transaction. Any plans to add more flexible introspection opcodes to Elements, such as OP_CHECKOUTPUTVERIFY?
Really minor nit: "Notice that we have appended 0x83 to the end of the transaction data"—should this say "to the end of the signature"?
On Thu, Nov 3, 2016 at 12:28 AM Russell O'Connor via bitcoin-dev < bitcoin-dev@lists•linuxfoundation•org> wrote:
Right. There are minor trade-offs to be made with regards to that design point of OP_CHECKSIGFROMSTACKVERIFY. Fortunately this covenant construction isn't sensitive to that choice and can be made to work with either implementation of OP_CHECKSIGFROMSTACKVERIFY.
On Wed, Nov 2, 2016 at 11:35 PM, Johnson Lau <jl2012@xbt•hk> wrote:
Interesting. I have implemented OP_CHECKSIGFROMSTACKVERIFY in a different way from the Elements. Instead of hashing the data on stack, I directly put the 32 byte hash to the stack. This should be more flexible as not every system are using double-SHA256
https://github.com/jl2012/bitcoin/commits/mast_v3_master
On 3 Nov 2016, at 01:30, Russell O'Connor via bitcoin-dev < bitcoin-dev@lists•linuxfoundation•org> wrote:
Hi all,
It is possible to implement covenants using two script extensions: OP_CAT and OP_CHECKSIGFROMSTACKVERIFY. Both of these op codes are already available in the Elements Alpha sidechain, so it is possible to construct covenants in Elements Alpha today. I have detailed how the construction works in a blog post at < https://blockstream.com/2016/11/02/covenants-in-elements-alpha.html>. As an example, I've constructed scripts for the Moeser-Eyal-Sirer vault.
I'm interested in collecting and implementing other useful covenants, so if people have ideas, please post them.
If there are any questions, I'd be happy to answer.
On Wed, Nov 2, 2016 at 1:30 PM, Russell O'Connor via bitcoin-dev <bitcoin-dev@lists•linuxfoundation•org> wrote:
Quoted text (2 lines)
> I'm interested in collecting and implementing other useful covenants, so if > people have ideas, please post them.
I know of a good business case that could benefit from two nice features.
As an example:
Two parties have initiated a transaction designed with counterparty-minimization in mind. It uses MAST and has many different payout distributions. Both parties enter expecting to gain from the transaction, but both take on risk due to external factors.
Because of the risks involved, there exist possible times when one party may wish to renegotiate the exit distribution, and might threaten to block any exit. Or, either party might get hit by the proverbial bus. During such times, the other party's eventual exit is protected by using a multisig which includes an oracle determination. The oracle's trusted role is bound to this example's unstated "external factors" in a very limited sense, and does not include broader concerns, such as determining whether a party to the transaction is of "sound mind and body".
The singular term "oracle" hides a set of entities participating in m-of-n multisig, which we can name the "oracle-set".
Transaction terms include a CLTV lasting perhaps several years, applied whenever the exit requires the oracle-set's signatures.
Both parties may mutually select and sign one of the payout distributions, to exit early.
The example, as I've described it so far, doesn't need anything other than MAST. It isn't a covenant, because it doesn't impose any forward restrictions when satisfied; despite the contractual complications of executing the oracle-set's signatures. As covenant features are considered across updated instances of what is otherwise a singular transaction, it's important that none carry into the final payout distribution, and that this is easy to verify.
Features desired:
- One party would like to unilaterally sell their participation in
the transaction, to a previously unknown recipient, before the
CLTV becomes valid.
The other originating party's stored MAST should either continue
to function, or require minimal replacements that can be
deterministically applied using data visible on the blockchain.
It should not be necessary to ask permission from - or coordinate
online communication with - the other originating party.
(This can also be viewed as a key rotation problem for any
long-lasting multisig transaction.)
- Both parties would like to mutually revoke rouge oracle-entities
from the oracle-set, without exposing each other to any possible
renegotiation of other terms.
Note that these features affect each other, since if one party sells their participation after any oracle-entities have been revoked, then the revocations should not reset, but rather remain in effect, until a proper payout executes the final agreement in the contract.
Of course, if there's a way to achieve these features with less risk than evaluating covenant logic, I would very much like to hear how to do so.
On Thu, Nov 3, 2016 at 3:37 AM, Daniel Robinson <danrobinson010@gmail•com> wrote:
Quoted text (7 lines)
> Really cool! > > How about "poison transactions," the other covenants use case proposed by > Möser, Eyal, and Sirer? (I think OP_CHECKSIGFROMSTACKVERIFY will also make > it easier to check fraud proofs, the other prerequisite for poison > transactions.) >
I admit I didn't study their poison transactions very carefully. It seemed specific to Bitcoin-NG.
Quoted text (5 lines)
> Seems a little wasteful to do those two "unnecessary" signature checks, > and to have to construct the entire transaction data structure, just to > verify a single output in the transaction. Any plans to add more flexible > introspection opcodes to Elements, such as OP_CHECKOUTPUTVERIFY? >
I used to be hesitant to the idea of adding transaction introspection operations, because the script design seemed to be deliberately avoiding doing that. One of the big takeaways from this work, for me at least, is that since the transaction data is so easily recoverable anyways, adding transaction introspection operations isn't really going to provide any more power to script; it will just save everyone a bunch of work. There are no specific plans to put transaction introspection opcodes into Elements at this moment, but I feel that the door for that possibility is wide open now.
Really minor nit: "Notice that we have appended 0x83 to the end of the
Quoted text (2 lines)
> transaction data"—should this say "to the end of the signature"? >
Probably should reed "Notice that we have appended 0x83000000 to the end of the transaction data". I'll make an update.
Quoted text (50 lines)
> > On Thu, Nov 3, 2016 at 12:28 AM Russell O'Connor via bitcoin-dev < > bitcoin-dev@lists•linuxfoundation•org> wrote: > > Right. There are minor trade-offs to be made with regards to that design > point of OP_CHECKSIGFROMSTACKVERIFY. Fortunately this covenant > construction isn't sensitive to that choice and can be made to work with > either implementation of OP_CHECKSIGFROMSTACKVERIFY. > > On Wed, Nov 2, 2016 at 11:35 PM, Johnson Lau <jl2012@xbt•hk> wrote: > > Interesting. I have implemented OP_CHECKSIGFROMSTACKVERIFY in a different > way from the Elements. Instead of hashing the data on stack, I directly put > the 32 byte hash to the stack. This should be more flexible as not every > system are using double-SHA256 > > https://github.com/jl2012/bitcoin/commits/mast_v3_master > > > On 3 Nov 2016, at 01:30, Russell O'Connor via bitcoin-dev < > bitcoin-dev@lists•linuxfoundation•org> wrote: > > Hi all, > > It is possible to implement covenants using two script extensions: OP_CAT > and OP_CHECKSIGFROMSTACKVERIFY. Both of these op codes are already > available in the Elements Alpha sidechain, so it is possible to construct > covenants in Elements Alpha today. I have detailed how the construction > works in a blog post at <https://blockstream.com/2016/ > 11/02/covenants-in-elements-alpha.html>. As an example, I've constructed > scripts for the Moeser-Eyal-Sirer vault. > > I'm interested in collecting and implementing other useful covenants, so > if people have ideas, please post them. > > If there are any questions, I'd be happy to answer. > > -- > Russell O'Connor > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists•linuxfoundation•org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists•linuxfoundation•org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > >
Not a covenant but interesting nevertheless: _One_ of OP_CAT and OP_CHECKSIGFROMSTACKVERIFY alone is enough to implement "opt-in miner takes double-spend" [1]:
You can create an output, which is spendable by everybody if you ever double-spend the output with two different transactions. Then the next miner will probably take your money (double-spending against your two or more contradicting transactions again).
If you spend such an output, then the recipient may be willing to accept a zero-conf transaction, because he knows that you'll lose the money when you attempt double-spending (unless you are the lucky miner). See the discussion in [1] for details.
The implementation using OP_CHECKSIGFROMSTACKVERIFY is straight- forward. You add a case to the script which allows spending if two valid signatures on different message under the public key of the output are given.
What is less known I think: The same functionality can be achieved in a simpler way just using OP_CAT, because it's possible to turn Bitcoin's ECDSA to an "opt-in one-time signature scheme". With OP_CAT, you can create an output that is only spendable using a signature (r,s) with a specific already fixed first part r=x_coord(kG). Basically, the creator of this output commits on r (and k) already when creating the output. Now, signing two different transaction with the same r allows everybody to extract the secret key from the two signatures.
The drawbacks of the implementation with OP_CAT is that it's not possible to make a distinction between legitimate or illegitimate double-spends (yet to be defined) but just every double-spend is penalized. Also, it's somewhat hackish and the signer must store k (or create it deterministically but that's a good idea anyway).
[1] https://www.mail-archive.com/bitcoin-development@lists.sourceforge.net/msg07122.html
Best, Tim
On Thu, 2016-11-03 at 07:37 +0000, Daniel Robinson via bitcoin-dev wrote:
Quoted text (70 lines)
> Really cool! > > How about "poison transactions," the other covenants use case > proposed by Möser, Eyal, and Sirer? (I think > OP_CHECKSIGFROMSTACKVERIFY will also make it easier to check fraud > proofs, the other prerequisite for poison transactions.) > > Seems a little wasteful to do those two "unnecessary" signature > checks, and to have to construct the entire transaction data > structure, just to verify a single output in the transaction. Any > plans to add more flexible introspection opcodes to Elements, such as > OP_CHECKOUTPUTVERIFY? > > Really minor nit: "Notice that we have appended 0x83 to the end of > the transaction data"—should this say "to the end of the signature"? > > On Thu, Nov 3, 2016 at 12:28 AM Russell O'Connor via bitcoin-dev <bit > coin-dev@lists•linuxfoundation•org> wrote: > > Right. There are minor trade-offs to be made with regards to that > > design point of OP_CHECKSIGFROMSTACKVERIFY. Fortunately this > > covenant construction isn't sensitive to that choice and can be > > made to work with either implementation of > > OP_CHECKSIGFROMSTACKVERIFY. > > > > On Wed, Nov 2, 2016 at 11:35 PM, Johnson Lau <jl2012@xbt•hk> wrote: > > > Interesting. I have implemented OP_CHECKSIGFROMSTACKVERIFY in a > > > different way from the Elements. Instead of hashing the data on > > > stack, I directly put the 32 byte hash to the stack. This should > > > be more flexible as not every system are using double-SHA256 > > > > > > https://github.com/jl2012/bitcoin/commits/mast_v3_master > > > > > > > > > > > > > On 3 Nov 2016, at 01:30, Russell O'Connor via bitcoin-dev <bitc > > > > oin-dev@lists•linuxfoundation•org> wrote: > > > > > > > > Hi all, > > > > > > > > It is possible to implement covenants using two script > > > > extensions: OP_CAT and OP_CHECKSIGFROMSTACKVERIFY. Both of > > > > these op codes are already available in the Elements Alpha > > > > sidechain, so it is possible to construct covenants in Elements > > > > Alpha today. I have detailed how the construction works in a > > > > blog post at <https://blockstream.com/2016/11/02/covenants-in-e > > > > lements-alpha.html>. As an example, I've constructed scripts > > > > for the Moeser-Eyal-Sirer vault. > > > > > > > > I'm interested in collecting and implementing other useful > > > > covenants, so if people have ideas, please post them. > > > > > > > > If there are any questions, I'd be happy to answer. > > > > > > > > -- > > > > Russell O'Connor > > > > _______________________________________________ > > > > bitcoin-dev mailing list > > > > bitcoin-dev@lists•linuxfoundation•org > > > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > > > > _______________________________________________ > > bitcoin-dev mailing list > > bitcoin-dev@lists•linuxfoundation•org > > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev > > > > _______________________________________________ > bitcoin-dev mailing list > bitcoin-dev@lists•linuxfoundation•org > https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
I think the following implementation may be advantageous. It uses the same number of opcodes, without OP_CAT.
Avoiding use of OP_CAT is still desirable as I think it will be difficult to agree on semantics for OP_CAT (given necessary measures to prevent memory abuse) than for OP_LEFT. Another option I would be in support of would be to have signature flags apply to OP_CHECKSIGFROMSTACK and all OP_CHECKSIG flags be ignored if they aren't meaningful...
*<signature; SIGHASH_ALL><signatureTxnData>1. <pubkey> OP_DUP3<pubkey><signature; SIGHASH_ALL><signatureTxnData><pubkey><signature; SIGHASH_ALL><signatureTxnData>2. OP_CHECKSIGVERIFY<signatureTxnData><pubkey><signature; SIGHASH_ALL><signatureTxnData>3. OP_SHA256 OP_ROT OP_SIZE OP_SUB1 OP_LEFT<signature><sha256(signatureTxnData)><pubkey><signatureTxnData>4. OP_SWAP OP_ROT OP_CHECKSIGFROMSTACKVERIFY (with same argument order)*