Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OP_REVAULT, example usages #4

Open
wants to merge 2 commits into
base: jamesob-23-02-opvault
Choose a base branch
from

Conversation

instagibbs
Copy link
Collaborator

I've surely made some off-by-ones on the fancier usages, but this should demonstrate that it works. I'm not a stack manipulation expert.

Very small spec change, and enables some interesting behavior.

@instagibbs
Copy link
Collaborator Author

instagibbs commented Aug 31, 2023

could also have OP_REVAULT push residual on stack. Could allow wallet authors to re-arrange which order OP_REVAULT/OP_VAULT are given, allowing the witness stack to give revault value instead of trigger value? Slightly more symmetrical, maybe nice.

you'd have to handle the corner cases where the final residual on the stack ends up being 0, however. OP_1ADD the result, I guess, for another 1 WU?

@instagibbs
Copy link
Collaborator Author

Of course, once you get "residual" values in either case, you can directly access the input value:

0 0 0 "" OP_VAULT would give you the input value on the stack.

* <code><revault-amount></code> is an up to 7-byte CScriptNum-encoded number indicating the number of satoshis being revaulted.
** If this value does not decode to a valid CScriptNum, script execution when spending this output MUST fail and terminate immediately.
** If this value is not greater than or equal to 0, script execution when spending this output MUST fail and terminate immediately.
** If this value is non-zero but <code><revault-vout-idx></code> is negative, script execution when spending this output MUST fail and terminate immediately.
Copy link
Collaborator Author

@instagibbs instagibbs Sep 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If going forward with this, I'd change the logic to what sanket suggested:

  1. if no revault exists, use -1 for index
  2. if revault amount is non-0, index must not be -1

same with trigger values

previously a 0-valued invocation would have allowed output index malleability

@instagibbs
Copy link
Collaborator Author

instagibbs commented Sep 1, 2023

you'd have to handle the corner cases where the final residual on the stack ends up being 0, however. OP_1ADD the result, I guess, for another 1 WU?

Eh, math is broken, you can't actually do OP_1ADD unless the entire utxo is smaller than ~2.1 BTC. You're going to have to add OP_DROP OP_TRUE. Probably not worth both pushing residual.

=======

If you swap which opcode pushes residual, args for common case should probably be moved around to save bytes and make basic vaults just as easy as before:

This PR's current idea:

OP_VAULT
<leaf-update-script-body>
<n-pushes>
[ n leaf-update script data items ... ]
<trigger-amount>
<trigger-vout-idx>

OP_REVAULT
<revault-amount>
<revault-vout-idx>

OP_VAULT needs single push for CTV hash, that's it

trigger:
  <trigger-auth-pubkey> OP_CHECKSIGVERIFY                       (i)
  1 $leaf-update-script-body OP_VAULT OP_REVAULT, (ii)
 witness stack:
 trigger-sig (consumed by CS)
 ctv-hash (top arg of OP_VAULT)
 trigger-amount (2nd arg of OP_VAULT)
 trigger-vout-idx (3rd arg of OP_VAULT, replaced with revault-amount)
 revault-vout-idx

============

If OP_REVAULT pushes residual instead, and OP_VAULT pushes 0x01:

OP_VAULT
<trigger-amount>
<leaf-update-script-body>
<n-pushes>
[ n leaf-update script data items ... ]
<trigger-vout-idx>

OP_REVAULT
<revault-amount>
<revault-vout-idx>
 trigger:
  <trigger-auth-pubkey> OP_CHECKSIGVERIFY                       (i)
  OP_REVAULT 1 $leaf-update-script-body OP_VAULT , (ii)
witness stack:
trigger-sig (consumed by CS)
revault-amount
revault-vout-idx (replaced by trigger-amount)
ctv-hash (2nd arg of OP_VAULT)
trigger-amount (3rd arg of OP_VAULT)
trigger-vout-idx (4th arg of OP_VAULT, replaced with revault-amount)

@instagibbs
Copy link
Collaborator Author

instagibbs commented Sep 1, 2023

hacky MVP percentage based idea:
for values -1 through -100, treat those as % of input-satoshi-value. Residual would remain absolute satoshi values. Common would be -100, allows for %-based rate-limit(complementing constant per utxo) by committing to that negative value, and %-based collateral similarly. This also makes the common case a smaller CScriptNum which is nice. Maybe could get rid of "denominations" issue for rate-limiting as well.

Aside: I like the idea of the collateral being able to go to a "different destination" as well, vs the unvault itself. i.e., the collateral OP_VAULT invocation could put the value in another script that is spendable via unique arbitrary policy. Collateral is just a requirement that more sats should go to some policy of the vault's choosing. Collateral could be immediately swept by another system, or put back into another unvault immediately, if desired.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant