OP_SEGMENT: Allowing Introspection to Check Partial Scripts
In my previous post on Examing scriptpubkeys in Script I pointed out that there are cases where we want to require a certain script condition, but not an exact script: an example would be a vault-like covenant which requires a delay, but doesn’t care what else is in the script.
The problem with this is that in Taproot scripts, any unknown opcode (OP_SUCCESSx
) will cause the entire script to succeed without being executed, so we need to hobble this slightly. My previous proposal of some kind of separator was awkward, so I’ve developed a new idea which is simpler.
Introducing OP_SEGMENT
Currently, the entire tapscript is scanned for the OP_SUCCESS
opcodes, and succeeds immediately if one it found. This would be modified:
- The tapscript is scanned for either
OP_SEGMENT
orOP_SUCCESSx
. - If
OP_SEGMENT
is found, the script up to that point is executed. If the script does not fail, scanning continues from that point. - If
OP_SUCCESSx
is found, the script succeeds.
This basically divides the script into segments, each executed serially. It’s not quite as simple as “cut into pieces by OP_SEGMENT and examine one at a time” because the tapscript is allowed to contain things which would fail to decode altogether, after an OP_SUCCESSx
, and we want to retain that property.
When OP_SEGMENT
is executed, it does nothing: it simply limits the range of OP_SUCCESS
opcodes.
Implementation
The ExecuteWitnessScript
would have to be refactored (probably as a separate ExecuteTapScript
since 21 of its 38 lines are an “if Tapscript” anyway), and it also implies that the stack limits for the current tapscript would be enforced upon encountering OP_SEGMENT
, even if OP_SUCCESS
were to follow after.
Interestingly, the core EvalScript
function wouldn’t change except to ignore OP_SEGMENT
, as it’s already fairly flexible.
Note that I haven’t implemented it yet, so there may yet be surprises, but I plan to prototype after the idea has received some review!
Enjoy!