Re: [bitcoin-dev] Vaults in the MATT framework

2023-06-02 Thread Johan Torås Halseth via bitcoin-dev
Hi,

It was briefly mentioned in the original post, but wanted to show how
simple it is to use COCV as an alternative to CTV, removing that
dependency.

> In particular, it also inherits the choice of using OP_CTV as a primitive,
> building on top of the bitcoin-inquisition's current branch that has already
> merged OP_CTV. Reasonable vaults would be possible without CTV, but they
> would be less efficient, particularly in the case of sending to many addresses
> in a single unvaulting flow.

Instead of specifying a CTV hash as embedded data, one could embed the
(commitment to the) outputs of the withdrawal transaction. Then
instead of a single OP_CTV, one OP_COCV per output to match against
the embedded data. Less efficient in case of many outputs as you
mention, but simple enough to be interesting.

Here's an example how to use MATT as a CTV replacement:
https://github.com/halseth/tapsim/blob/b07f29804cf32dce0168ab5bb40558cbb18f2e76/examples/matt/ctv2/README.md

Cheers,
Johan



On Tue, May 2, 2023 at 10:22 AM Salvatore Ingala via bitcoin-dev
 wrote:
>
> Hi Michael,
>
> I can't make any claim of expertise on the field (especially on the
> other proposals that you mentioned), so this post necessarily includes
> my opinions − and possibly my biases.
>
> The core functionality of MATT is quite simple, and could be adapted
> to any version of the scripting system: basically, COCV allows to
> "embed" some data in the next output, and decide its script; CICV
> allows "reading" this data.
> The design I proposed on taproot is surely not the only possible way,
> but it's the most simple/elegant I could come up with. Moreover, it
> doesn't seem very useful to spend time trying to get it to work on
> pre-taproot Script, due to the obvious advantages of those ideas when
> deployed on taproot (like having taptrees, and all the nice properties
> of Schnorr signatures).
>
> CICV/COCV can certainly be considered an additional form of
> introspection: you're checking that the script of an input/output
> equals a certain value, which is not possible in today's Script.
> I think that's generally true for all covenant proposals.
>
> Unlike some other proposals, MATT is not yet fully formalized, so I
> generally call "MATT" the combination of CICV+COCV, plus some other
> small set of opcodes that is yet to be defined exactly. I would say it
> fits in the same family as APO/OP_CTV/OP_VAULT, per your bucketization.
>
> The previous posts about MATT, fraud proofs, etc. are an exploration of
> the deeper things that are enabled by the MATT opcodes. The claim is
> that a set of changes that is (arguably) quite small and easy to analyze
> is enough to express general smart contracts − thanks to fraud proofs.
> However, fraud proofs themselves are a quite advanced application of
> the new opcodes, and are not needed for most/all of the things that
> people are trying to build today with the other covenant proposals.
>
>
> Since you mention Simplicity: my current understanding is that its
> endeavour of replacing Script with a better language is orthogonal to
> the discussion about what features (e.g.: introspection, covenants)
> should be in the language.
>
> All the covenant proposals listed above are technically a lot smaller
> and easier to audit than both the SegWit and the Taproot soft forks,
> both in terms of code and conceptual complexity.
>
> Therefore, if we _do_ want the features that they enable, the required
> engineering for a soft-fork is relatively straightforward, and there is
> not much of a reason to wait for Simplicity. It will be trivial to "port" any
> constructions we might create today with covenants to Simplicity scripts.
>
> If we _do not_ want those features, then the decision would rather be
> guided by other considerations, like potential risks to bitcoin caused
> by the effect of those features on miners' incentives. These
> concerns are not answered by Simplicity, as far as I understand:
> you would then want to implement Simplicity _without_ those features.
>
> Best,
> Salvatore
>
> On Mon, 1 May 2023 at 16:18, Michael Folkson  
> wrote:
>>
>> Hi Salvatore
>>
>> Can you clarify for me which bucket this proposal sits? We have APO, CTV, 
>> OP_VAULT etc that are proposals to add additional functionality to SegWit 
>> version 1, Tapleaf version 0 scripts. We have Simplicity that would need a 
>> new Tapleaf version (e.g. Tapleaf version 1). And then there are CISA like 
>> proposals that would need a new SegWit version (e.g. SegWit version 2). It 
>> looks to me like your proposal is in the first bucket (same as APO, CTV etc) 
>> as it is just introducing new opcode functionality to existing script with 
>> no deeper introspection needed but previous and current discussion of fraud 
>> proofs, MATT frameworks etc made me initially think it was going to require 
>> more than that.
>>
>> Thanks
>> Michael
>>
>> --
>> Michael Folkson
>> Email: michaelfolkson at protonmail.com
>> GPG: A2CF5D71603C9201065981

Re: [bitcoin-dev] Vaults in the MATT framework

2023-05-02 Thread Salvatore Ingala via bitcoin-dev
Hi Michael,

I can't make any claim of expertise on the field (especially on the
other proposals that you mentioned), so this post necessarily includes
my opinions − and possibly my biases.

The core functionality of MATT is quite simple, and could be adapted
to any version of the scripting system: basically, COCV allows to
"embed" some data in the next output, and decide its script; CICV
allows "reading" this data.
The design I proposed on taproot is surely not the only possible way,
but it's the most simple/elegant I could come up with. Moreover, it
doesn't seem very useful to spend time trying to get it to work on
pre-taproot Script, due to the obvious advantages of those ideas when
deployed on taproot (like having taptrees, and all the nice properties
of Schnorr signatures).

CICV/COCV can certainly be considered an additional form of
introspection: you're checking that the script of an input/output
equals a certain value, which is not possible in today's Script.
I think that's generally true for all covenant proposals.

Unlike some other proposals, MATT is not yet fully formalized, so I
generally call "MATT" the combination of CICV+COCV, plus some other
small set of opcodes that is yet to be defined exactly. I would say it
fits in the same family as APO/OP_CTV/OP_VAULT, per your bucketization.

The previous posts about MATT, fraud proofs, etc. are an exploration of
the deeper things that are enabled by the MATT opcodes. The claim is
that a set of changes that is (arguably) quite small and easy to analyze
is enough to express general smart contracts − thanks to fraud proofs.
However, fraud proofs themselves are a quite advanced application of
the new opcodes, and are not needed for most/all of the things that
people are trying to build today with the other covenant proposals.


Since you mention Simplicity: my current understanding is that its
endeavour of replacing Script with a better language is orthogonal to
the discussion about what features (e.g.: introspection, covenants)
should be in the language.

All the covenant proposals listed above are technically a lot smaller
and easier to audit than both the SegWit and the Taproot soft forks,
both in terms of code and conceptual complexity.

Therefore, if we _do_ want the features that they enable, the required
engineering for a soft-fork is relatively straightforward, and there is
not much of a reason to wait for Simplicity. It will be trivial to "port"
any
constructions we might create today with covenants to Simplicity scripts.

If we _do not_ want those features, then the decision would rather be
guided by other considerations, like potential risks to bitcoin caused
by the effect of those features on miners' incentives. These
concerns are not answered by Simplicity, as far as I understand:
you would then want to implement Simplicity _without_ those features.

Best,
Salvatore

On Mon, 1 May 2023 at 16:18, Michael Folkson 
wrote:

> Hi Salvatore
>
> Can you clarify for me which bucket this proposal sits? We have APO, CTV,
> OP_VAULT etc that are proposals to add additional functionality to SegWit
> version 1, Tapleaf version 0 scripts. We have Simplicity that would need a
> new Tapleaf version (e.g. Tapleaf version 1). And then there are CISA like
> proposals that would need a new SegWit version (e.g. SegWit version 2). It
> looks to me like your proposal is in the first bucket (same as APO, CTV
> etc) as it is just introducing new opcode functionality to existing script
> with no deeper introspection needed but previous and current discussion of
> fraud proofs, MATT frameworks etc made me initially think it was going to
> require more than that.
>
> Thanks
> Michael
>
> --
> Michael Folkson
> Email: michaelfolkson at protonmail.com
> GPG: A2CF5D71603C92010659818D2A75D601B23FEE0F
>
> Learn about Bitcoin: https://www.youtube.com/@portofbitcoin
>
> --- Original Message ---
> On Monday, April 24th, 2023 at 20:37, Salvatore Ingala via bitcoin-dev <
> bitcoin-dev@lists.linuxfoundation.org> wrote:
>
> Hello list,
>
> TL;DR: the core opcodes of MATT can build vaults with a very similar design
> to OP_VAULT. Code example here:
>
>
> https://github.com/bitcoin-inquisition/bitcoin/compare/24.0...bigspider:bitcoin-inquisition:matt-vault
>
>
> In my previous emails about the MATT proposal for smart contracts in
> bitcoin [1], I mostly focused on proving its generality; that is, it
> allows arbitrary smart contracts thanks to fraud proofs.
>
> While I still find this "completeness" result compelling, I spent more time
> thinking about the framework itself; the construction is not very
> interesting
> if it turns simple things into complicated ones. Luckily, this is not the
> case.
> In particular, in this email we will not merkleize anything (other than
> taptrees).
>
> This post describes some progress into formalizing the semantics of the
> core
> opcodes, and demonstrates how they could be used to create vaults that seem
> comparable to the ones built 

Re: [bitcoin-dev] Vaults in the MATT framework

2023-05-01 Thread Michael Folkson via bitcoin-dev
Hi Salvatore

Can you clarify for me which bucket this proposal sits? We have APO, CTV, 
OP_VAULT etc that are proposals to add additional functionality to SegWit 
version 1, Tapleaf version 0 scripts. We have Simplicity that would need a new 
Tapleaf version (e.g. Tapleaf version 1). And then there are CISA like 
proposals that would need a new SegWit version (e.g. SegWit version 2). It 
looks to me like your proposal is in the first bucket (same as APO, CTV etc) as 
it is just introducing new opcode functionality to existing script with no 
deeper introspection needed but previous and current discussion of fraud 
proofs, MATT frameworks etc made me initially think it was going to require 
more than that.

Thanks
Michael

--
Michael Folkson
Email: michaelfolkson at [protonmail.com](http://protonmail.com/)
GPG: A2CF5D71603C92010659818D2A75D601B23FEE0F

Learn about Bitcoin: https://www.youtube.com/@portofbitcoin

--- Original Message ---
On Monday, April 24th, 2023 at 20:37, Salvatore Ingala via bitcoin-dev 
 wrote:

> Hello list,
>
> TL;DR: the core opcodes of MATT can build vaults with a very similar design
> to OP_VAULT. Code example here:
>
> https://github.com/bitcoin-inquisition/bitcoin/compare/24.0...bigspider:bitcoin-inquisition:matt-vault
>
> In my previous emails about the MATT proposal for smart contracts in
> bitcoin [1], I mostly focused on proving its generality; that is, it
> allows arbitrary smart contracts thanks to fraud proofs.
>
> While I still find this "completeness" result compelling, I spent more time
> thinking about the framework itself; the construction is not very interesting
> if it turns simple things into complicated ones. Luckily, this is not the 
> case.
> In particular, in this email we will not merkleize anything (other than 
> taptrees).
>
> This post describes some progress into formalizing the semantics of the core
> opcodes, and demonstrates how they could be used to create vaults that seem
> comparable to the ones built with OP_VAULT [2], despite using general purpose
> opcodes.
>
> An implementation and some minimal tests matching the content of this
> e-mail can be found in the link above, using the bitcoin-inquisition as the
> base branch.
>
> Note that the linked code is not well tested and is only intended for
> exploratory and demonstrative purposes; therefore, bugs are likely at this
> stage.
>
> ##
> # PART 1: MATT's core
> ##
>
> In this section, I will discuss plausible semantics for the core opcodes for 
> MATT.
>
> The two core opcodes are defined below as OP_CHECKINPUTCONTRACTVERIFY and
> OP_CHECKOUTPUTCONTRACTVERIFY.
>
> (the initial posts named them OP_CHECK{INPUT,OUTPUT}COVENANTVERIFY)
>
> They enhance Script with the following capabilities:
> - decide the taptree of the output
> - embed some (dynamically computed) data in the output
> - access the embedded data in the current UTXO (if any)
>
> The opcodes below are incomplete, as they only control the output's Script and
> not the amounts; more on that below.
>
> Other than that, the semantics should be quite close to the "right" one for
> the MATT framework.
>
> ### The opcodes
>
> case OP_CHECKINPUTCONTRACTVERIFY:
> {
> // OP_CHECKINPUTCONTRACTVERIFY is only available in Tapscript
> if (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0) 
> return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
> // (x d -- )
> if (stack.size() < 2)
> return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
> valtype& x = stacktop(-2);
> valtype& d = stacktop(-1);
> if (x.size() != 32 || d.size() != 32)
> return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
> const XOnlyPubKey nakedXOnlyKey{Span{x.data(), x.data() 
> + 32}};
> const uint256 data(d);
> if (!execdata.m_internal_key.has_value())
> return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); // TODO
> // Verify that tweak(lift_x(x), d) equals the internal pubkey
> if (!execdata.m_internal_key.value().CheckDoubleTweak(nakedXOnlyKey, &data, 
> nullptr))
> return set_error(serror, SCRIPT_ERR_WRONGCONTRACTDATA);
> popstack(stack);
> popstack(stack);
> }
> break;
> case OP_CHECKOUTPUTCONTRACTVERIFY:
> {
> // OP_CHECKOUTPUTCONTRACTVERIFY is only available in Tapscript
> if (sigversion == SigVersion::BASE || sigversion == SigVersion::WITNESS_V0) 
> return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
> // (out_i x taptree d -- )
> if (stack.size() < 4)
> return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
> int out_i = CScriptNum(stacktop(-4), fRequireMinimal).getint();
> valtype& x = stacktop(-3);
> valtype& taptree = stacktop(-2);
> valtype& d = stacktop(-1);
> auto outps = checker.GetTxvOut();
> // Return error if the evaluation context is unavailable
> if (!outps)
> return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); // TODO
> if (x.size() != 32 || taptree.size() != 32 || (d.size() != 0 && d.size() != 
> 32))
> return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
> if

[bitcoin-dev] Vaults in the MATT framework

2023-04-24 Thread Salvatore Ingala via bitcoin-dev
Hello list,

TL;DR: the core opcodes of MATT can build vaults with a very similar design
to OP_VAULT. Code example here:


https://github.com/bitcoin-inquisition/bitcoin/compare/24.0...bigspider:bitcoin-inquisition:matt-vault


In my previous emails about the MATT proposal for smart contracts in
bitcoin [1], I mostly focused on proving its generality; that is, it
allows arbitrary smart contracts thanks to fraud proofs.

While I still find this "completeness" result compelling, I spent more time
thinking about the framework itself; the construction is not very
interesting
if it turns simple things into complicated ones. Luckily, this is not the
case.
In particular, in this email we will not merkleize anything (other than
taptrees).

This post describes some progress into formalizing the semantics of the core
opcodes, and demonstrates how they could be used to create vaults that seem
comparable to the ones built with OP_VAULT [2], despite using general
purpose
opcodes.

An implementation and some minimal tests matching the content of this
e-mail can be found in the link above, using the bitcoin-inquisition as the
base branch.

Note that the linked code is not well tested and is only intended for
exploratory and demonstrative purposes; therefore, bugs are likely at this
stage.


##
#PART 1: MATT's core
##

In this section, I will discuss plausible semantics for the core opcodes
for MATT.

The two core opcodes are defined below as OP_CHECKINPUTCONTRACTVERIFY and
OP_CHECKOUTPUTCONTRACTVERIFY.

(the initial posts named them OP_CHECK{INPUT,OUTPUT}COVENANTVERIFY)

They enhance Script with the following capabilities:
  - decide the taptree of the output
  - embed some (dynamically computed) data in the output
  - access the embedded data in the current UTXO (if any)

The opcodes below are incomplete, as they only control the output's Script
and
not the amounts; more on that below.

Other than that, the semantics should be quite close to the "right" one for
the MATT framework.


### The opcodes

case OP_CHECKINPUTCONTRACTVERIFY:
{
// OP_CHECKINPUTCONTRACTVERIFY is only available in Tapscript
if (sigversion == SigVersion::BASE || sigversion ==
SigVersion::WITNESS_V0) return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
// (x d -- )
if (stack.size() < 2)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
valtype& x = stacktop(-2);
valtype& d = stacktop(-1);
if (x.size() != 32 || d.size() != 32)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
const XOnlyPubKey nakedXOnlyKey{Span{x.data(),
x.data() + 32}};
const uint256 data(d);
if (!execdata.m_internal_key.has_value())
return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR);  // TODO
// Verify that tweak(lift_x(x), d) equals the internal pubkey
if (!execdata.m_internal_key.value().CheckDoubleTweak(nakedXOnlyKey,
&data, nullptr))
return set_error(serror, SCRIPT_ERR_WRONGCONTRACTDATA);
popstack(stack);
popstack(stack);
}
break;
case OP_CHECKOUTPUTCONTRACTVERIFY:
{
// OP_CHECKOUTPUTCONTRACTVERIFY is only available in Tapscript
if (sigversion == SigVersion::BASE || sigversion ==
SigVersion::WITNESS_V0) return set_error(serror, SCRIPT_ERR_BAD_OPCODE);
// (out_i x taptree d -- )
if (stack.size() < 4)
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
int out_i = CScriptNum(stacktop(-4), fRequireMinimal).getint();
valtype& x = stacktop(-3);
valtype& taptree = stacktop(-2);
valtype& d = stacktop(-1);
auto outps = checker.GetTxvOut();
// Return error if the evaluation context is unavailable
if (!outps)
return set_error(serror, SCRIPT_ERR_UNKNOWN_ERROR); // TODO
if (x.size() != 32 || taptree.size() != 32 || (d.size() != 0 &&
d.size() != 32))
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
if (out_i < 0 || out_i >= (int)outps->size())
return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION);
const XOnlyPubKey nakedXOnlyKey{Span{x.data(),
x.data() + 32}};
const uint256 data(d);
const uint256 *data_ptr = (d.size() == 0 ? nullptr : &data);
const uint256 merkle_tree(taptree);
CScript scriptPubKey = outps->at(out_i).scriptPubKey;
if (scriptPubKey.size() != 1 + 1 + 32 || scriptPubKey[0] != OP_1 ||
scriptPubKey[1] != 32)
return set_error(serror, SCRIPT_ERR_WRONGCONTRACTDATA);
const XOnlyPubKey outputXOnlyKey{Span{scriptPubKey.data() + 2, scriptPubKey.data() + 34}};
// Verify that taptweak(tweak(lift_x(x), d), taptree) equals the
internal pubkey
if (!outputXOnlyKey.CheckDoubleTweak(nakedXOnlyKey, data_ptr,
&merkle_tree))
return set_error(serror, SCRIPT_ERR_WRONGCONTRACTDATA);
popstack(stack);
popstack(stack);
popstack(stack);
popstack(stack);
}
break;

### Commentary

CheckDoubleTweak function (implemented in the branch) gets an x-only pubkey,
optionally so