Miniscript 是对 Bitcoin Script 一部分功能的结构化表达。Bitcoin Script 决定一笔币满足什么条件才能被花费;Miniscript 则把签名、等待期限和特定秘密的披露组合成软件容易分析和满足的形式。它不是独立的钱包,也不是比特币的新规则,真正保护资金的是生成的脚本。
安娜希望平时用自己的密钥花费资金,同时为彼得留一条路:从该输出获得确认起经过 144 个区块后,彼得也能用自己的密钥花费它。数字签名利用私钥这个秘密数值证明付款获得授权,同时不泄露私钥。钱包是接收和发送比特币的应用程序或设备。这种意图称为 spending policy,即花费策略。Miniscript 帮助把它变成钱包能够处理的精确表达。彼得仍然需要密钥,等待不能代替密钥。这个简单例子描述的是两条可选路径,不是自动转账,也不会检测安娜是否丢了密钥。 [1] [2] [10]
用一句话表达规则,还没有得到网络能验证的程序。编译器可以选择具体的 Miniscript 表达式,再将其转换为 Bitcoin Script。Output Descriptor 描述生成的脚本、相关密钥及可能使用的派生路径,也可以包含用于发现抄写错误的校验和。花费时,网络验证的是实际脚本和提交的数据,而不是最初那句话。Miniscript 不增加新指令,也不修改共识,也就是共同遵守的有效性规则。它不能表达所有可能的 Bitcoin Script。 [1] [3] [6]
区块把交易组成一批,加入共同历史记录。在彼得的例子中,144 个区块从输出确认时开始计算。输出是附有花费条件的一笔具体金额。这不是精确的一天,也不是从创建钱包时算起。Miniscript 用 older(n) 表示相对等待条件,底层使用 CSV 和花费该输出的交易输入中的 nSequence 字段;BIP 68 规定了后者在验证币龄时的含义。相反,after(n) 使用 CLTV 和绝对的 nLockTime,指定固定区块高度或时间门槛。钱包必须正确设置交易字段,并满足其他条件。按高度和按时间计量的锁定条件不能以不兼容的方式组合;等够时间也不会自动发送资金。 [1] [7] [8] [9] [11]
仅展示规则说明还不够。钱包必须提供满足某条许可路径的数据,例如签名,或哈希值与要求一致的秘密,也就是 preimage。哈希是数据的数字指纹;这里要检查提交的秘密能否生成所要求的指纹。这种满足条件的方式称为 satisfaction,所需输入数据属于交易的 witness。组合分支时,有时需要按规则让某个子条件为假,才能使用另一条路径。这叫 dissatisfaction,并不表示整笔付款无效。软件能组织合适的路径,却不能凭空产生缺失的私钥或未知的秘密。 [1] [12]
PSBT 是在钱包与签名设备之间传递待签交易及补充信息的格式。仅支持 PSBT 并不够,软件和 Hardware Wallet 还必须理解具体的 descriptor 及其条件。Bitcoin Core 在版本 24 中加入了对 P2WSH 中 Miniscript 的只读观察支持,在版本 25 中加入签名支持,在版本 26 中加入 Taproot descriptors 支持。因此,能看到这些币不代表能花费它们。设置时,应根据设备实际能力,在可信屏幕上核对密钥、所需签名、等待条件以及所有替代路径。 [3] [4] [5]
Seed Phrase 可以恢复密钥,但对于自定义的复杂条件,它未必能说明这些密钥如何与其他密钥及脚本组合。这种备份是一串有顺序的单词,钱包可以据此派生密钥。请保存带校验和的准确 descriptor、密钥对应关系、派生路径,以及收款地址和找零地址的区分。另行记录所用网络、地址范围及历史扫描的起点。公开 descriptor 不是私钥,却可能暴露付款历史。正式使用前,应在 Regtest 或 Signet 测试环境中验证只读钱包恢复,并测试每条计划使用的花费路径。 [5] [6]
pk()、older()、after() 和 sha256() 分别用于表达签名、等待或提供秘密等条件。and_v()、or_d() 和 thresh() 可以组合条件。v: 等包装器调整求值方式,同时保留子表达式的含义。B、V、K、W 类型约束不同部分如何在栈上交接数据;栈是脚本的工作区,并不是任意两部分都能连接。类型检查可以发现不兼容的组合,却不能替安娜决定该信任谁,也不能判断她选择的备用路径是否合理。 [1] [2]
结构化表达使软件能够提前分析脚本和 witness 的大小、操作数量、签名检查次数以及栈元素数量。这有助于估算不同路径的成本,并发现超出允许范围的情况。但必须区分使用环境:P2WSH 在 SegWit 框架内表达条件,Tapscript 则指 Taproot 中使用的脚本。两者的限制并非完全相同。除了共识规则,还要考虑通常的交易转发规则。因此,分析结果不能证明所有钱包都能执行这个方案。 [1]
公钥用于验证签名,不需要保密。malleability 分析研究的是:外人能否把一种有效 satisfaction 改成另一种仍有效的 satisfaction。相应保证有明确前提:攻击者没有参与者的私钥,知道的 preimages 不多于诚实用户,而且只看到一种 satisfaction。分析还假设公钥没有重复,并遵循通常的接收规则;矿工可能有普通转发节点没有的选择。因此,这不是针对所有恶意参与者、备份丢失或糟糕托管设计的全面保证。这些问题需要单独检查。 [1]
编译器可以用不同方式表达相同规则,得到不同大小的脚本和 witness,并按成本模型作出选择。策略输入语言中,分支上的 9@ 之类标记提示的是相对使用概率,不是签名数量,也不是网络授予的权限。不同的编译结果可能生成不同脚本,从而产生不同地址。因此,恢复时不能只靠重新用自己的话描述规则,再编译一次。准确保存的表达形式、派生地址的核对,以及经过测试的签名路径都很重要。 [2] [5]
要获得更完整的理解,请将本词条与以下词条结合阅读: Bitcoin Script, Output Descriptor, Multisig, Andrew Poelstra, Timelock, Bitcoin. 反向关联还来自: Output Descriptor, Dead Man’s Switch, Andrew Poelstra, Simplicity.