Minsc has some functional constructs for looping that might be interesting to check out.
You can use repeat($n, $script)
for cases where you need to repeat a script fragment exactly N times. For example to create a rollFromAltStack
function (for statically known N):
fn rollFromAltStack($n) = `
repeat($n, OP_FROMALTSTACK)
repeat($n - 1, `OP_SWAP OP_TOALTSTACK`)
`;
script = `100 rollFromAltStack(5) OP_ADD`;
The fragment can also be constructed with a function if the index is needed, for example `0 repeat(3, |$i| repeat(5, |$k| `$i OP_ADD {$k+10} OP_SUB`))`
There’s also unrollLoop($max, $condition, $body)
that runs a script fragment as long as a condition is met, up to $max
times. For example, a simple countdown from a number on the stack (up to 50) down to 0:
unrollLoop(50, `OP_DUP 0 OP_GREATERTHANOREQUAL`, OP_1SUB)
(playground, more advanced example with liquid. unrollLoop
is itself implemented in Minsc as part of its stdlib.)
–
Minsc focuses entirely on defining the (Mini)Script-level spending conditions and doesn’t deal with higher-level abstracts like Bitcoin DSL does, so perhaps they could somehow work together.
Note that the main https://min.sc website is outdated, the docs are lacking the (non-Miniscript) Script features and the playground runs an old version. A playground that matches the code on github is available at https://min.sc/next/. I don’t have updated docs but I did publish some more advanced examples using CTV and Liquid’s introspection opcodes.
I should really get this cleaned up and released properly I haven’t been working on this for some time but picking this back up has been on my mind.