OP_RETURN inside TapScript

OP_RETURN inside TapScript
2022-02-24 10:08 ` Ruben Somsen
                   ` (2 more replies)
  
From: vjudeu @ 2022-02-24  9:02 UTC (permalink / raw)
  To: bitcoin-dev

[-- Attachment #1: Type: text/plain, Size: 898 bytes --]

Since Taproot was activated, we no longer need separate OP_RETURN outputs to be pushed on-chain. If we want to attach any data to a transaction, we can create "OP_RETURN <anything>" as a branch in the TapScript. In this way, we can store that data off-chain and we can always prove that they are connected with some taproot address, that was pushed on-chain. Also, we can store more than 80 bytes for "free", because no such taproot branch will be ever pushed on-chain and used as an input. That means we can use "OP_RETURN <1.5 GB of data>", create some address having that taproot branch, and later prove to anyone that such "1.5 GB of data" is connected with our taproot address.
 
Currently in Bitcoin Core we have "data" field in "createrawtransaction". Should the implementation be changed to place that data in a TapScript instead of creating separate OP_RETURN output? What do you think?

[-- Attachment #2: Type: text/html, Size: 949 bytes --]

 permalink raw reply	[|nested]
2022-02-24 10:08 ` 
                   ` 
  
From: vjudeu @ 2022-02-24  9:02 UTC (permalink / raw)
  To: bitcoin-dev

[-- Attachment #1: Type: text/plain, Size: 898 bytes --]

Since Taproot was activated, we no longer need separate OP_RETURN outputs to be pushed on-chain. If we want to attach any data to a transaction, we can create "OP_RETURN <anything>" as a branch in the TapScript. In this way, we can store that data off-chain and we can always prove that they are connected with some taproot address, that was pushed on-chain. Also, we can store more than 80 bytes for "free", because no such taproot branch will be ever pushed on-chain and used as an input. That means we can use "OP_RETURN <1.5 GB of data>", create some address having that taproot branch, and later prove to anyone that such "1.5 GB of data" is connected with our taproot address.
 
Currently in Bitcoin Core we have "data" field in "createrawtransaction". Should the implementation be changed to place that data in a TapScript instead of creating separate OP_RETURN output? What do you think?

[-- Attachment #2: Type: text/html, Size: 949 bytes --]

 permalink raw reply	[|nested]
2022-02-24 10:08 ` Ruben Somsen

  2022-02-24 14:01     ` Ruben Somsen
  
From: vjudeu @ 2022-02-24 13:27 UTC (permalink / raw)
  To: Ruben Somsen, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3819 bytes --]

> Also, tweaking an ECC point (this includes tapscript) in non-deterministic ways also makes it harder to recover from backup, because you can't recover the key without knowing the full commitment.
I don't think so. You can spend coins from taproot by key or by script. If you spend by key, making backup is simple, we have WIF for that. If you spend by script, you only need a part of the tree. So, you can "recover the key without knowing the full commitment", because you can spend coins "without knowing the full commitment". On-chain, you never reveal your "OP_RETURN <data>" or "OP_RETURN <hash>" or "<tapbranch> <tapbranch> <tapbranch> OP_RETURN <chunk_of_data>". Those additional branches are stored only by those who wants their data to be connected with some key, knowing the full script is not needed, because it is not needed for on-chain validation.
> Furthermore, the scheme is not actually equivalent to op_return, because it requires the user to communicate out-of-band to reveal the commitment, whereas with op_return the data is immediately visible (while not popular, BIP47 and various colored coin protocols rely on this).
Yes, but storing that additional data on-chain is not needed. It is expensive. By paying one satoshi per byte, you would pay 0.01 BTC for pushing 1 MB of data. That means 1 BTC for 100 MB of data, so 15 BTC for that 1.5 GB file. And in practice it is the absolute minimum, because you have to wrap your data somehow, you cannot just push 1.5 GB file. By placing that in TapScript, you can use your taproot public key as usual and attach any data into your key for "free", because it takes zero additional bytes on-chain.
On 2022-02-24 11:08:39 user Ruben Somsen <rsomsen@gmail•com> wrote:
Note this has always been possible, and is not specifically related to tapscript. As long as you're committing to an ECC point, you can tweak it to commit data inside it (i.e. pay-to-contract). This includes P2PK and P2PKH.
 
Committing to 1.5GB of data has equally been possible with OP_RETURN <hash>, or even an entire merkle tree of hashes, as is the case with Todd's opentimestamps.
 
Also, tweaking an ECC point (this includes tapscript) in non-deterministic ways also makes it harder to recover from backup, because you can't recover the key without knowing the full commitment.
 
Furthermore, the scheme is not actually equivalent to op_return, because it requires the user to communicate out-of-band to reveal the commitment, whereas with op_return the data is immediately visible (while not popular, BIP47 and various colored coin protocols rely on this).
 
Cheers,
Ruben
 
On Thu, Feb 24, 2022 at 10:19 AM vjudeu via bitcoin-dev <bitcoin-dev@lists•linuxfoundation.org> wrote:
Since Taproot was activated, we no longer need separate OP_RETURN outputs to be pushed on-chain. If we want to attach any data to a transaction, we can create "OP_RETURN <anything>" as a branch in the TapScript. In this way, we can store that data off-chain and we can always prove that they are connected with some taproot address, that was pushed on-chain. Also, we can store more than 80 bytes for "free", because no such taproot branch will be ever pushed on-chain and used as an input. That means we can use "OP_RETURN <1.5 GB of data>", create some address having that taproot branch, and later prove to anyone that such "1.5 GB of data" is connected with our taproot address.
 
Currently in Bitcoin Core we have "data" field in "createrawtransaction". Should the implementation be changed to place that data in a TapScript instead of creating separate OP_RETURN output? What do you think?
_______________________________________________
bitcoin-dev mailing list
bitcoin-dev@lists•linuxfoundation.org
https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev

[-- Attachment #2: Type: text/html, Size: 5092 bytes --]

 permalink raw reply	[|nested]
2022-02-24 13:27   ` vjudeu

  
From: Ruben Somsen @ 2022-02-24 14:01 UTC (permalink / raw)
  To: vjudeu;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 4836 bytes --]

In Q = P + hash(P||commitment)G you cannot spend from Q without knowing
both the private key of P as well as the commitment (i.e. 32 bytes,
assuming the commitment itself is another hash). This is generally not a
problem for tapscript, as the scripts are deterministically generated (i.e.
backing up the policy once is sufficient), but what you are suggesting is
not deterministic. Hope that clarifies things.

On Thu, Feb 24, 2022 at 2:27 PM <vjudeu@gazeta•pl> wrote:

> > Also, tweaking an ECC point (this includes tapscript) in
> non-deterministic ways also makes it harder to recover from backup, because
> you can't recover the key without knowing the full commitment.
>
> I don't think so. You can spend coins from taproot by key or by script. If
> you spend by key, making backup is simple, we have WIF for that. If you
> spend by script, you only need a part of the tree. So, you can "recover the
> key without knowing the full commitment", because you can spend coins
> "without knowing the full commitment". On-chain, you never reveal your
> "OP_RETURN <data>" or "OP_RETURN <hash>" or "<tapbranch> <tapbranch>
> <tapbranch> OP_RETURN <chunk_of_data>". Those additional branches are
> stored only by those who wants their data to be connected with some key,
> knowing the full script is not needed, because it is not needed for
> on-chain validation.
>
> > Furthermore, the scheme is not actually equivalent to op_return, because
> it requires the user to communicate out-of-band to reveal the commitment,
> whereas with op_return the data is immediately visible (while not popular,
> BIP47 and various colored coin protocols rely on this).
>
> Yes, but storing that additional data on-chain is not needed. It is
> expensive. By paying one satoshi per byte, you would pay 0.01 BTC for
> pushing 1 MB of data. That means 1 BTC for 100 MB of data, so 15 BTC for
> that 1.5 GB file. And in practice it is the absolute minimum, because you
> have to wrap your data somehow, you cannot just push 1.5 GB file. By
> placing that in TapScript, you can use your taproot public key as usual and
> attach any data into your key for "free", because it takes zero additional
> bytes on-chain.
>
> On 2022-02-24 11:08:39 user Ruben Somsen <rsomsen@gmail•com> wrote:
>
> Note this has always been possible, and is not specifically related to
> tapscript. As long as you're committing to an ECC point, you can tweak it
> to commit data inside it (i.e. pay-to-contract). This includes P2PK and
> P2PKH.
>
> Committing to 1.5GB of data has equally been possible with OP_RETURN
> <hash>, or even an entire merkle tree of hashes, as is the case with Todd's
> opentimestamps.
>
> Also, tweaking an ECC point (this includes tapscript) in non-deterministic
> ways also makes it harder to recover from backup, because you can't recover
> the key without knowing the full commitment.
>
> Furthermore, the scheme is not actually equivalent to op_return, because
> it requires the user to communicate out-of-band to reveal the commitment,
> whereas with op_return the data is immediately visible (while not popular,
> BIP47 and various colored coin protocols rely on this).
>
> Cheers,
> Ruben
>
>
> On Thu, Feb 24, 2022 at 10:19 AM vjudeu via bitcoin-dev <
> bitcoin-dev@lists•linuxfoundation.org
> <http://../NowaWiadomosc/Do/QlIkBFQ6QUFhIVRZX192dnQBeCtCchE6GhA5LFpLCUc7EVZQVl9dQRIXXR8NCBMbCwIGChJXQFxcXEgcFh8UVVVDEyBdVkE9JVRdEwFhYXVlblhVIkosEAszLR5BQVV7U0MID0BAQUgIGh0RHgAMGAMXBQJfW1sdXRQUQUoDQlAiBFY8>>
> wrote:
>
>> Since Taproot was activated, we no longer need separate OP_RETURN outputs
>> to be pushed on-chain. If we want to attach any data to a transaction, we
>> can create "OP_RETURN <anything>" as a branch in the TapScript. In this
>> way, we can store that data off-chain and we can always prove that they are
>> connected with some taproot address, that was pushed on-chain. Also, we can
>> store more than 80 bytes for "free", because no such taproot branch will be
>> ever pushed on-chain and used as an input. That means we can use "OP_RETURN
>> <1.5 GB of data>", create some address having that taproot branch, and
>> later prove to anyone that such "1.5 GB of data" is connected with our
>> taproot address.
>>
>> Currently in Bitcoin Core we have "data" field in "createrawtransaction".
>> Should the implementation be changed to place that data in a TapScript
>> instead of creating separate OP_RETURN output? What do you think?
>> _______________________________________________
>> bitcoin-dev mailing list
>> bitcoin-dev@lists•linuxfoundation.org
>> <http://../NowaWiadomosc/Do/QlIkBFQ6QUFhIVRZX192dnQBeCtCchE6GhA5LFpLCUc7EVZQVl9dQRIXXR8NCBMbCwIGChJXQFxcXEgcFh8UVVVDEyBdVkE9JVRdEwFhYXVlblhVIkosEAszLR5BQVV7U0MID0BAQUgIGh0RHgAMGAMXBQJfW1sdXRQUQUoDQlAiBFY8>
>> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>
>

[-- Attachment #2: Type: text/html, Size: 5981 bytes --]

 permalink raw reply	[|nested]
2022-02-24  9:02 [bitcoin-dev] OP_RETURN inside TapScript vjudeu
  2022-02-24 10:08 ` Ruben Somsen

  2022-02-25  0:04   ` ZmnSCPxj
  2022-03-16 18:21 ` Peter Todd
  
From: Zac Greenwood @ 2022-02-24 21:40 UTC (permalink / raw)
  To: Bitcoin Protocol Discussion, vjudeu

[-- Attachment #1: Type: text/plain, Size: 1863 bytes --]

Reducing the footprint of storing data on-chain might better be achieved by
*supporting* it.

Currently storing data is wasteful because it is embedded inside an
OP_RETURN within a transaction structure. As an alternative, by supporting
storing of raw data without creating a transaction, waste can be reduced.

Storing data in this way must only be marginally cheaper per on-chain byte
than the current method  using OP_RETURN by applying the appropriate
weight-per-byte for on-chain data.

The intended result is a smaller footprint for on-chain data without making
it cheaper (except marginally in order to disincentivize the use of
OP_RETURN).

Zac


On Thu, 24 Feb 2022 at 10:19, vjudeu via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> Since Taproot was activated, we no longer need separate OP_RETURN outputs
> to be pushed on-chain. If we want to attach any data to a transaction, we
> can create "OP_RETURN <anything>" as a branch in the TapScript. In this
> way, we can store that data off-chain and we can always prove that they are
> connected with some taproot address, that was pushed on-chain. Also, we can
> store more than 80 bytes for "free", because no such taproot branch will be
> ever pushed on-chain and used as an input. That means we can use "OP_RETURN
> <1.5 GB of data>", create some address having that taproot branch, and
> later prove to anyone that such "1.5 GB of data" is connected with our
> taproot address.
>
> Currently in Bitcoin Core we have "data" field in "createrawtransaction".
> Should the implementation be changed to place that data in a TapScript
> instead of creating separate OP_RETURN output? What do you think?
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 2703 bytes --]

 permalink raw reply	[|nested]
2022-02-24 21:40 ` Zac Greenwood

  2022-02-25  1:12     ` Zac Greenwood
  
From: ZmnSCPxj @ 2022-02-25  0:04 UTC (permalink / raw)
  To: Zac Greenwood, Bitcoin Protocol Discussion

Good morning Zac,

> Reducing the footprint of storing data on-chain might better be achieved by *supporting* it.
>
> Currently storing data is wasteful because it is embedded inside an OP_RETURN within a transaction structure. As an alternative, by supporting storing of raw data without creating a transaction, waste can be reduced.

If the data is not embedded inside a transaction, how would I be able to pay a miner to include the data on the blockchain?

I need a transaction in order to pay a miner anyway, so why not just embed it into the same transaction I am using to pay the miner?
(i.e. the current design)




Regards,
ZmnSCPxj


 permalink raw reply	[|nested]
2022-02-25  0:04   ` ZmnSCPxj

  2022-02-25  3:19       ` ZmnSCPxj
  
From: Zac Greenwood @ 2022-02-25  1:12 UTC (permalink / raw)
  To: ZmnSCPxj;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 1486 bytes --]

Hi ZmnSCPxj,

Any benefits of my proposal depend on my presumption that using a standard
transaction for storing data must be inefficient. Presumably a transaction
takes up significantly more on-chain space than the data it carries within
its OP_RETURN. Therefore, not requiring a standard transaction for data
storage should be more efficient. Facilitating data storage within some
specialized, more space-efficient data structure at marginally lower fee
per payload-byte should enable reducing the footprint of storing data
on-chain.

In case storing data through OP_RETURN embedded within a transaction is
optimal in terms of on-chain footprint then my proposal doesn’t seem useful.

Zac

On Fri, 25 Feb 2022 at 01:05, ZmnSCPxj <ZmnSCPxj@protonmail•com> wrote:

> Good morning Zac,
>
> > Reducing the footprint of storing data on-chain might better be achieved
> by *supporting* it.
> >
> > Currently storing data is wasteful because it is embedded inside an
> OP_RETURN within a transaction structure. As an alternative, by supporting
> storing of raw data without creating a transaction, waste can be reduced.
>
> If the data is not embedded inside a transaction, how would I be able to
> pay a miner to include the data on the blockchain?
>
> I need a transaction in order to pay a miner anyway, so why not just embed
> it into the same transaction I am using to pay the miner?
> (i.e. the current design)
>
>
>
>
> Regards,
> ZmnSCPxj
>

[-- Attachment #2: Type: text/html, Size: 2688 bytes --]

 permalink raw reply	[|nested]
2022-02-25  1:12     ` Zac Greenwood

  2022-02-25  7:15         ` Zac Greenwood
  
From: ZmnSCPxj @ 2022-02-25  3:19 UTC (permalink / raw)
  To: Zac Greenwood;  Bitcoin Protocol Discussion

Good morning Zac,

> Hi ZmnSCPxj,
>
> Any benefits of my proposal depend on my presumption that using a standard transaction for storing data must be inefficient. Presumably a transaction takes up significantly more on-chain space than the data it carries within its OP_RETURN. Therefore, not requiring a standard transaction for data storage should be more efficient. Facilitating data storage within some specialized, more space-efficient data structure at marginally lower fee per payload-byte should enable reducing the footprint of storing data on-chain.
>
> In case storing data through OP_RETURN embedded within a transaction is optimal in terms of on-chain footprint then my proposal doesn’t seem useful.

You need to have some assurance that, if you pay a fee, this data gets on the blockchain.
And you also need to pay a fee for the blockchain space.
In order to do that, you need to indicate an existing UTXO, and of course you have to provably authorize the spend of that UTXO.
But that is already an existing transaction structure, the transaction input.
If you are not going to pay an entire UTXO for it, you need a transaction output as well to store the change.

Your signature needs to cover the data being published, and it is more efficient to have a single signature that covers the transaction input, the transaction output, and the data being published.
We already have a structure for that, the transaction.

So an `OP_RETURN` transaction output is added and you put published data there, and existing constructions make everything Just Work (TM).

Now I admit we can shave off some bytes.
Pure published data does not need an amount, and using a transaction output means there is always an amount field.
We do not want the `OP_RETURN` opcode itself, though if the data is variable-size we do need an equivalent to the `OP_PUSH` opcode (which has many variants depending on the size of the data).

But that is not really a lot of bytes, and adding a separate field to the transaction would require a hardfork.
We cannot use the SegWit technique of just adding a new field that is not serialized for `txid` and `wtxid` calculations, but is committed in a new id, let us call it `dtxid`, and a new Merkle Tree added to the coinbase.
If we *could*, then a separate field for data publication would be softforkable, but the technique does not apply here.
The reason we cannot use that technique is that we want to save bytes by having the signature cover the data to be published, and signatures need to be validated by pre-softfork nodes looking at just the data committed to in `wtxid`.
If you have a separate signature that is in the `dtxid`, then you spend more actual bytes to save a few bytes.

Saving a few bytes for an application that is arguably not the "job" of Bitcoin (Bitcoin is supposed to be for value transfer, not data archiving) is not enough to justify a **hard**fork.
And any softfork seems likely to spend more bytes than what it could save.

Regards,
ZmnSCPxj


 permalink raw reply	[|nested]
2022-02-25  3:19       ` ZmnSCPxj

  2022-02-25 12:48           ` ZmnSCPxj
  
From: Zac Greenwood @ 2022-02-25  7:15 UTC (permalink / raw)
  To: ZmnSCPxj;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 4159 bytes --]

Hi ZmnSCPxj,

To me it seems that more space can be saved.

The data-“transaction” need not specify any output. The network could
subtract the fee amount of the transaction directly from the specified
UTXO. A fee also need not to be specified. It can be calculated in advance
both by the network and the transaction sender based on the size of the
data.

The calculation of the fee should be such that it only marginally cheaper
to use this new construct over using one or more transactions. For
instance, sending 81 bytes should cost as much as two OP_RETURN
transactions (minus some marginal discount to incentivize the use of this
more efficient way to store data).

If the balance of the selected UTXO is insufficient to pay for the data
then the transaction will be invalid.

I can’t judge whether this particular approach would require a hardfork,
sadly.

Zac


On Fri, 25 Feb 2022 at 04:19, ZmnSCPxj <ZmnSCPxj@protonmail•com> wrote:

> Good morning Zac,
>
> > Hi ZmnSCPxj,
> >
> > Any benefits of my proposal depend on my presumption that using a
> standard transaction for storing data must be inefficient. Presumably a
> transaction takes up significantly more on-chain space than the data it
> carries within its OP_RETURN. Therefore, not requiring a standard
> transaction for data storage should be more efficient. Facilitating data
> storage within some specialized, more space-efficient data structure at
> marginally lower fee per payload-byte should enable reducing the footprint
> of storing data on-chain.
> >
> > In case storing data through OP_RETURN embedded within a transaction is
> optimal in terms of on-chain footprint then my proposal doesn’t seem useful.
>
> You need to have some assurance that, if you pay a fee, this data gets on
> the blockchain.
> And you also need to pay a fee for the blockchain space.
> In order to do that, you need to indicate an existing UTXO, and of course
> you have to provably authorize the spend of that UTXO.
> But that is already an existing transaction structure, the transaction
> input.
> If you are not going to pay an entire UTXO for it, you need a transaction
> output as well to store the change.
>
> Your signature needs to cover the data being published, and it is more
> efficient to have a single signature that covers the transaction input, the
> transaction output, and the data being published.
> We already have a structure for that, the transaction.
>
> So an `OP_RETURN` transaction output is added and you put published data
> there, and existing constructions make everything Just Work (TM).
>
> Now I admit we can shave off some bytes.
> Pure published data does not need an amount, and using a transaction
> output means there is always an amount field.
> We do not want the `OP_RETURN` opcode itself, though if the data is
> variable-size we do need an equivalent to the `OP_PUSH` opcode (which has
> many variants depending on the size of the data).
>
> But that is not really a lot of bytes, and adding a separate field to the
> transaction would require a hardfork.
> We cannot use the SegWit technique of just adding a new field that is not
> serialized for `txid` and `wtxid` calculations, but is committed in a new
> id, let us call it `dtxid`, and a new Merkle Tree added to the coinbase.
> If we *could*, then a separate field for data publication would be
> softforkable, but the technique does not apply here.
> The reason we cannot use that technique is that we want to save bytes by
> having the signature cover the data to be published, and signatures need to
> be validated by pre-softfork nodes looking at just the data committed to in
> `wtxid`.
> If you have a separate signature that is in the `dtxid`, then you spend
> more actual bytes to save a few bytes.
>
> Saving a few bytes for an application that is arguably not the "job" of
> Bitcoin (Bitcoin is supposed to be for value transfer, not data archiving)
> is not enough to justify a **hard**fork.
> And any softfork seems likely to spend more bytes than what it could save.
>
> Regards,
> ZmnSCPxj
>

[-- Attachment #2: Type: text/html, Size: 6966 bytes --]

 permalink raw reply	[|nested]
2022-02-25  7:15         ` Zac Greenwood

  2022-02-25 13:53             ` Zac Greenwood
  
From: ZmnSCPxj @ 2022-02-25 12:48 UTC (permalink / raw)
  To: Zac Greenwood;  Bitcoin Protocol Discussion

Good morning Zac,

> Hi ZmnSCPxj,
>
> To me it seems that more space can be saved.
>
> The data-“transaction” need not specify any output. The network could subtract the fee amount of the transaction directly from the specified UTXO.

That is not how UTXO systems like Bitcoin work.
Either you consume the entire UTXO (take away the "U" from the "UTXO") completely and in full, or you do not touch the UTXO (and cannot get fees from it).

> A fee also need not to be specified.

Fees are never explicit in Bitcoin; it is always the difference between total input amount minus the total output amount.

> It can be calculated in advance both by the network and the transaction sender based on the size of the data.

It is already implicitly calculated by the difference between the total input amount minus the total output amount.

You seem to misunderstand as well.
Fee rate is computed from the fee (computed from total input minus total output) divided by the transaction weight.
Nodes do not compute fees from feerate and weight.

> The calculation of the fee should be such that it only marginally cheaper to use this new construct over using one or more transactions. For instance, sending 81 bytes should cost as much as two OP_RETURN transactions (minus some marginal discount to incentivize the use of this more efficient way to store data).

Do you want to change weight calculations?
*reducing* weight calculations is a hardfork, increasing it is a softfork.

> If the balance of the selected UTXO is insufficient to pay for the data then the transaction will be invalid.
>
> I can’t judge whether this particular approach would require a hardfork, sadly.

See above note, if you want to somehow reduce the weight of the data so as to reduce the cost of data relative to `OP_RETURN`, that is a hardfork.

Regards,
ZmnSCPxj


 permalink raw reply	[|nested]
2022-02-25 12:48           ` ZmnSCPxj

  
From: Zac Greenwood @ 2022-02-25 13:53 UTC (permalink / raw)
  To: ZmnSCPxj;  Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3431 bytes --]

Hi ZmnSCPxj,

> Either you consume the entire UTXO (take away the "U" from the "UTXO")
completely and in full, or you do not touch the UTXO

Ok, so enabling spending a UTXO partly would be a significant departure
from the systems’ design philosophy.

I have been unclear about the fee part. In my proposal there’s only one
input and zero outputs, so normally there would be no way to set any fee.
One could add a fee field although that would be slightly wasteful — it may
be sufficient to just specify the fee *rate*, for instance 0-255
sat/payload_byte, requiring only one byte for the fee. The calculation of
the actual fee can be performed by both the network and the sender. The fee
equals payload_size*feerate +
an-amount-calculated-by-preset-rules-such-that-it-raises-the-cost-of-the-transaction-to-only-marginally-less-than-what-it
would-have-cost-to-store-the-same-amount-of-data-using-one-or-more-OP_RETURN-transactions.

However explicitly specifying the fee amount is probably preferable for the
sake of transparency.

I wonder if this proposal could technically work. I fully recognize though
that even if it would, it has close to zero chances becoming reality as it
breaks the core design based on *U*TXOs (and likely also a lot of existing
software) — thank you for pointing that out and for your helpful feedback.

Zac


On Fri, 25 Feb 2022 at 13:48, ZmnSCPxj <ZmnSCPxj@protonmail•com> wrote:

> Good morning Zac,
>
> > Hi ZmnSCPxj,
> >
> > To me it seems that more space can be saved.
> >
> > The data-“transaction” need not specify any output. The network could
> subtract the fee amount of the transaction directly from the specified UTXO.
>
> That is not how UTXO systems like Bitcoin work.
> Either you consume the entire UTXO (take away the "U" from the "UTXO")
> completely and in full, or you do not touch the UTXO (and cannot get fees
> from it).
>
> > A fee also need not to be specified.
>
> Fees are never explicit in Bitcoin; it is always the difference between
> total input amount minus the total output amount.
>
> > It can be calculated in advance both by the network and the transaction
> sender based on the size of the data.
>
> It is already implicitly calculated by the difference between the total
> input amount minus the total output amount.
>
> You seem to misunderstand as well.
> Fee rate is computed from the fee (computed from total input minus total
> output) divided by the transaction weight.
> Nodes do not compute fees from feerate and weight.
>
> > The calculation of the fee should be such that it only marginally
> cheaper to use this new construct over using one or more transactions. For
> instance, sending 81 bytes should cost as much as two OP_RETURN
> transactions (minus some marginal discount to incentivize the use of this
> more efficient way to store data).
>
> Do you want to change weight calculations?
> *reducing* weight calculations is a hardfork, increasing it is a softfork.
>
> > If the balance of the selected UTXO is insufficient to pay for the data
> then the transaction will be invalid.
> >
> > I can’t judge whether this particular approach would require a hardfork,
> sadly.
>
> See above note, if you want to somehow reduce the weight of the data so as
> to reduce the cost of data relative to `OP_RETURN`, that is a hardfork.
>
> Regards,
> ZmnSCPxj
>

[-- Attachment #2: Type: text/html, Size: 5872 bytes --]

 permalink raw reply	[|nested]
2022-02-24  9:02 [bitcoin-dev] OP_RETURN inside TapScript vjudeu
  2022-02-24 10:08 ` Ruben Somsen
  2022-02-24 21:40 ` Zac Greenwood

  2022-03-19 18:32   ` vjudeu
  
From: Peter Todd @ 2022-03-16 18:21 UTC (permalink / raw)
  To: vjudeu, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 989 bytes --]

On Thu, Feb 24, 2022 at 10:02:08AM +0100, vjudeu via bitcoin-dev wrote:
> Since Taproot was activated, we no longer need separate OP_RETURN outputs to be pushed on-chain. If we want to attach any data to a transaction, we can create "OP_RETURN <anything>" as a branch in the TapScript. In this way, we can store that data off-chain and we can always prove that they are connected with some taproot address, that was pushed on-chain. Also, we can store more than 80 bytes for "free", because no such taproot branch will be ever pushed on-chain and used as an input. That means we can use "OP_RETURN <1.5 GB of data>", create some address having that taproot branch, and later prove to anyone that such "1.5 GB of data" is connected with our taproot address.

There are two use-cases for OP_RETURN: committing to data, and publishing data.
Your proposal can only do the former, not the latter, and there are use-cases
for both.

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

 permalink raw reply	[|nested]
2022-03-16 18:21 ` Peter Todd

  2022-03-21 11:00     ` Kostas Karasavvas
  
From: vjudeu @ 2022-03-19 18:32 UTC (permalink / raw)
  To: Peter Todd, Bitcoin Protocol Discussion

> There are two use-cases for OP_RETURN: committing to data, and publishing data. Your proposal can only do the former, not the latter, and there are use-cases for both.

Only the former is needed. Pushing data on-chain is expensive and that kind of data is useful only to the transaction maker. Also, the latter can be pushed on a separate chain (or even a separate layer that is not a chain at all).

Also note that since Taproot we have the latter: we can spend by TapScript and reveal some public key and tapbranches. It is possible to push more than 80 bytes in this way, so why direct OP_RETURN is needed, except for backward-compatibility? (for example in Segwit commitments)

There is only one problem with spending by TapScript, when it comes to publishing data: only the first item is the public key. If we could use public keys instead of tapbranch hashes, we could literally replace "OP_RETURN <commitment>" with "<tweakedPublicKey> <tweakedTapBranchKey1> <tweakedTapBranchKey2> <tweakedTapBranchKey3> ... <tweakedTapBranchKeyN>". Then, we could use unspendable public keys to push data, so OP_RETURN would be obsolete.

By the way, committing to data has a lot of use cases, for example the whole idea of NameCoin could be implemented on such OP_RETURN's. Instead of creating some special transaction upfront, people could place some hidden commitment and reveal that later. Then, there would be no need to produce any new coins out of thin air, because everything would be merge-mined by default, providing Bitcoin-level Proof of Work protection all the time, 24/7/365. Then, people could store that revealed commitments on their own chain, just to keep track of who owns which name. And then, that network could easily turn on and off all Bitcoin features as they please. Lightning Network on NameCoin? No problem, even the same satoshis could be used to pay for domains!

On 2022-03-16 19:21:37 user Peter Todd <pete@petertodd•org> wrote:
> On Thu, Feb 24, 2022 at 10:02:08AM +0100, vjudeu via bitcoin-dev wrote:
> Since Taproot was activated, we no longer need separate OP_RETURN outputs to be pushed on-chain. If we want to attach any data to a transaction, we can create "OP_RETURN <anything>" as a branch in the TapScript. In this way, we can store that data off-chain and we can always prove that they are connected with some taproot address, that was pushed on-chain. Also, we can store more than 80 bytes for "free", because no such taproot branch will be ever pushed on-chain and used as an input. That means we can use "OP_RETURN <1.5 GB of data>", create some address having that taproot branch, and later prove to anyone that such "1.5 GB of data" is connected with our taproot address.

There are two use-cases for OP_RETURN: committing to data, and publishing data.
Your proposal can only do the former, not the latter, and there are use-cases
for both.

-- 
https://petertodd.org 'peter'[:-1]@petertodd.org



 permalink raw reply	[|nested]
2022-03-19 18:32   ` vjudeu

  
From: Kostas Karasavvas @ 2022-03-21 11:00 UTC (permalink / raw)
  To: vjudeu, Bitcoin Protocol Discussion

[-- Attachment #1: Type: text/plain, Size: 3835 bytes --]

Hi vjudeu,

There are use cases where your following assumption is wrong:  ".. and that
kind of data is useful only to the transaction maker."

No one really publishes the actual data with an OP_RETURN. They publish the
hash (typically merkle root) of that 1.5 GB of data. So the overhead is
just 32 bytes for arbitrarily large data sets. What you gain with these 32
bytes is that your hash is visible to anyone and they can verify it without
active participation of the hash publisher.

Regards,
Kostas


On Sat, Mar 19, 2022 at 9:26 PM vjudeu via bitcoin-dev <
bitcoin-dev@lists•linuxfoundation.org> wrote:

> > There are two use-cases for OP_RETURN: committing to data, and
> publishing data. Your proposal can only do the former, not the latter, and
> there are use-cases for both.
>
> Only the former is needed. Pushing data on-chain is expensive and that
> kind of data is useful only to the transaction maker. Also, the latter can
> be pushed on a separate chain (or even a separate layer that is not a chain
> at all).
>
> Also note that since Taproot we have the latter: we can spend by TapScript
> and reveal some public key and tapbranches. It is possible to push more
> than 80 bytes in this way, so why direct OP_RETURN is needed, except for
> backward-compatibility? (for example in Segwit commitments)
>
> There is only one problem with spending by TapScript, when it comes to
> publishing data: only the first item is the public key. If we could use
> public keys instead of tapbranch hashes, we could literally replace
> "OP_RETURN <commitment>" with "<tweakedPublicKey> <tweakedTapBranchKey1>
> <tweakedTapBranchKey2> <tweakedTapBranchKey3> ... <tweakedTapBranchKeyN>".
> Then, we could use unspendable public keys to push data, so OP_RETURN would
> be obsolete.
>
> By the way, committing to data has a lot of use cases, for example the
> whole idea of NameCoin could be implemented on such OP_RETURN's. Instead of
> creating some special transaction upfront, people could place some hidden
> commitment and reveal that later. Then, there would be no need to produce
> any new coins out of thin air, because everything would be merge-mined by
> default, providing Bitcoin-level Proof of Work protection all the time,
> 24/7/365. Then, people could store that revealed commitments on their own
> chain, just to keep track of who owns which name. And then, that network
> could easily turn on and off all Bitcoin features as they please. Lightning
> Network on NameCoin? No problem, even the same satoshis could be used to
> pay for domains!
>
> On 2022-03-16 19:21:37 user Peter Todd <pete@petertodd•org> wrote:
> > On Thu, Feb 24, 2022 at 10:02:08AM +0100, vjudeu via bitcoin-dev wrote:
> > Since Taproot was activated, we no longer need separate OP_RETURN
> outputs to be pushed on-chain. If we want to attach any data to a
> transaction, we can create "OP_RETURN <anything>" as a branch in the
> TapScript. In this way, we can store that data off-chain and we can always
> prove that they are connected with some taproot address, that was pushed
> on-chain. Also, we can store more than 80 bytes for "free", because no such
> taproot branch will be ever pushed on-chain and used as an input. That
> means we can use "OP_RETURN <1.5 GB of data>", create some address having
> that taproot branch, and later prove to anyone that such "1.5 GB of data"
> is connected with our taproot address.
>
> There are two use-cases for OP_RETURN: committing to data, and publishing
> data.
> Your proposal can only do the former, not the latter, and there are
> use-cases
> for both.
>
> --
> https://petertodd.org 'peter'[:-1]@petertodd.org
>
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation.org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>

[-- Attachment #2: Type: text/html, Size: 4839 bytes --]

 permalink raw reply	[|nested]