Anthony Towns [ARCHIVE] on Nostr: 📅 Original date posted:2023-03-02 🗒️ Summary of this message: A proposed ...
📅 Original date posted:2023-03-02
🗒️ Summary of this message: A proposed replacement for two opcodes in Bitcoin involves a new opcode called OP_TRIGGER_FORWARD, which takes three arguments and can be generalized for more flexibility. The proposed opcode can be embedded in a tapscript and used to modify a TLUV-ish script. The existing OP_VAULT cleverness can be used to spend two inputs to the same output, but there is no way to refund values.
📝 Original message:On Wed, Mar 01, 2023 at 10:05:47AM -0500, Greg Sanders via bitcoin-dev wrote:
> Below is a sketch of a replacement for the two opcodes.
I like this! I tried to come up with something along similar lines for
similar reasons, but I think I tried too hard to reduce it to two opcodes
or something and got myself confused.
> `OP_TRIGGER_FORWARD`: Takes exactly three arguments:
> 1) output index to match against (provided at spend time normally)
> 2) target-outputs-hash: 32 byte hash to be forwarded to output given at (1)
> (provided at spend time normally)
> 3) spend-delay: value to be forwarded to output given at (1)
I think you could generalise this as follows:
idx .. npush script OP_FORWARD_LEAF_UPDATE
(OP_FLU :) with the behaviour being:
pop script from the stack
pop npush from the stack (error if non-minimal or <0)
pop npush entries from the stack,
prefix script with a minimal push of that entry
pop idx off the stack (error if idx is not a valid output)
calculate the spk corresponding to taking the current
input's spk and replacing the current leaf with the
given script
check the output at idx matches this spk, and the
value from this input accumulates to that output
Then instead of `idx hash delay OP_TRIGGER_FORWARD` you
write `idx hash delay 2 "OP_CSV OP_DROP OP_FORWARD_OUTPUTS"
OP_FORWARD_LEAF_UPDATE`
That's an additional 5 witness bytes, but a much more generic/composable
opcode.
Being able to prefix a script with push opcodes avoids the possibility
of being able to add OP_SUCCESS instructions, so I think this is a fairly
safe way of allowing a TLUV-ish script to be modified, especially compared
to OP_CAT.
I do recognise that it makes it take a variable number of stack elements
though :)
> As the derived tapscript, embedded in a output scriptpubkey of the form:
> `tr(NUMS,{...,EXPR_WITHDRAW})`, meaning we literally take the control block
> from the spending input, swap the inner pubkey for `NUMS`, use
> `EXPR_WITHDRAW` as the tapleaf, reconstruct the merkle root. If the output
> scriptpubkey doesnt match, fail.
I don't think replacing the internal-public-key makes sense -- if it
was immediately spendable via the keypath before there's no reason for
it not to be immediately spendable now.
> Could save 2 WU having OP_FORWARD_OUTPUTS take the <spend-delay> directly
> as an argument, or keep it more general as I did.
Having OP_FORWARD_OUTPUTS not leave its input on the stack would let
you move the OP_CSV to the end and drop the OP_DROP too, saving 1 WU.
> Would love to know what you and others think about this direction. I
> apologies for any misunderstandings I have about the current OP_VAULT BIP!
I think the existing OP_VAULT cleverness would work here, allowing you
to spend two inputs to the same output, accumulating their values.
I don't think it quite gives you a way to "refund" values though -- so
that you can take a vault with 3 BTC, start the <delay> wait to spend
1.4 BTC, and then immediately decide to spend an additional 0.8 BTC on
something else, without the 0.8 BTC effectively having a doubled delay.
I think you could fix that with something as simple as an additional
"idx OP_FORWARD_REFUND" opcode, though -- then the restriction is just
that the output at the refund idx has the same sPK as this input, and
the total value of this input is accumulated amongst all the outputs
specified by OP_FORWARD opcodes. (Maybe you need to specify the refund
amount explicitly as well, to keep verification easy)
That would make maybe three new opcodes to cover the "accumulate value
from one or more inputs into specified outputs":
- OP_FORWARD_LEAF_UPDATE --> forward input value to modified spk
- OP_FORWARD_DESTINATION --> forward input value to given spk
- OP_FORWARD_REFUND --> forward part of input value to same spk
along with OP_CTV:
- OP_FORWARD_OUTPUTS --> pay to specific outputs
OP_VAULT's "accumulate value" behaviour here makes the OP_IN_OUT_AMOUNT
things from TLUV more implicit and automatic, which is nice. I think
doing TLUV payment pools wouldn't require much more than the ability to
combine OP_FLU and OP_FDEST in a single script, explicitly specifying
how much value is extracted via OP_FDEST with the rest assigned to OP_FLU.
Cheers,
aj
Published at
2023-06-07 23:19:56Event JSON
{
"id": "730cd4de841c8b22612bbad52aa7a0fed309b8e18a8394933c7fc7f42b1d6c09",
"pubkey": "f0feda6ad58ea9f486e469f87b3b9996494363a26982b864667c5d8acb0542ab",
"created_at": 1686179996,
"kind": 1,
"tags": [
[
"e",
"647fc7db9ce6599535c0921f7a07494f1213a0b3b646951b297e97e004c8718e",
"",
"root"
],
[
"e",
"46234e6c944c5b7e8e5147029df2f313025e24cd7e9ce7500a0ba29b231c15fe",
"",
"reply"
],
[
"p",
"937f10fc4f78d8676348562d9d886843fbb351d99d6c96423fe9970819962e19"
]
],
"content": "📅 Original date posted:2023-03-02\n🗒️ Summary of this message: A proposed replacement for two opcodes in Bitcoin involves a new opcode called OP_TRIGGER_FORWARD, which takes three arguments and can be generalized for more flexibility. The proposed opcode can be embedded in a tapscript and used to modify a TLUV-ish script. The existing OP_VAULT cleverness can be used to spend two inputs to the same output, but there is no way to refund values.\n📝 Original message:On Wed, Mar 01, 2023 at 10:05:47AM -0500, Greg Sanders via bitcoin-dev wrote:\n\u003e Below is a sketch of a replacement for the two opcodes. \n\nI like this! I tried to come up with something along similar lines for\nsimilar reasons, but I think I tried too hard to reduce it to two opcodes\nor something and got myself confused.\n\n\u003e `OP_TRIGGER_FORWARD`: Takes exactly three arguments:\n\u003e 1) output index to match against (provided at spend time normally)\n\u003e 2) target-outputs-hash: 32 byte hash to be forwarded to output given at (1)\n\u003e (provided at spend time normally)\n\u003e 3) spend-delay: value to be forwarded to output given at (1)\n\nI think you could generalise this as follows:\n\n idx .. npush script OP_FORWARD_LEAF_UPDATE\n\n(OP_FLU :) with the behaviour being:\n\n pop script from the stack\n pop npush from the stack (error if non-minimal or \u003c0)\n pop npush entries from the stack,\n prefix script with a minimal push of that entry\n pop idx off the stack (error if idx is not a valid output)\n calculate the spk corresponding to taking the current\n input's spk and replacing the current leaf with the\n given script\n check the output at idx matches this spk, and the\n value from this input accumulates to that output\n\nThen instead of `idx hash delay OP_TRIGGER_FORWARD` you\nwrite `idx hash delay 2 \"OP_CSV OP_DROP OP_FORWARD_OUTPUTS\"\nOP_FORWARD_LEAF_UPDATE`\n\nThat's an additional 5 witness bytes, but a much more generic/composable\nopcode.\n\nBeing able to prefix a script with push opcodes avoids the possibility\nof being able to add OP_SUCCESS instructions, so I think this is a fairly\nsafe way of allowing a TLUV-ish script to be modified, especially compared\nto OP_CAT.\n\nI do recognise that it makes it take a variable number of stack elements\nthough :)\n\n\u003e As the derived tapscript, embedded in a output scriptpubkey of the form:\n\u003e `tr(NUMS,{...,EXPR_WITHDRAW})`, meaning we literally take the control block\n\u003e from the spending input, swap the inner pubkey for `NUMS`, use\n\u003e `EXPR_WITHDRAW` as the tapleaf, reconstruct the merkle root. If the output\n\u003e scriptpubkey doesnt match, fail.\n\nI don't think replacing the internal-public-key makes sense -- if it\nwas immediately spendable via the keypath before there's no reason for\nit not to be immediately spendable now.\n\n\u003e Could save 2 WU having OP_FORWARD_OUTPUTS take the \u003cspend-delay\u003e directly\n\u003e as an argument, or keep it more general as I did.\n\nHaving OP_FORWARD_OUTPUTS not leave its input on the stack would let\nyou move the OP_CSV to the end and drop the OP_DROP too, saving 1 WU.\n\n\u003e Would love to know what you and others think about this direction. I\n\u003e apologies for any misunderstandings I have about the current OP_VAULT BIP!\n\nI think the existing OP_VAULT cleverness would work here, allowing you\nto spend two inputs to the same output, accumulating their values.\n\nI don't think it quite gives you a way to \"refund\" values though -- so\nthat you can take a vault with 3 BTC, start the \u003cdelay\u003e wait to spend\n1.4 BTC, and then immediately decide to spend an additional 0.8 BTC on\nsomething else, without the 0.8 BTC effectively having a doubled delay.\n\nI think you could fix that with something as simple as an additional\n\"idx OP_FORWARD_REFUND\" opcode, though -- then the restriction is just\nthat the output at the refund idx has the same sPK as this input, and\nthe total value of this input is accumulated amongst all the outputs\nspecified by OP_FORWARD opcodes. (Maybe you need to specify the refund\namount explicitly as well, to keep verification easy)\n\nThat would make maybe three new opcodes to cover the \"accumulate value\nfrom one or more inputs into specified outputs\":\n\n - OP_FORWARD_LEAF_UPDATE --\u003e forward input value to modified spk\n - OP_FORWARD_DESTINATION --\u003e forward input value to given spk\n - OP_FORWARD_REFUND --\u003e forward part of input value to same spk\n\nalong with OP_CTV:\n\n - OP_FORWARD_OUTPUTS --\u003e pay to specific outputs\n\nOP_VAULT's \"accumulate value\" behaviour here makes the OP_IN_OUT_AMOUNT\nthings from TLUV more implicit and automatic, which is nice. I think\ndoing TLUV payment pools wouldn't require much more than the ability to\ncombine OP_FLU and OP_FDEST in a single script, explicitly specifying\nhow much value is extracted via OP_FDEST with the rest assigned to OP_FLU.\n\nCheers,\naj",
"sig": "6d32ad4c0afc22d4ff4b498f5d5a9ff3029c20bf17c61e17a1d7915d957ad724274082b8f9d0b6423f6ad920782c61dd3f2e554accdc1f02efd437fa5ac00eba"
}