Here you'll find an assorted mix of content from yours truly. I post about a lot
of things, but primarily
02 Aug 2021
TL;DR: click here to answer call to action
The infrastructure bill draft has been circulating which contains language that
would have massive impact for the crypto ecosystem (and Bitcoin) in the United
States, and most likely globally. The broad implication of the proposed bill is
that many types of service provider would be categorized as brokers, even if
fully ‘non custodial’. E.g., a coinjoin coordinator might be a broker, even if
they never take control of the funds, because they are facilitating a
transaction. There’s a lot of nuance, and the language is still being changed,
so we’ll see where it lands. But that’s not the point of this blog post.
The point of this blog post is that we need to hurry the fuck up and improve
the self-sovereign software available and widely used by bitcoiners. You heard
me right, hurry the fuck up.
While there’s space for debate around perfect designs and optima for protocol
improvements, these discussions take years to turn into code running in end
users wallets. I do not believe that we have time to leisurely improve
self-sovereign custody solutions while regulators figure out a wrench to throw
in our spokes.
Why am I so concerned about this bill in particular? A confidential source
tells me that this language came out of the blue, an executive branch driven
regulatory ninja attack of sorts. Normally, when the government looks to
regulate an industry, the provisions and terms get floated around by
legislators for a long while with industry input, comment periods, and more.
Then, when a bill or other rules get passed, it’s something that the industry
has at least had a chance to weigh in on and prepare for. My source claims no
one has seen the clauses in the infrastructure bill before, and they infer that
may mean this is a part of a broader crack-down coming from specific political
personalities and agencies. This means we may be seeing government actions
further restricting users’ rights in the pipeline much sooner than anyone could
anticipate.
I’ve long been saying that we should be deploying BIP-119
CTV for congestion control before we see broad congestion
on the network. If you wait until a problem is manifest, it can take years to
deploy a solution. This merits proactivity in solving a problem before it
comes. Today, the need to improve self-custody looms urgently on the horizon.
CTV is not a panacea solution. It doesn’t magically fix all custodial issues.
But, along with Sapio, it does offer a pathway
to dramatically improving self custody options, letting users customize vault
smart contracts which do not depend on any third parties. Deploying CTV now is
an opportunity to put in motion the wheels for broad ecosystem support for
these enhanced custody protocols. We may come up with better options in the
future which may obsolete CTV in place of more clever technologies. I cheer
those efforts. But we need solutions for Tomorrow.
A soft fork activation for CTV could be deployable for Bitcoin imminently,
should the community embrace it. The spec is nearly 2 years old, the code has
required only small updates to be mergeable with other changes to Bitcoin Core.
The review burden is 185 lines of consensus code, and a couple hundred lines of
tests. To that end I believe it is prudent for the Bitcoin community to embrace
the deployment of CTV and I’m calling on the community to soft-signal
intent for a soft-fork
activation of CTV.
We cannot control what rules state authorities attempt to mandate. But we can
individually control our own compliance with measures we see as unjust, and as
a community we can advance technologies and solutions that ensure that choice
remains squarely in the hands of every user and not the service providers they
may use.
09 Jul 2021
As a part of my ongoing review of BIP-118 I put together a
chart
of what gets hashed under the current proposal.
Not tightly checked to be free of errors, but I figured such a chart would be
helpful for folks evaluating BIP-118.
Perhaps the BIPs (generally, incl 34x) could be updated to present the
information in such a chart – at least for me it’s much clearer than following
a bunch of conditional logic (maybe if there’s ever desire for some consensus
refactoring this could be a table in the code replacing the cond logic).
A few highlighted nuances:
- input index is never signed (i previously thought one mode signed it). Key reuse under
APOAS | Default
and APOAS | All
is a bit extra unsafe given susceptibility to the “half-spend” problem. This limits usability of APO for covenants a-la CTV because you can’t stop someone from adding inputs to your contract nor can you prevent half-spend problems when reusing addresses.
- APO signs the Amounts, APOAS never does.
- APO signs both the SPK and the Tapleaf hash, meaning that APO binds itself to the entire script rather than just it’s fragment. There’s no setting which is “just this fragment”
- APO’s signature binds it to a specific script fragment within a taproot key, but not a specific script path
- the flag “default” is not really a flag at all – when default is used (as a or’d byte) there are different results than when default is inferred (by absence of a byte) (this is maybe a bitcoin core specific quirk).
- There are 16 different possible modes total, so all combinations of flags mean something (advisable or not as with
ACP | None
)
*| Default
and *| All
overlap, so there’s an opportunity to either reserve or assign 4 additional sighash modes if desired. These could cover some of the gaps above, or be saved for future purposes rather than be wasted now. Another point of interest is – not to rock the boat – but because BIP-118 is defining a new key type we could do away with the notion that sighash flags are “flags” and convert to an enum (e.g., numbered 0-256 for whatever combination of fields each would incur) and give each signature type a sensible name, rather than thinking of things as a combo of flags (e.g., APOAS
is not some intersection of what APO
and ACP
do independently).
no cats harmed in the making of this post
06 Jul 2021
I recently published a blog
post about signing up to a
5 byte value using Bitcoin script arithmetic and Lamport signatures.
By itself, this is neat, but a little limited. What if we could sign longer
messages? If we can sign up to 20 bytes, we could sign a HASH160 digest which
is most likely quantum safe…
What would it mean if we signed the HASH160 digest of a signature? What the
what? Why would we do that?
Well, as it turns out, even if a quantum computer were able to crack ECDSA, it
would yield revealing the private key but not the ability to malleate the
content of what was actually signed. I asked my good friend and cryptographer
Madars Virza if my intuition was correct, and he
confirmed that it should be sufficient, but it’s definitely worth closer
analysis before relying on this. While the ECDSA signature can be malleated to a
different, negative form, if the signature is otherwise made immalleable there
should only be one value the commitment can be opened to.
If we required the ECDSA signature be signed with a quantum proof signature
algorithm, then we’d have a quantum proof Bitcoin! And the 5 byte signing scheme
we discussed previously is a Lamport signature, which is quantum secure.
Unfortunately, we need at least 20 contiguous bytes… so we need some sort of
OP_CAT like operation.
OP_CAT can’t be directly soft forked to Segwit v0 because it modifies the
stack, so instead we’ll (for simplicity) also show how to use a new opcode that
uses verify semantics, OP_SUBSTRINGEQUALVERIFY that checks a splice of a string
for equality.
Fun Fact: OP_CAT existed in Bitcoin untill 2010, when Satoshi “secretly”
forked out a bunch of opcodes. So in theory the original Bitcoin implementation
supported Post Quantum cryptography out of the box!
... FOR j in 0..=5
<0>
... FOR i in 0..=31
SWAP hash160 DUP <H(K_j_i_1)> EQUAL IF DROP <2**i> ADD ELSE <H(K_j_i_0)> EQUALVERIFY ENDIF
... END FOR
TOALTSTACK
... END FOR
DUP HASH160
... IF CAT AVAILABLE
FROMALTSTACK
... FOR j in 0..=5
FROMALTSTACK
CAT
... END FOR
EQUALVERIFY
... ELSE SUBSTRINGEQUALVERIFY AVAILABLE
... FOR j in 0..=5
FROMALTSTACK <0+j*4> <4+j*4> SUBSTRINGEQUALVERIFY DROP DROP DROP
... END FOR
DROP
... END IF
<pk> CHECKSIG
That’s a long script… but will it fit? We need to verify 20 bytes of message
each bit takes around 10 bytes script, an average of 3.375 bytes per number
(counting pushes), and two 21 bytes keys = 55.375 bytes of program space and 21
bytes of witness element per bit.
It fits! 20*8*55.375 = 8860
, which leaves 1140 bytes less than the limit for
the rest of the logic, which is plenty (around 15-40 bytes required for the rest
of the logic, leaving 1100 free for custom signature checking). The stack size
is 160 elements for the hash gadget, 3360 bytes.
This can probably be made a bit more efficient by expanding to a ternary
representation.
SWAP hash160 DUP <H(K_j_i_0)> EQUAL IF DROP ELSE <3**i> SWAP DUP <H(K_j_i_T)> EQUAL IF DROP SUB ELSE <H(K_j_i_1)> EQUALVERIFY ADD ENDIF ENDIF
This should bring it up to roughly 85 bytes per trit, and there should be 101
trits (log(2**160)/log(3) == 100.94
), so about 8560 bytes… a bit cheaper!
But the witness stack is “only” 2121
bytes…
As a homework exercise, maybe someone can prove the optimal choice of radix for
this protocol… My guess is that base 4 is optimal!
Taproot?
What about Taproot? As far as I’m aware the commitment scheme (Q = pG + hash(pG
|| m)G
) can be securely opened to m even with a quantum computer (finding q
such that qG = Q
might be trivial, but suppose key path was disabled, then
finding m and p such that the taproot equation holds should be difficult because
of the hash, but I’d need to certify that claim better). Therefore this
script can nest inside of a Tapscript path – Tapscript also does not impose a
length limit, 32 byte hashes could be used as well.
Further, to make keys reusable, there could be many Lamport keys comitted inside
a taproot tree so that an address could be used for thousands of times before
expiring. This could be used as a measure to protect accidental use rather than
to support it.
Lastly, Schnorr actually has a stronger non-malleability property than ECDSA,
the signatures will be binding to the approved transaction and once Lamport
signed, even a quantum computer could not steal the funds.
02 Jul 2021
I recently published a blog post
about covenants on Bitcoin.
Readers were quick to point out I hadn’t
fully explained myself on a claim I made that you can do a form of
CheckSigFromStack in Bitcoin today.
So I thought it would be worthwhile to fully describe the technique – for the
archives.
There are two insights in this post:
- to use a bitwise expansion of the number
- to use a lamport signature
Let’s look at the code in python and then translate to bitcoin script:
def add_bit(idx, preimage, image_0, image_1):
s = sha256(preimage)
if s == image_1:
return (1 << idx)
if s == image_0:
return 0
else:
assert False
def get_signed_number(witnesses : List[Hash], keys : List[Tuple[Hash, Hash]]):
acc = 0
for (idx, preimage) in enumerate(witnesses):
acc += add_bit(idx, preimage, keys[idx][0], keys[idx][1])
return x
So what’s going on here? The signer generates a key which is a list of pairs of
hash images to create the script.
To sign, the signer provides a witness of a list of preimages that match one or the other.
During validation, the network adds up a weighted value per preimage and checks
that there are no left out values.
Let’s imagine a concrete use case: I want a third party to post-hoc sign a sequence lock. This is 16 bits.
I can form the following script:
<pk> checksigverify
0
SWAP sha256 DUP <H(K_0_1)> EQUAL IF DROP <1> ADD ELSE <H(K_0_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_1_1)> EQUAL IF DROP <1<<1> ADD ELSE <H(K_1_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_2_1)> EQUAL IF DROP <1<<2> ADD ELSE <H(K_2_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_3_1)> EQUAL IF DROP <1<<3> ADD ELSE <H(K_3_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_4_1)> EQUAL IF DROP <1<<4> ADD ELSE <H(K_4_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_5_1)> EQUAL IF DROP <1<<5> ADD ELSE <H(K_5_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_6_1)> EQUAL IF DROP <1<<6> ADD ELSE <H(K_6_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_7_1)> EQUAL IF DROP <1<<7> ADD ELSE <H(K_7_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_8_1)> EQUAL IF DROP <1<<8> ADD ELSE <H(K_8_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_9_1)> EQUAL IF DROP <1<<9> ADD ELSE <H(K_9_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_10_1)> EQUAL IF DROP <1<<10> ADD ELSE <H(K_10_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_11_1)> EQUAL IF DROP <1<<11> ADD ELSE <H(K_11_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_12_1)> EQUAL IF DROP <1<<12> ADD ELSE <H(K_12_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_13_1)> EQUAL IF DROP <1<<13> ADD ELSE <H(K_13_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_14_1)> EQUAL IF DROP <1<<14> ADD ELSE <H(K_14_0)> EQUALVERIFY ENDIF
SWAP sha256 DUP <H(K_15_1)> EQUAL IF DROP <1<<15> ADD ELSE <H(K_15_0)> EQUALVERIFY ENDIF
CHECKSEQUENCEVERIFY
In order to sign a 16 bit value V, the owner of K simply puts on the stack the
binary representation of V indexed into the K. E.g., to sign 53593
, first
expand to binary 0b1101000101011001
, then put the appropriate K values on the
stack.
K_15_1
K_14_1
K_13_0
K_12_1
K_11_0
K_10_0
K_9_0
K_8_1
K_7_0
K_6_1
K_5_0
K_4_1
K_3_1
K_2_0
K_1_0
K_0_1
<sig>
This technique is kind of bulky! It’s around 80x16 = 1280 length for the
gadget, and 528 bytes for the witnesses. So it is doable, if not a bit
expensive. There might be some more efficient scripts for this – would a
trinary representation be more efficient?
The values that can be signed can be range limited either post-hoc (using
OP_WITHIN) or internally as was done with the 16 bit value circuit where it’s
impossible to do more than 16 bits.
Keys can be reused across scripts, but signatures may only be constructed one
time because a third party could take two signed messages and construct an
unintended value (e.g., if you sign both 4 and 2 then a third party could
construct 6).
There are certain applications where this could be used for an effect – for
example, an oracle might have a bonding contract whereby posessing any K_i_0
and K_i_1 allows the burning of funds.
02 Jul 2021
If you’ve been following The Discourse, you probably know that Taproot is
merged, locked in, and will activate later this November. What you might not
know is what’s coming next… and you wouldn’t be alone in that. There are a
number of fantastic proposals floating around to further improve Bitcoin, but
there’s no clear picture on what is ready to be added next and on what
timeline. No one – core developer, technically enlightened individuals, power
users, or plebs – can claim to know otherwise.
In this post I’m going to describe 4 loosely related possible upgrades to
Bitcoin – SH_APO (BIP-118), OP_CAT, OP_CSFS, and OP_CTV (BIP-119). These four
upgrades all relate to how the next generation of stateful smart contracts can
be built on top of bitcoin. As such, there’s natural overlap – and competition
– for mindshare for review and deployment. This post is my attempt to stitch
together a path we might take to roll them out and why that ordering makes
sense. This post is for developers and engineers building in the Bitcoin space,
but is intended to be followable by anyone technical or not who has a keen
interest in Bitcoin.
Bitcoin Eschews Roadmaps and Agendas.
I provide this maxim to make clear that this document is by no means an
official roadmap, narrative, or prioritization. However, it is my own
assessment of what the current most pragmatic approach to upgrading Bitcoin is,
based on my understanding of the state of outstanding proposals and their
interactions.
My priorities in producing this are to open a discussion on potential new
features, risk minimization, and pragmatic design for Bitcoin.
Upgrade Summaries
Below follows summaries of what each upgrade would enable and how it works. You
might be tempted to skip it if you’re already familiar with the upgrades, but I
recommend reading in any case as there are a few non obvious insights.
APO: SIGHASH_ANYPREVOUT, SIGHASH_ANYPREVOUTANYSCRIPT
Currently proposed as
BIP-118.
APO provides two new signature digest algorithms that do not commit to the coin
being spent, or the current script additionally. Essentially allowing scripts
to use outputs that didn’t exist at the time the script was made. This would be
a new promise enforced by Bitcoin (ex. “You can close this Lightning channel
and receive these coins if you give me the right proof. If a newer proof comes
in later I’ll trust that one instead.”).
APO’s primary purpose is to enable off chain protocols like
Eltoo, an
improved non-punitive payment channel protocol.
APO can also
emulate
some of the main features of CTV and could be made to work with Sapio,
partially. See the complimentary upgrades section for more detail.
CAT (+ variants)
Currently no BIP. However, CAT exists in
Elements
and Bitcoin
Cash
as a 520 byte limited form, so a proposal for Bitcoin can crib heavily from
either.
Cat enables appending data onto other pieces of data. Diabolically simple
functionality that has many advanced use cases by itself and in concert with
other opcodes. There are many “straightforward” use cases of cat like requiring
sighash types, requiring specific R values, etc, but there are too many devious
use cases to list here. Andrew Poelstra has a decent blogpost series (part
1 and
part
ii) if
you’re interested to read more. In particular, with much cleverness, it seems
possible one could implement full covenants with just CAT, which covers
(inefficiently) most of the other techniques discussed in this post.
CSFS: CHECKSIGFROMSTACK
Currently no BIP. However, CSFS exists in
Elements
and in Bitcoin
Cash,
so a proposal for Bitcoin can crib heavily from either.
CSFS enables checking of a signature against a message and key from the stack
without including any transaction data.
Use cases include oracle protocols, key delegations, a channel update
invalidation
variant
(Laolu claims this can be tweaked to be fully non punitive like eltoo, but
you’ll need to bug him to write it up), and (+CAT) full covenants.
CTV: OP_CHECKTEMPLATEVERIFY
Currently proposed as
BIP-119.
CTV enables committing to a specific “next” transaction from script. This is
the ability to make an unbreakable promise on chain which Bitcoin can enforce
(e.g. “This coin can only be spent to my multisig, or my backup after a
timelock”). This is a departure from normal script which is traditionally only
concerned with restrictions on the sender, CTV imposes restrictions on the
recipient. More technically, CTV is essentially the ability to embed a
signature of a specific transaction inside of a script without needing any
elliptic curve operations. The validation costs are low. For more advanced
logic, you can nest multiple different CTV Hashes either using taproot or up to
the script length limits in regular script.
CTV can be used for vaults, channels, and many other
uses. There’s also
Sapio which is a language and toolkit for
creating many kinds of programs with CTV.
CTV compliments CSFS to be able to emulate APO-like functionality
sufficient to build Eltoo, potentially making APO feature-wise redundant.
Comparative Analysis
Now that we’ve got the basics covered, let’s explore these upgrades
comparatively across several dimensions.
Design Specificity
“Design Specificity” is a subjective measure of how substantially an upgrade
could change from its current design while still meeting the features goals. It
is not to be confused with security or safety. Ranked in order from most to
least design specific, with non-exhaustive lists of design questions based on
ongoing community discourse as well as my own personal understanding of what
might be desirable.
- CSFS
- CTV
- CAT
- APO
Explanations & Open Questions:
- CSFS is very simple and there is essentially a single way to implement it. Three open questions are:
- Should CSFS require some sort of tagged hash? Very likely answer is no –
tags interfere with certain use cases)
- Should CSFS split the signature’s R & S value stack items for some
applications that otherwise may require OP_CAT? E.g. using a pinned R
value allows you to extract a private key if ever double signed, using 2 R
values allows pay-to-reveal-key contracts. Most likely answer is no, if that is
desired then OP_CAT can be introduced
- Should CSFS support a cheap way to reference the taproot internal or
external key? Perhaps, can be handled with undefined upgradeable
keytypes. One might want to use the internal key, if the signed data should be
valid independent of the tapscript tree. One might want to use the external
key, if the data should only be valid for a single tapscript key + tree.
- CTV is a commitment to all data that can malleate TXID besides the inputs
being spent, therefore CTV does not have much space for variation on design.
- Should the digest be reordered or formatted differently? If there were
more data on what types of covenants might be built in the future, a
better order could be picked. Some thought has already gone into an order and
commitments that make covenants easier, see the BIP for more. It’s also
possible the serialization format for the variable length fields (scriptsigs,
outputs) could be changed to make it easier to work with from script. (Maybe,
minor change)
- Should CTV include more template types? Possibly, CTV includes an upgrade
mechanism baked in for new template types, so it is extensible for future
purposes.
- Should CTV commit to the amounts? CTV does not commit to the amount that
a coin has. Input-inspecting functionality should be handled by separate
opcodes, as CTV would be overly restrictive otherwise. E.g. dynamic fees
through new inputs would be harder: given CTV’s design it is not possible to
detect which field did not match therefore it is not possible to script against
unexpected amount sent errors without some compromise (e.g. timeouts).
- CAT is simplistic, and there are really few ways to implement it. However,
because it requires some restrictions for security, there are difficult to
answer open design questions:
- What is the appropriate maximum stack size CAT should permit? Currently
the design in Elements is 520 bytes, the max general stack size permitted
in script.
- Should CAT be introduced or
SHASTREAM,
SUBSTRING, or another variant? There is a strong argument for SHASTREAM because
when constructing covenants (e.g. for use with CTV) based on TX data it’s
possible for size of a data field (e.g., serialization of all outputs) to
exceed 520 bytes.
- There are many tough questions that the community has grappled with during
APO’s design and engineering process, generally asking how APO-like
techniques can be made ‘Generally Safe’ given iit breaks current assumptions
around address reuse.
- Should APO require chaperone signatures (in order to ensure that replay
is not done by 3rd parties)? Current Answer: No, anyone is free to burn
their keys by revealing them to similar effect.
- Should APO use key tagging to mark keys that can use APO: Current Answer:
yes, APO should be “double opt-in” (both requiring a tag and a signer to
produce such a signature)
- Should APO allow signing with the external taproot key: Current Answer:
no, because it makes APO not “double opt-in”.
- Should APO optimize signing with the internal taproot key? Answer:
default key 0x01 refers to taproot internal key, so it can be made
cheaper if you’re going to need it without having to repeat the entire key.
- Should APO commit to the signing script? Answer: let’s do two variants.
- Should APO instead be a larger refactoring of sighash logic that
encapsulates APO (e.g. sighash bitmasks)? Current Answer: No, APO is good
enough to ship as is and doesn’t preclude future work.
Safety
This category covers how “safe” each change is ranked from safest to least
safe. What makes a change more or less safe is how limited and foreseeable the
uses are of a specific opcode, in other words, how well we understand what it
can do or where it might interact poorly with deployed infrastructure.
- CTV
- CSFS
- APO
- CAT
CTV is the safest new feature since fundamentally what it introduces is very
similar to what can be done with pre-signed transactions, so it is only a pivot
on trust and interactivity. Where there is some risk from CTV is that addresses
(or rather, invoices) that are reused might have the same program behind them
which could cause unintended behavior. This differs from the reuse problem in
APO because the problem is stateless, that is, if you verify what is behind an
address you will know what exists and does not exist. E.g., two payment channel
addresses will create distinct payment channels that updates cannot be replayed
across. In contrast with APO, paying one APO using address twice creates two
instances of the same channel, state updates from one channel can be used on
the other.
CSFS is the next safest, it is just a small piece of authenticated data. CSFS
and CTV are relatively close in terms of safety, but CSFS is slightly less safe
given a remote possibility of surprising uses of it to perform unforeseen
elliptic curve operations. This functionality already exists for up to 5-byte
messages. A hash preimage revelation can emulate a signer compactly. Using
binary expansions and addition could be used to allow signing of values more
compactly (e.g., 2x16x32 byte hashes could be used to construct a signature of
a post-hoc selected Sequence lock). Read more here. Therefore it is appropriate to think of
CSFS as an expansion of the efficiency of this technique, reusability of keys,
and the types of data that can be signed over. Although CSFS is famously used
to build covenants by comparing a CSFS signature to a CHECKSIG signature and
getting transaction data onto the stack, CSFS cannot do that without CAT.
APO. This is the next safest because APO has some questions around key reuse
safety and statefulness of information. See the above description in CTV for
why this is tangibly worse for APO than CTV. See more discussion of APO’s
safety & design trade offs
here.
CAT is the least ‘safe’ in terms of extant Bitcoin concepts as it is highly
likely CAT introduces at least advanced covenants if added, especially in
conjunction with the above opcodes, but may also enable other unintended
functionality. CAT is a source of continual surprise with regards to what it
enables in composition with existing opcodes, therefore a systematic review of
composability and known uses should be done before considering it. That CAT was
forked out by Satoshi is of limited relevance as the variant proposed for
reintroduction would not have the vulnerability present initially.
Complimentary Upgrades
Pairings of upgrades can work together to deliver functionality that neither
could alone:
- CAT + CSFS: full blown arbitrary covenants
- With arbitrary covenants you can deploy many different kinds of smart
contracts which are out of scope for this article.
- CAT + CTV: Expanded covenants
- slightly simpler to use interface but fewer features than CSFS + CAT which can
covenant over witness data and inputs.
- CTV + CSFS: Eltoo
- This can add very similar functionality to eltoo with the script fragment:
CTV <musig(pka, pkb)> CSFS <S+1> CLTV
The protocol is essentially identical to the Eltoo paper, however there are
a couple subtle differences required for dynamic fee rates.
- CTV + APO: Slightly Different
- Several sources have claimed that APO offers a strict superset
of CTV’s functionality (but not efficiency). This is false. Their digests
are slightly different, as such there are some niche smart contracts that could
use the differences in commitment structure for interesting effects (CTV
commits to all scriptsigs and sequences, APO cannot cover that data but can
cover a few variants of less data covered).
By all means not an exhaustive list – feel free to message me with additions.
Recommendation
My recommendation is to deliver the upgrades described in this document in the
following order:
- CTV
- CSFS
- APO
- CAT/SHASTREAM/SUBSTRING/etc
This recommendation comes as a synthesis of the thoughts above on the
composability, safety, and open design considerations of the various proposals
currently in flight.
With CTV in place, we can begin experimenting with a wide variety of contracts
using the Sapio toolchain, as well as improve and invest in maturing the
toolchain. Mature toolchains will make it easier to safely engineer and deploy
applications making use of CTV and future upgrades.
CSFS is an independent change that can be deployed/developed in parallel to or
before CTV, the implementation from Elements could be easily ported to Bitcoin.
With CSFS and CTV, Eltoo-like constructions will be possible as well.
APO can then be deployed as an optimization to existing use patterns driven by
market adoption of CTV+CSFS based use. This also gives us time to kick the can
down the road on the design questions that APO prompts around generalization of
signature digests and key reuse safety. A similar approach was discussed on
the mailing
list,
but without the insight that CSFS + CTV was sufficient for Eltoo like
constructions, requiring CAT instead.
Lastly, OP_CAT can be delivered as part of an effort towards generalized
arbitrary covenants and perhaps in conjunction with some special purpose
opcodes (such as OP_CHECKINPUT) that can more easily handle common cases. CAT,
although it has safe implementations used in Elements, deserves very strict
scrutiny given it’s documented surprising uses.
This approach represents a gradual relaxation of Bitcoin’s restrictions around
smart contract programming that introduces useful, safe primitives and gives
the community time to build and deploy useful infrastructure. The path
described in this post is an opportunity to upgrade bitcoin with simple
primitives that compose nicely for permissionless innovation.
Thanks to those who reviewed drafts of this post and provided valuable
feedback improving the clarity and accuracy of this post, including
pyskell, Keagan
McClelland, Ryan
Gentry, and Olaoluwa
Osuntokun. Edit + Feedback ≠ Endorsement.