跳至主要內容
高級

Miniscript 腳本語言

Miniscript 是一種結構化的方式來編寫比特幣腳本,使複雜的支付條件變得可組合、可分析和可預測。

25 分鐘

什麼是 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:離散日誌合約的條件執行

相關資源

延伸閱讀: 查看 Miniscript 官方網站 了解完整的語法和分析工具。

已複製連結
已複製到剪貼簿