>  Since scriptpubkeys/scriptsigs continue to run ephemerally at validation time full turing completeness is much less dangerous than people fear. 

The covenant proposals I've seen that might give bitcoin turing completeness require a turing complete process to be stepped such that each step is a transaction paid for with a usual fee. This fact I think makes the turing completeness a lot less scary. No single transaction would be turing complete, while a sequence of them could be. But importantly, each transaction has a strictly limited runtime and every script could continue to have a calculable number of maximum runtime steps.

> The main thing missing from what's expressed in transactions themselves is a coherent notion of a single parent of each output instead of the all-inputs-lead-to-all-outputs approach of transactions currently.

I'm curious to hear more about specifically what you mean by this. I think there are covenant proposals that do that. TLUV has the concept of specifying which output should have a script that's "modified" in a particular way. CTV basically specifies a specific output set. My own OP_CONSTRAINDESTINATION also specifies what outputs the value of the input is transferred to. Is this what you mean?

> It would also probably be a good idea to add in a bunch of special purpose opcodes for making coherent statements about transactions since in Bitcoin they're a very complex and hard to parse format.

What are some examples you're thinking of?

> Once you start implementing complex general purpose functionality it tends to get very expensive very fast and is likely impractical unless there's a way to compress or at least de-duplicate snippets of code which are repeated on chain.

I like this idea. If there was a way to dedupe scripts in some way, it could save a lot of bandwidth which would help bitcoin scale better. One thing we could do is have a specific set of pre-ordained script snippets that are given a shorthand that's stored in the software and explicitly shouldn't be transmitted long-hand. That would help for very standard widespread things. We could even add in a consensus rule where short-handed scripts pay for their expanded vbytes, not the vbytes of the compressed version. This would mean the incentives wouldn't be changed by this approach. 

We could also imagine a more dynamic approach, where nodes keep an index of scripts or script snippets in some way, and keep around ones that it sees most often. I'm not sure how this would work, since a script can contain a lot of unique values and there's no clear way to split a script into pieces. Perhaps script segments could be committed to the chain and nodes could attempt to only store and reuse these paid-for segments, maybe only the X most paid-for scripts (the scripts committed with the largest fee, potentially across multiple explicit standalone commitments). However, this dynamic approach would also have some scalability benefits, tho it would be a bit more chaotic. Any node transmitting transactions would only need to send the script segments when the node they're transmitting to requests them. However, the extra script references also take up space, and so if the ratio of how often the node has a script segment to how often they don't is bad enough, this could a net negative scalability wise. 

> For a payment to someone to come with a rider where they could accept it and think their system was working properly for a while until you exercised some kind of retroactive veto on new action or even clawback would obviously be unacceptable behavior.

I definitely agree. A payment's covenant should be completely knowable to the recipient, and recipients shouldn't accept random covenants they haven't explicitly accepted on their own. 

> for payments to come with covenants but the recipient not even be able to parse them unless they're fully buying into that behavior is much more reasonable. 

The recipient not being able to parse them? Couldn't that result in exactly the situation above you said was not acceptable? The recipient must be able to know all the possibilities of the covenant or there might be some secret retroactive clawback in there waiting to bite them.



On Fri, Dec 31, 2021 at 6:41 PM Bram Cohen via bitcoin-dev <bitcoin-dev@lists.linuxfoundation.org> wrote:
There are a few different approaches to adding covenants and capabilities to the UTXO model with varying tradeoffs. It turns out that it can be done while making very few but not quite zero compromises to practices Bitcoin has been following so far.

First, the good news: Full support for both capabilities and covenants can be added without changing the UTXO model whatsoever by adding some more programmatic capabilities to the language and doing some programmatic tricks. Since scriptpubkeys/scriptsigs continue to run ephemerally at validation time full turing completeness is much less dangerous than people fear. The main thing missing from what's expressed in transactions themselves is a coherent notion of a single parent of each output instead of the all-inputs-lead-to-all-outputs approach of transactions currently. It would also probably be a good idea to add in a bunch of special purpose opcodes for making coherent statements about transactions since in Bitcoin they're a very complex and hard to parse format.

Now for the controversial stuff. Once you start implementing complex general purpose functionality it tends to get very expensive very fast and is likely impractical unless there's a way to compress or at least de-duplicate snippets of code which are repeated on chain. Currently Bitcoin has a strong policy that deciding which transactions to let into a block for maximum fee is a strictly linear optimization problem and while it's possible to keep things mostly that way making it completely strict is unlikely to workable. About as close as you can get is to make it so that each block can reference code snippets in previous blocks for deduplication, so at least the optimization is linear for each block by itself.

Having covenants and capabilities at all is controversial in and of itself. With covenants the main issue is whether they're opt-in or opt-out. For a payment to someone to come with a rider where they could accept it and think their system was working properly for a while until you exercised some kind of retroactive veto on new action or even clawback would obviously be unacceptable behavior. But for payments to come with covenants but the recipient not even be able to parse them unless they're fully buying into that behavior is much more reasonable. 

The main issue which people have raised with capabilities is that if you were to have colored coins whose value was substantially greater than the chain they were tokenized on then that could potentially create a business model for attacking the underlying chain. While this is a real concern tokenized assets have been out for a while now and have never come close to causing this to happen, so maybe people aren't so worried about it now.

Given all the above caveats it turns out one weird trick is all you need to support general purpose capabilities: for a UTXO to have a capability its scriptpubkey asserts that its parent must either be the originator of that capability or also conform to the same parent-asserting format. More complex functionality such as supporting on-chain verifiable colored coins can also be done but it follows the same pattern: Capabilities are implemented as backwards pointing covenants.

If you'd like to see a fleshed out implementation of these ideas (albeit in a slightly different model) there's quite a bit of stuff on chialisp.com

_______________________________________________
bitcoin-dev mailing list
bitcoin-dev@lists.linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev