LearnBitcoin

Bitcoin Dev Archive 2016

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

Permalink Original thread on gnusha.org

Russell O'Connor permalink original

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.

Johnson Lau in reply to Russell O'Connor permalink original

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
Russell O'Connor in reply to Russell O'Connor permalink original

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
>
>
>
Dan Robinson in reply to Russell O'Connor permalink original

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.

Ryan Grant in reply to Russell O'Connor permalink original

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.

Russell O'Connor in reply to Dan Robinson permalink original

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
>
>
Tim Ruffing in reply to Dan Robinson permalink original

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
Jeremy Rubin in reply to Tim Ruffing permalink original

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_CHECKSIGFROMSTACK​VERIFY​ (with same ​argument order​)​*