DSL for experimenting with contracts

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`;

(playground)

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 :sweat_smile: I haven’t been working on this for some time but picking this back up has been on my mind.

2 Likes