Anthony Towns [ARCHIVE] on Nostr: 📅 Original date posted:2022-03-10 📝 Original message:On Tue, Mar 08, 2022 at ...
📅 Original date posted:2022-03-10
📝 Original message:On Tue, Mar 08, 2022 at 06:54:56PM -0800, Bram Cohen via bitcoin-dev wrote:
> On Mon, Mar 7, 2022 at 5:27 PM Anthony Towns <aj at erisian.com.au> wrote:
> > One way to match the way bitcoin do things, you could have the "list of
> > extra conditions" encoded explicitly in the transaction via the annex,
> > and then check the extra conditions when the script is executed.
> The conditions are already basically what's in transactions. I think the
> only thing missing is the assertion about one's own id, which could be
> added in by, in addition to passing the scriptpubkey the transaction it's
> part of, also passing in the index of inputs which it itself is.
To redo the singleton pattern in bitcoin's context, I think you'd have
to pass in both the full tx you're spending (to be able to get the
txid of its parent) and the full tx of its parent (to be able to get
the scriptPubKey that your utxo spent) which seems klunky but at least
possible (you'd be able to drop the witness data at least; without that
every tx would be including the entire history of the singleton).
> > > 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 is already the approach to soft forking in Bitcoin script and I don't
> see anything wrong with it.
It's fine in Bitcoin script, because the scriptPubKey already commits to
all the opcodes that can possibly be used for any particular output. With
a lisp approach, however, you could pass in additional code fragments
to execute. For example, where you currently say:
script: [pubkey] CHECKSIG
witness: [64B signature][0x83]
(where 0x83 is SINGLE|ANYONECANPAY) you might translate that to:
script: (checksig pubkey (bip342-txmsg 3) 2)
witness: signature 0x83
where "3" grabs the sighash byte, and "2" grabs the signature. But you
could also translate it to:
script: (checksig pubkey (sha256 3 (a 3)) 2)
witness: signature (bip342-txmsg 0x83)
where "a 3" takes "(bip342-txmsg 0x83)" then evaluates it, and (sha256
3 (a 3)) makes sure you've signed off on both how the message was
constructed as well as what the message was. The advantage there is that
the spender can then create their own signature hashes however they like;
even ones that hadn't been thought of when the output was created.
But what if we later softfork in a bip118-txmsg for quick and easy
ANYPREVOUT style-signatures, and want to use that instead of custom
lisp code? You can't just stick (softfork C (bip118-txmsg 0xc3)) into
the witness, because it will evaluate to nil and you won't be signing
anything. But you *could* change the script to something like:
script: (softfork C (q checksigverify pubkey (a 3) 2))
witness: signature (bip118-txmsg 0xc3)
But what happens if the witness instead has:
script: (softfork C (q checksigverify pubkey (a 3) 2))
witness: fake-signature (fakeopcode 0xff)
If softfork is just doing a best effort for whatever opcodes it knows
about, and otherwise succeeding, then it has to succeed, and your
script/output has become anyone-can-spend.
On the other hand, if you could tell the softfork op that you only wanted
ops up-to-and-including the 118 softfork, then it could reject fakeopcode
and fail the script, which I think gives the desirable behaviour.
Cheers,
aj
📝 Original message:On Tue, Mar 08, 2022 at 06:54:56PM -0800, Bram Cohen via bitcoin-dev wrote:
> On Mon, Mar 7, 2022 at 5:27 PM Anthony Towns <aj at erisian.com.au> wrote:
> > One way to match the way bitcoin do things, you could have the "list of
> > extra conditions" encoded explicitly in the transaction via the annex,
> > and then check the extra conditions when the script is executed.
> The conditions are already basically what's in transactions. I think the
> only thing missing is the assertion about one's own id, which could be
> added in by, in addition to passing the scriptpubkey the transaction it's
> part of, also passing in the index of inputs which it itself is.
To redo the singleton pattern in bitcoin's context, I think you'd have
to pass in both the full tx you're spending (to be able to get the
txid of its parent) and the full tx of its parent (to be able to get
the scriptPubKey that your utxo spent) which seems klunky but at least
possible (you'd be able to drop the witness data at least; without that
every tx would be including the entire history of the singleton).
> > > 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 is already the approach to soft forking in Bitcoin script and I don't
> see anything wrong with it.
It's fine in Bitcoin script, because the scriptPubKey already commits to
all the opcodes that can possibly be used for any particular output. With
a lisp approach, however, you could pass in additional code fragments
to execute. For example, where you currently say:
script: [pubkey] CHECKSIG
witness: [64B signature][0x83]
(where 0x83 is SINGLE|ANYONECANPAY) you might translate that to:
script: (checksig pubkey (bip342-txmsg 3) 2)
witness: signature 0x83
where "3" grabs the sighash byte, and "2" grabs the signature. But you
could also translate it to:
script: (checksig pubkey (sha256 3 (a 3)) 2)
witness: signature (bip342-txmsg 0x83)
where "a 3" takes "(bip342-txmsg 0x83)" then evaluates it, and (sha256
3 (a 3)) makes sure you've signed off on both how the message was
constructed as well as what the message was. The advantage there is that
the spender can then create their own signature hashes however they like;
even ones that hadn't been thought of when the output was created.
But what if we later softfork in a bip118-txmsg for quick and easy
ANYPREVOUT style-signatures, and want to use that instead of custom
lisp code? You can't just stick (softfork C (bip118-txmsg 0xc3)) into
the witness, because it will evaluate to nil and you won't be signing
anything. But you *could* change the script to something like:
script: (softfork C (q checksigverify pubkey (a 3) 2))
witness: signature (bip118-txmsg 0xc3)
But what happens if the witness instead has:
script: (softfork C (q checksigverify pubkey (a 3) 2))
witness: fake-signature (fakeopcode 0xff)
If softfork is just doing a best effort for whatever opcodes it knows
about, and otherwise succeeding, then it has to succeed, and your
script/output has become anyone-can-spend.
On the other hand, if you could tell the softfork op that you only wanted
ops up-to-and-including the 118 softfork, then it could reject fakeopcode
and fail the script, which I think gives the desirable behaviour.
Cheers,
aj