Script Opcodes & Macros¶
In addition to Bitcoin's native opcodes,
Minsc also ships with some built-in composite opcodes for common multi-opcode operations,
as well as function macros that generate dynamic Script.
Also see:
Composite Opcodes¶
Minsc's custom opcodes are prefixed with
OP::, to differentiate them from native opcodes.
Verify that the two top stack elements are not equal
stack in: <a> <b> stack out: (none) (or fail)
OP::MINIMAL_BOOL
Script
¶
OP::MINIMAL_BOOL = `OP_DUP OP_SIZE OP_EQUALVERIFY`
Verify that the top stack element is exactly 1 or 0
(0x01 or the empty byte-array 0x)
stack in: <n> stack out: <n> (or fail)
OP::PICK_BOTTOM
Script
¶
OP::PICK_BOTTOM = `OP_TOALTSTACK OP_DEPTH OP_FROMALTSTACK OP_SUB OP_PICK`
PICK (copy) from the bottom of the stack (1 for the bottom-most stack element, not 0)
OP::ROLL_BOTTOM
Script
¶
OP::ROLL_BOTTOM = `OP_TOALTSTACK OP_DEPTH OP_FROMALTSTACK OP_SUB OP_ROLL`
ROLL (move) from the bottom of the stack (1 for the bottom-most stack element, not 0)
Shift the bottom-most stack element to the top of the stack
Sort the top 2 stack elements (higher placed on top)
OP::𝘯MUL
¶
Minsc source code: src/stdlib/btc.minsc:N/A
Script Macros¶
Loop Unrolling¶
Run the body script as long as the condition is met, up to max_iterations times.
If max_iterations is reached but the condition is still met, execution fails.
The body can be a Script or a Function that takes the iteration count and returns a Script.
For example, this will count from <num> down to 0 (for numbers up to 10):
A more advanced example that sums the total inputs amount using the Liquid introspection opcodes is available here.
Minsc source code: src/stdlib/btc.minsc:N/A
Pop the top stack element as the number of times to run the script body, up to max_iterations.
For example, this will sum the numbers between 1 and <num> (for numbers up to 10):
Minsc source code: src/stdlib/btc.minsc:N/A
Control Structures¶
Check a series of nested OP_IF..OP_ELSE conditions, running the script associated with the first
match or the optional default branch. If there's no match and no default, execution fails.
Given an array of clauses, where each clause is a tuple of the Script checking the condition (or default), plus the Script to execute as the clause body.
For example, to match the number on the top of the stack and run some code accordingly:
Minsc source code: src/stdlib/btc.minsc:N/A
Match the element at the top of the stack against the clauses and run the first match,
keeping the item being matched around as necessary (without requiring manual OP_DUP/OP_DROP).
If there's no match and no default, execution fails.
For example, this is equivalent to the ifelseif example above:
Minsc source code: src/stdlib/btc.minsc:N/A
Match the item at the top of the stack for equality.
Given an array of clauses, where each clause is a tuple of the Value to match against
(any Bytes-coercible) or default, plus the Script to execute as the clause body.
For example, this is equvalent to the ifelseif/match examples above:
Minsc source code: src/stdlib/btc.minsc:N/A
Pop an index number off the stack and execute the scripts branch with that index.
Does not support a default branch.
This can typically be better accomplished with separate Taproot leaves for the script branches, but branching within a single Script may be preferable in some cases.
For example:
Optimized to a simple
OP_IF..OP_ELSE..OP_ENDIFwhen there are only 2 branches. This relies onMINIMALIFfor non-malleability, which is consensus-enforced in Taproot but only a standardness policy for Segwitv0/P2SH, whereOP::MINIMAL_BOOLis required to ensure non-malleability.
Minsc source code: src/stdlib/btc.minsc:N/A
(Alt)Stack Manipulation¶
PICK (copy) from the bottom of the stack, for statically known depth (1 for the bottom-most stack element, not 0)
Like OP::PICK_BOTTOM, but more weight-efficient when the depth is static.
Minsc source code: src/stdlib/btc.minsc:N/A
ROLL (move) from the bottom of the stack, for statically known depth (1 for the bottom-most stack element, not 0)
Like OP::ROLL_BOTTOM, but more weight-efficient when the depth is static.
Minsc source code: src/stdlib/btc.minsc:N/A
PICK (copy) from the altstack, for statically known depth
Minsc source code: src/stdlib/btc.minsc:N/A
ROLL (move) from the altstack, for statically known depth
Minsc source code: src/stdlib/btc.minsc:N/A
PICK (copy) from the altstack, using the number at the top of the stack as the depth (loop unrolled up to max_depth)
Minsc source code: src/stdlib/btc.minsc:N/A
ROLL (move) from the altstack, using the number at the top of the stack as the depth (loop unrolled up to max_elements)
Minsc source code: src/stdlib/btc.minsc:N/A
Send multiple stack elements the the altstack, using the number at the top of the stack as the number of elements to send (loop unrolled up to max_elements). nFromAlt() can be used to bring them back.
stack in: <el1> <el2> .. <elN> <N total> stack out: (none)
altstack out: <elN> .. <el2> <el1> <N total>
When the number of elements to send is static, this can be done much more efficiently using simple Script repetition, e.g.
OP_TOALTSTACK*5
Minsc source code: src/stdlib/btc.minsc:N/A
Bring back multiple stack elements from the altstack, using the number at the top of the altstack as the number of elements to bring (loop unrolled up to max_elements). The opposite of nToAlt().
altstack in: <elN> .. <el2> <el1> <N total> altstack out: (none)
stack out: <el1> <el2> .. <elN> <N total>
When the number of elements to bring is static, this can be done much more efficiently using simple Script repetition, e.g.
OP_FROMALTSTACK*5
Minsc source code: src/stdlib/btc.minsc:N/A
Drop num_elements from the stack, using the minimal number of OP_2DROP/OP_DROP's
Minsc source code: src/stdlib/btc.minsc:N/A
Drop num_elements from the altstack
Minsc source code: src/stdlib/btc.minsc:N/A
Native Opcodes¶
OP_PUSHNUM_1-OP_PUSHNUM_16
OP_PUSHBYTES_0-OP_PUSHBYTES_75
OP_PUSHDATA1, OP_PUSHDATA2, OP_PUSHDATA4
Alias of: OP_PUSHBYTES_0
Aliased as: OP_CHECKSEQUENCEVERIFY
OP_NOP1-OP_NOP10
OP_RETURN_187-OP_RETURN_254
Disabled Opcodes¶
Proposed Opcodes¶
Aliased as: OP_CHECKTEMPLATEVERIFY
Also see: the CTV reference