Subject: Re: [bitcoin-dev] bitcoin scripting and lisp

From: ZmnSCPxj <[email-masked]>
Date: Tue, 08 Mar 2022 03:06:43 +0000

Good morning aj et al.,

> > They're radically different approaches and
> > it's hard to see how they mix. Everything in lisp is completely sandboxed,
> > and that functionality is important to a lot of things, and it's really
> > normal to be given a reveal of a scriptpubkey and be able to rely on your
> > parsing of it.
>
> The above prevents combining puzzles/solutions from multiple coin spends,
> but I don't think that's very attractive in bitcoin's context, the way
> it is for chia. I don't think it loses much else?

But cross-input signature aggregation is a nice-to-have we want for Bitcoin, and, to me, cross-input sigagg is not much different from cross-input puzzle/solution compression.

For example you might have multiple HTLCs, with mostly the same code except for details like who the acceptor and offerrer are, exact hash, and timelock, and you could claim multiple HTLCs in a single tx and feed the details separately but the code for the HTLC is common to all of the HTLCs.
You do not even need to come from the same protocol if multiple protocols use the same code for implementing HTLC.

> > > There's two ways to think about upgradability here; if someday we want
> > > to add new opcodes to the language -- perhaps something to validate zero
> > > knowledge proofs or calculate sha3 or use a different ECC curve, or some
> > > way to support cross-input signature aggregation, or perhaps it's just
> > > that some snippets are very widely used and we'd like to code them in
> > > C++ directly so they validate quicker and don't use up as much block
> > > weight. One approach is to just define a new version of the language
> > > via the tapleaf version, defining new opcodes however we like.
> > > A nice side benefit of sticking with the UTXO model is that the soft fork
> > > hook can be that all unknown opcodes make the entire thing automatically
> > > pass.
>
> I don't think that works well if you want to allow the spender (the
> puzzle solution) to be able to use opcodes introduced in a soft-fork
> (eg, for graftroot-like behaviour)?

This does not apply to current Bitcoin since we no longer accept a SCRIPT from the spender, we now have a witness stack.
However, once we introduce opcodes that allow recursive covenants, it seems this is now a potential footgun if the spender can tell the puzzle SCRIPT to load some code that will then be used in the *next* UTXO created, and *then* the spender can claim it.

Hmmm.... Or maybe not?
If the spender can already tell the puzzle SCRIPT to send the funds to a SCRIPT that is controlled by the spender, the spender can already tell the puzzle SCRIPT to forward the funds to a pubkey the spender controls.
So this seems to be more like "do not write broken SCRIPTs"?

> > > > - serialization seems to be a bit verbose -- 100kB of serialized clvm
> > > >    code from a random block gzips to 60kB; optimising the serialization
> > > >    for small lists, and perhaps also for small literal numbers might be
> > > >    a feasible improvement; though it's not clear to me how frequently
> > > >    serialization size would be the limiting factor for cost versus
> > > >    execution time or memory usage.
> > > > A lot of this is because there's a hook for doing compression at the consensus layer which isn't being used aggressively yet. That one has the downside that the combined cost of transactions can add up very nonlinearly, but when you have constantly repeated bits of large boilerplate it gets close and there isn't much of an alternative. That said even with that form of compression maxxed out it's likely that gzip could still do some compression but that would be better done in the database and in wire protocol formats rather than changing the format which is hashed at the consensus layer.
> > > > How different is this from "jets" as proposed in Simplicity?
>
> Rather than a "transaction" containing "inputs/outputs", chia has spend
> bundles that spend and create coins; and spend bundles can be merged
> together, so that a block only has a single spend bundle. That spend
> bundle joins all the puzzles (the programs that, when hashed match
> the scriptPubKey) and solutions (scriptSigs) for the coins being spent
> together.
>
> I /think/ the compression hook would be to allow you to have the puzzles
> be (re)generated via another lisp program if that was more efficient
> than just listing them out. But I assume it would be turtles, err,
> lisp all the way down, no special C functions like with jets.

Eh, you could use Common LISP or a recent-enough RnRS Scheme to write a cryptocurrency node software, so "special C function" seems to overprivilege C...
I suppose the more proper way to think of this is that jets are *equivalent to* some code in the hosted language, and have an *efficient implementation* in the hosting language.
In this view, the current OG Bitcoin SCRIPT is the hosted language, and the C++ Bitcoin Core interpreter for it is in the hosting language C++.

LISP can be both the hosted and hosting language because it is easy to implement `eval` in LISP and you can write macros which transform small code snippets into larger code.
LISP code generating *more* LISP code is pretty much what macros are.

Regards,
ZmnSCPxj