Greg Sanders [ARCHIVE] on Nostr: 📅 Original date posted:2023-03-02 🗒️ Summary of this message: Greg proposes a ...
📅 Original date posted:2023-03-02
🗒️ Summary of this message: Greg proposes a new script for the EXPR_TRIGGER opcode, allowing for withdrawal authorization and introducing a refund path.
📝 Original message:Greetings AJ,
Glad I could resurrect the idea!
> 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`
Interesting idea! (I'll let you be the one to scope creep the proposal :) )
To be pedantic, EXPR_TRIGGER would become:
<trigger> <auth> <stuff> <spend-delay> <2> <OP_CSV OP_DROP
OP_FORWARD_OUTPUTS> OP_FORWARD_LEAF_UPDATE
and at spend time the idx and hash are put into the witness stack.
To be clear, <spend-delay> could be embedded in the <script> too, right,
making <2> a <1> in the above? Any reason for one or the other?
Another bonus from this is that you can introduce withdrawal authorization
as well as part of the <script>. Current proposal has no withdrawal
authorization, from what I understand. So each transition in a vault
construct can have authorization, if it desires it.
> I do recognise that it makes it take a variable number of stack elements
though :)
Just when I thought I was out, they pulled me back in.
> 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.
Slavishly following the current proposal was the idea to make sure all
functionality was captured; I agree with this change.
> 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.
Previously setting CSV timeout to 0 would result in it not being
satisfiable, if I'm understanding the suggestion correctly. I suppose this
was a side-effect of having OP_UNVAULT take this value directly. Indeed
with `OP_FORWARD_OUTPUTS` being split out there's not really a reason to
use a 0 value?
> I think the existing OP_VAULT cleverness would work here, allowing you
to spend two inputs to the same output, accumulating their values.
Yes I think batching story should be same hopefully. I am assuming all the
accounting OP_VAULT is doing is being done here. We match against the hash
passed in, and fits into the "deferred checks" IIUC.
> OP_FORWARD_REFUND
Again, to be pedantic EXPR_TRIGGER becomes:
<trigger> <auth> <stuff> <spend-delay> <2> <OP_CSV OP_DROP
OP_FORWARD_OUTPUTS> OP_FORWARD_LEAF_UPDATE OP_FORWARD_REFUND
Resulting in 2 more WU at spend time(for small idx). So *up front*
committing to a refund path, perhaps with value explicitly passed in.
Totally forgot about the refund path; will need to mull the issue over, see
how it interacts with BYOF schemes, etc.
Cheers,
Greg
On Wed, Mar 1, 2023 at 11:46 PM Anthony Towns <aj at erisian.com.au> wrote:
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20230302/59e4f0f8/attachment.html>
🗒️ Summary of this message: Greg proposes a new script for the EXPR_TRIGGER opcode, allowing for withdrawal authorization and introducing a refund path.
📝 Original message:Greetings AJ,
Glad I could resurrect the idea!
> 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`
Interesting idea! (I'll let you be the one to scope creep the proposal :) )
To be pedantic, EXPR_TRIGGER would become:
<trigger> <auth> <stuff> <spend-delay> <2> <OP_CSV OP_DROP
OP_FORWARD_OUTPUTS> OP_FORWARD_LEAF_UPDATE
and at spend time the idx and hash are put into the witness stack.
To be clear, <spend-delay> could be embedded in the <script> too, right,
making <2> a <1> in the above? Any reason for one or the other?
Another bonus from this is that you can introduce withdrawal authorization
as well as part of the <script>. Current proposal has no withdrawal
authorization, from what I understand. So each transition in a vault
construct can have authorization, if it desires it.
> I do recognise that it makes it take a variable number of stack elements
though :)
Just when I thought I was out, they pulled me back in.
> 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.
Slavishly following the current proposal was the idea to make sure all
functionality was captured; I agree with this change.
> 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.
Previously setting CSV timeout to 0 would result in it not being
satisfiable, if I'm understanding the suggestion correctly. I suppose this
was a side-effect of having OP_UNVAULT take this value directly. Indeed
with `OP_FORWARD_OUTPUTS` being split out there's not really a reason to
use a 0 value?
> I think the existing OP_VAULT cleverness would work here, allowing you
to spend two inputs to the same output, accumulating their values.
Yes I think batching story should be same hopefully. I am assuming all the
accounting OP_VAULT is doing is being done here. We match against the hash
passed in, and fits into the "deferred checks" IIUC.
> OP_FORWARD_REFUND
Again, to be pedantic EXPR_TRIGGER becomes:
<trigger> <auth> <stuff> <spend-delay> <2> <OP_CSV OP_DROP
OP_FORWARD_OUTPUTS> OP_FORWARD_LEAF_UPDATE OP_FORWARD_REFUND
Resulting in 2 more WU at spend time(for small idx). So *up front*
committing to a refund path, perhaps with value explicitly passed in.
Totally forgot about the refund path; will need to mull the issue over, see
how it interacts with BYOF schemes, etc.
Cheers,
Greg
On Wed, Mar 1, 2023 at 11:46 PM Anthony Towns <aj at erisian.com.au> wrote:
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/attachments/20230302/59e4f0f8/attachment.html>