Miniscript 腳本語言
Miniscript 是一種結構化的方式來編寫比特幣腳本,使複雜的支付條件變得可組合、可分析和可預測。
什麼是 Miniscript?
Miniscript 由 Pieter Wuille、Andrew Poelstra 和 Sanket Kanjalkar 開發, 是一種用於表達比特幣腳本子集的語言。它不是新的共識規則, 而是一種更高層次的抽象,可以編譯為標準的 Bitcoin Script。
Miniscript 的核心優勢
- + 可組合性:像積木一樣組合複雜條件
- + 可分析性:自動計算花費成本和安全屬性
- + 可滿足性:自動生成有效的見證數據
- + 互操作性:不同錢包可以理解相同的策略
為什麼需要 Miniscript?
原始 Script 的問題
直接編寫 Bitcoin Script 面臨多個挑戰:
- * 難以理解:堆疊式語言不直觀
- * 容易出錯:微小錯誤可能導致資金鎖死
- * 難以分析:無法輕易計算最差情況成本
- * 不可組合:合併兩個腳本需要深入理解
真實案例: 2020 年,一個 DeFi 協議因為 Script 錯誤損失了數百萬美元。 使用 Miniscript 可以通過形式化分析避免這類問題。
基本語法
原子表達式
Miniscript 的基本構建塊:
| 表達式 | 含義 | Script |
|---|---|---|
| pk(KEY) | 公鑰檢查 | <KEY> CHECKSIG |
| pkh(KEY) | 公鑰哈希檢查 | DUP HASH160 <HASH> EQUALVERIFY CHECKSIG |
| older(N) | 相對時間鎖(N 區塊) | <N> CHECKSEQUENCEVERIFY |
| after(N) | 絕對時間鎖 | <N> CHECKLOCKTIMEVERIFY |
| sha256(H) | SHA256 前像 | SIZE 32 EQUALVERIFY SHA256 <H> EQUAL |
| hash160(H) | HASH160 前像 | SIZE 32 EQUALVERIFY HASH160 <H> EQUAL |
組合器
用於組合多個條件:
| 組合器 | 含義 | 說明 |
|---|---|---|
| and_v(X, Y) | X AND Y | 兩個條件都必須滿足 |
| and_b(X, Y) | X AND Y | 兩個條件都必須滿足(布林) |
| or_b(X, Y) | X OR Y | 至少一個條件滿足 |
| or_d(X, Y) | X OR Y | 優先嘗試 X |
| or_c(X, Y) | X OR Y | X 失敗時嘗試 Y |
| thresh(k, X, Y, ...) | k-of-n | 至少 k 個條件滿足 |
| multi(k, KEY1, ...) | k-of-n 多簽 | k 個簽名驗證 |
實際範例
2-of-3 多簽
# Miniscript
multi(2, Alice, Bob, Carol)
# 編譯為 Script
OP_2 <Alice> <Bob> <Carol> OP_3 OP_CHECKMULTISIG
帶超時的 2-of-2
# Alice 和 Bob 一起,或者 1000 區塊後 Alice 單獨
or_d(
multi(2, Alice, Bob),
and_v(pk(Alice), older(1000))
)
閃電網路 HTLC
# 提供原像可立即花費,或超時後退款
or_d(
and_v(pk(Receiver), sha256(H)),
and_v(pk(Sender), after(1000000))
)
企業金庫
# 3-of-5 立即,或 2-of-5 + 1週延遲,或 1-of-5 + 1月延遲
or_d(
multi(3, K1, K2, K3, K4, K5),
or_d(
and_v(multi(2, K1, K2, K3, K4, K5), older(1008)),
and_v(thresh(1, pk(K1), pk(K2), pk(K3), pk(K4), pk(K5)), older(4320))
)
)
類型系統
Miniscript 有嚴格的類型系統,確保生成的腳本是有效的:
| 類型 | 含義 | 堆疊結果 |
|---|---|---|
| B | 基礎表達式 | 消耗輸入,產生 0 或 1 |
| V | 驗證表達式 | 成功時無輸出,失敗時中止 |
| K | 密鑰表達式 | 產生公鑰 |
| W | 包裝表達式 | 消耗頂部元素 |
分析能力
花費成本分析
Miniscript 可以自動計算每個花費路徑的成本:
2-of-3 多簽成本分析
Script 大小: 105 bytes
Witness 大小: 1 + 72 + 72 = 145 bytes
總 vBytes: ~105 + 145/4 = 141 vBytes
安全屬性
Miniscript 可以驗證以下安全屬性:
- + 共識有效性:腳本符合比特幣共識規則
- + 標準性:腳本符合標準性規則,可被轉發
- + 可塑性:見證數據是否可被第三方修改
- + 時間鎖混合:區塊高度和時間戳是否混用
Policy 語言
Policy 是比 Miniscript 更高層的抽象,描述「想要什麼」而不是「如何實現」:
# Policy(描述意圖)
or(99@pk(A), 1@and(pk(B), older(1000)))
# 編譯為 Miniscript(最佳化實現)
or_d(pk(A), and_v(pk(B), older(1000)))
# 99% 機率走 A 路徑,優化為主路徑
Policy 編譯器會根據提供的機率優化生成最高效的 Miniscript。
Output Descriptors
Miniscript 通常與 Output Descriptors 一起使用,完整描述如何生成地址:
# P2WSH 包裝的 Miniscript
wsh(multi(2, xpub.../0/*, xpub.../0/*, xpub.../0/*))
# Taproot 包裝的 Miniscript
tr(KEY, multi_a(2, KEY1, KEY2))
Taproot 與 Miniscript
Taproot 引入了新的腳本功能,Miniscript 也相應擴展:
| 特性 | SegWit v0 | Tapscript |
|---|---|---|
| 多簽 | multi(k, ...) | multi_a(k, ...) |
| 簽名驗證 | ECDSA | Schnorr |
| 腳本大小限制 | 10,000 bytes | 無限制 |
| 操作碼限制 | 201 個 | 無限制 |
工具與實現
Bitcoin Core
從 v24.0 開始支援 Miniscript descriptors
rust-miniscript
Rust 實現,包含 Policy 編譯器
Liana Wallet
使用 Miniscript 的繼承錢包
min.sc
線上 Miniscript 編譯器和分析工具
應用場景
- + 繼承規劃:時間鎖配合多重簽名的資產傳承
- + 企業金庫:多層次的簽名和時間鎖要求
- + 閃電網路:複雜的 HTLC 和懲罰機制
- + 託管服務:用戶最終控制權的保障
- + DLC:離散日誌合約的條件執行
相關資源
- * Script 語言
- * Taproot 升級
- * 多簽錢包入門
- * 時間鎖機制
延伸閱讀: 查看 Miniscript 官方網站 了解完整的語法和分析工具。