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.
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_SEGMENTis found, the script up to that point is executed. If the script does not fail, scanning continues from that point.
OP_SUCCESSxis 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.
OP_SEGMENT is executed, it does nothing: it simply limits the range of
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!