Hi all, TL;DR: a v1 tapscript opcode for generic covenants, but OP_SUCCESS unless it's used a-la OP_CHECKTEMPLATEVERIFY. This gives an obvious use case, with clean future expansion. OP_NOP4 can be repurposed in future as a shortcut, if experience shows that to be a useful optimization.
(This proposal builds on Russell O'Connor's TXHASH, with Anthony Towns' modification via extending the opcode; I also notice on re-reading that James Lu had a similar restriction idea). Details ------- OP_TX, when inside v1 tapscript, is followed by 4 bytes of flags. Unknown flag patterns are OP_SUCCESS, though for thoroughness some future potential uses are documented here. Note that pushing more than 1000 elements on the stack or an element more than 512 bytes will hit the BIP-342 resource limits and fail. Defined bits ------------ (Only those marked with * have to be defined for this soft fork; the others can have semantics later). OPTX_SEPARATELY: treat fields separately (vs concatenating) OPTX_UNHASHED: push on the stack without hashing (vs SHA256 before push) - The first nicely sidesteps the lack of OP_CAT, and the latter allows OP_TXHASH semantics (and avoid stack element limits). OPTX_SELECT_VERSION*: version OPTX_SELECT_LOCKTIME*: nLocktime OPTX_SELECT_INPUTNUM*: current input number OPTX_SELECT_INPUTCOUNT*: number of inputs OPTX_SELECT_OUTPUTCOUNT*: number of outputs OPTX_INPUT_SINGLE: if set, pop input number off stack to apply to OPTX_SELECT_INPUT_*, otherwise iterate through all. OPTX_SELECT_INPUT_TXID: txid OPTX_SELECT_INPUT_OUTNUM: txout index OPTX_SELECT_INPUT_NSEQUENCE*: sequence number OPTX_SELECT_INPUT_AMOUNT32x2: sats in, as a high-low u31 pair OPTX_SELECT_INPUT_SCRIPT*: input scriptsig OPTX_SELECT_INPUT_TAPBRANCH: ? OPTX_SELECT_INPUT_TAPLEAF: ? OPTX_OUTPUT_SINGLE: if set, pop input number off stack to apply to OPTX_SELECT_OUTPUT_*, otherwise iterate through all. OPTX_SELECT_OUTPUT_AMOUNT32x2*: sats out, as a high-low u31 pair OPTX_SELECT_OUTPUT_SCRIPTPUBKEY*: output scriptpubkey OPTX_SELECT_19...OPTX_SELECT_31: future expansion. OP_CHECKTEMPLATEVERIFY is approximated by the following flags: OPTX_SELECT_VERSION OPTX_SELECT_LOCKTIME OPTX_SELECT_INPUTCOUNT OPTX_SELECT_INPUT_SCRIPT OPTX_SELECT_INPUT_NSEQUENCE OPTX_SELECT_OUTPUTCOUNT OPTX_SELECT_OUTPUT_AMOUNT32x2 OPTX_SELECT_OUTPUT_SCRIPTPUBKEY OPTX_SELECT_INPUTNUM All other flag combinations result in OP_SUCCESS. Discussion ---------- By enumerating exactly what can be committed to, it's absolutely clear what is and isn't committed (and what you need to think about!). The bits which separate concatenation and hashing provide a simple mechanism for template-style (i.e. CTV-style) commitments, or for programatic treatment of individual elements (e.g. amounts, though the two s31 style is awkward: a 64-bit push flag could be added in future). The lack of double-hashing of scriptsigs and other fields means we cannot simply re-use hashing done for SIGHASH_ALL. The OP_SUCCESS semantic is only valid in tapscript v1, so this does not allow covenants for v0 segwit or pre-segwit inputs. If covenants prove useful, dedicated opcodes can be provided for those cases (a-la OP_CHECKTEMPLATEVERIFY). Cheers, Rusty.  https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019813.html  https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019819.html  https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2022-January/019816.html _______________________________________________ bitcoin-dev mailing list email@example.com https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev