BIP-119 CTV Fundamentals

Background

BIP-119 OP_CHECKTEMPLATEVERIFY (CTV) is a proposed soft-fork upgrade to Bitcoin for enabling a bevy of use cases.

At it's core, CTV enables a script to commit to the "important bits" of how it can be spent, or the:

  1. nVersion
  2. nLockTime
  3. scriptSig hash (maybe!)
  4. input count
  5. sequences hash
  6. output count
  7. outputs hash
  8. input index

This enables a myriad of use cases, which are described in detail in the BIP and on the website utxos.org.

How do we think about Smart Contracts and CTV?

Before CTV, in most Bitcoin smart contracts, we think at the key-level. That is, what is a complex set of signers and satisfactions to unlock a specific coin. But once we unlock a coin, the smart contract usually does not encode any further restrictions on how it may be spent.

You could think of this as "a key to a car". If it unlocks the car, you can take the car wherever you want.

With CTV, we hope to encode a bit more information about how coins should move by providing the paths that the coins must move through as well. So rather than just being the key to a car, you could think of it a bit more like the keys to train -- still required to start the engine, but you have to stay on the tracks and there is a finite number of tracks to pick at any juncture.

That's all a bit abstract. Think back to the Hello World example we saw earlier. We created a coin with the following options:

  1. Alice and Bob Agree \( \rightarrow \) coin goes anywhere
  2. Timeout \( \rightarrow \) coins go back to Alice and Bob

Now imagine we wanted to change the rules a little. What if instead of rule 2 apply after a timeout, what if we wanted the timeout to be measured from the time that Alice or Bob claimed they wanted to use the escrow.

This puts us in a little bit of a pickle. Sure we could just re-write the rules:

  1. Alice and Bob Agree \( \rightarrow \) coin goes anywhere
  2. Timeout since Alice or Bob requested \( \rightarrow \) coins go back to Alice and Bob

But Bitcoin doesn't have a script level notion of "since" a part of a witness was constructed. The CTV way to think of this script is to define a state machine with two states \( S \in \{Normal, Closing\}\) and the rules:

  • \( S \gets Normal\):

    1. Alice and Bob Agree \( \rightarrow \) coin goes anywhere
    2. Alice or Bob Requested \( \rightarrow \) (\(S \gets Closing \))
  • \( S \gets Closing\):

    1. Alice and Bob Agree \( \rightarrow \) coin goes anywhere
    2. Timeout since (\(S \gets Closing\)) \( \rightarrow \) coins go back to Alice and Bob.

What drives the transition from Normal to Closing? Just a standard Bitcoin transaction!

So What is Sapio

Sapio is an embedded domain specific language for defining these sorts of state transition rules to build smart contracts for Bitcoin.

CTV is used as the mechanism to enforce that specific state transitions occur.

When we write a program in Sapio, we are designing an arbitrary state machine that can run any program.

When we compile a Sapio program, we run that state machine to completion and merkelize the resultant program states into a fixed graph.

As such, Sapio is a very powerful framework for designing Bitcoin smart contracts, but we're constrained to the set of contracts where we can enumerate all possible end states.

To get around these restrictions, Sapio has some tricks up it's sleeve that will be described in future chapters.