3

OP_CAT takes the top 2 stack items, concatenates them and pushes the result to the stack. How can this be used to add new restrictions how a UTXO can be spent? (Beyond the existing signature and time lock covenants)

1 Answer 1

3

Background

Bitcoin script is a stack-based verification language. Because it's a verification language any operation available in the language can be used to either take inputs and produce an output for later use in the script, or require inputs to be provided for use in the script which produce a pre-determined output. As Andrew Poelstra says - operations can be run forward or backward.

Currently, bitcoin scripts have 3 ways to verify the transaction in which they are spent:

  • Requiring a specific nLockTime field on the transaction (OP_CHECKLOCKTIMEVERIFY)
  • Requiring a specific nSequence field on the input (OP_CHECKSEQUENCEVERIFY)
  • Requiring a signature over a hash of the transaction (OP_CHECKSIG and its variants)

When people discuss "adding covenants" to bitcoin, they refer to adding additional ways to verify the spending transaction, most commonly restrictions on the outputs the transaction will make.

Bitcoin signature checking operations internally hash the transaction being verified. Because the hashing and signing are contained in a single operation, neither the signature hash nor the input data for that hash can be directly inspected by script.

BIP 340 signatures consist of (R,s) satisfying the function s⋅G = R + hash(R || P || m)⋅P where m is the signature hash, P is the signer's public key, and G is the secp256k1 generator point.

Getting the signature hash on the stack

As Andrew Poelstra describes in detail, by setting R and P equal to G, we can force s to be equal to hash(G || G || m) + 1. Using CAT, we can deconstruct the 64-byte signature into its R and s values, and if we further require the spend stack to include the first 31 bytes of hash(G || G || m) (ground until the last byte would have been 0x00), we can then further require the spend stack to provide m.

Verifying transaction elements

BIP 341 signature hashes are composed of internal hashes of many parts of the transaction being verified. Using CAT, a bitcoin spend script can require the spend stack to include the unconstrained inputs to the signature hashes and concatenate them with script-provided constrained portions to verify that the constrained portions match the actual transaction. This means that any datum included in the signature hash can be constrained individually using CAT.

Thus, by including (for example) a hash of transaction outputs in a locking script, an OP_CAT-based covenant script can require the caller to provide all other transaction data and the hashes described above and require that the spending transaction has the required outputs. An additional covenant in bitcoin script.


Full working code using these techniques can be seen in @rot13maxi's Purrfect Vaults

2
  • I did a deep dive on this topic with more naive eyes and wrote up my understanding (with some ascii art!). I'd be happy to write up a more condensed version here to complement your answer, or feel free to poach some or none of this.
    – yonson
    Commented Aug 7 at 20:35
  • Thanks! Added some text that based on your write-up that I think was missing here. Commented Aug 8 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.