Install Rust and miniscript CLI
14. Miniscript Policy Language Basics
Policy vs. Miniscript
It is important to distinguish Policy from Miniscript:
-
Policy is the high-level human-readable description of spending conditions.
-
Miniscript is the structured intermediate representation that maps 1:1 to Bitcoin Script.
-
Bitcoin Script is the actual bytecode executed by nodes.
The compilation pipeline: Policy → Miniscript → Bitcoin Script
Policy is more abstract and allows the compiler to optimize the resulting Miniscript for minimal script size or minimal witness size. Different Miniscript expressions can implement the same policy with different trade-offs.
Policy Operators
pk(KEY) — Signature from KEY
pkh(KEY) — Signature from KEY (hash-keyed)
older(n) — Relative timelock: n blocks or seconds
after(n) — Absolute timelock
sha256(HASH) — SHA256 preimage hash lock
hash256(HASH) — Double-SHA256 preimage lock
and(A, B) — Both A and B required
or(A, B) — Either A or B (equal probability assumed)
or(9@A, 1@B) — A with 90% probability, B with 10% (affects optimization)
thresh(k, A, B, C) — k-of-n threshold
Writing and Compiling Policies
Using the reference implementation (Rust-based miniscript crate) via the miniscriptc CLI:
# Install Rust and miniscript CLI
cargo install miniscript
# Compile a policy
miniscriptc "or(and(pk(Alice),older(1000)),and(pk(Bob),pk(Carol)))" segwit
Output:
Miniscript: or_d(pk(Alice),and_v(v:older(1000),pk(Bob)))
Script: <Alice> OP_CHECKSIG OP_IFDUP OP_NOTIF <1000> OP_CHECKSEQUENCEVERIFY OP_DROP <Bob> OP_CHECKSIG OP_ENDIF
Address: bc1q...
Using Python for Policy Compilation
from miniscript import miniscript_from_policy, Network
policy = "thresh(2, pk(alice_key_hex), pk(bob_key_hex), pk(carol_key_hex))"
ms = miniscript_from_policy(policy, network=Network.MAINNET)
print("Miniscript:", ms)
print("Script hex:", ms.script.hex())
print("P2WSH address:", ms.p2wsh_address())
print("Max witness weight:", ms.max_weight_to_satisfy)
print("Is safe:", ms.is_safe())
print("Is non-malleable:", ms.is_non_malleable())
Analyzing a Policy's Properties
Miniscript provides formal guarantees that can be checked programmatically:
| Property | Meaning | |
Pro Tip
When debugging scripts, always start with a high-level disassembly before diving into the stack trace. Tools like bitcoin-cli decodescript are your first line of defense in identifying standard script patterns.
TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation: