Subject: Re: [bitcoin-dev] Version 1 witness programs (first draft)

From: Luke Dashjr <[email-masked]>
Date: Mon, 2 Oct 2017 00:45:22 +0000

On Sunday 01 October 2017 9:32:56 PM Johnson Lau wrote:
> 1. How do we allow further upgrade within v1 witness? Here are some
> options: a. Minor version in witness. (Johnson / Luke) I prefer this way,
> but we may end up with many minor versions. b. OP_RETURNTRUE (Luke). I
> proposed this in an earlier version of BIP114 but now I think it doesn’t
> interact well with signature aggregation, and I worry that it would have
> some other unexpected effects. c. Generalised NOP method: user has to
> provide the returned value, so even VERIFY-type code could do anything

I like (A) and (B). Use B when practical, and (A) when more fundamental 
changes are needed. SigAgg is a concern, but there are ways to adapt it.

(C) is harmless, but I think unnecessary with (A) and/or (B).

> 2. Do we want to allow signature-time commitment of extra scripts?
> I think all proposals allow this, just with different way
> a. Tail-call semantics with CHECKSIGFROMSTACK (Mark). I think this is too
> rigid as it works only with specially designed scriptPubKey b.
> scriptWitCode: extra scripts are put in some fixed location in witness
> (Johnson). This makes sure static analysability. c. Extra-data as script
> in OP_CHECKSIG (Luke)

Note that my BIP draft supports both (A) and (C).

> 3. Do we want to allow static analysis of sigop?
> BIP114 and the related proposals are specifically designed to allow static
> analysis of sigop. I think this was one of the main reason of OP_EVAL not
> being accepted. This was also the main reason of Ethereum failing to do a
> DAO hacker softfork, leading to the ETH/ETC split. I’m not sure if we
> really want to give up this property. Once we do it, we have to support it
> forever.

It seems inevitable at this point. Maybe we could add a separate "executable-
witness" array (in the same manner as the current witness was softforked in), 
and require tail-call and condition scripts to merely reference these by hash, 
but I'm not sure it's worth the effort?

Thinking further, we could avoid adding a separate executable-witness 
commitment by either:
A) Define that all the witness elements in v1 are type-tagged (put the minor
   witness version on them all, and redefine minor 0 as a stack item?); or
B) Use an empty element as a delimiter between stack and executable items.

To avoid witness malleability, the executable items can be required to be 
sorted in some manner.

The downside of these approaches is that we now need an addition 20 or 32 
bytes per script reference... which IMO may possibly be worse than losing 
static analysis. I wonder if there's a way to avoid that overhead?

Luke