本文介绍了Miniscript,这是一种以结构化的方式表示比特币脚本的编程语言,旨在实现高效分析、组合和通用签名等功能。Miniscript通过将复杂的脚本转化为人类可读的格式,并提供在线编译器优化脚本,从而简化了比特币脚本的构造和使用,提高了互操作性,并为诸如储备金证明、花费方式组合和动态联盟等应用场景提供了解决方案。
作者:Pieter Wuille & Andrew Poelstra
来源: https://medium.com/blockstream/miniscript-bitcoin-scripting-3aeff3853620
比特币一直都有一种机制将币的花费条件变得更加复杂(而不是只要你有私钥就一路畅通):Script(脚本)机制。虽然 Script 主要用于单密钥支付,它也是许多技术(比如多签名钱包、原子化互换结构以及闪电网络)的基础。
然而,这还不是它的极限。Script 可以用来表示构造一笔交易所需的复杂条件 —— 例如(A、B、C 三把密钥中的任意两个)以及(D 或者(E、F 一道)) —— 还有哈希原像检查、时间锁以及少量更奇特的结构。
我们远远没有释放 Script 的全部潜能的一个原因是,想要为一些不简单的场景构造脚本并不容易:验证脚本的正确性和安全性很难,而想要发现最经济的编写方法就更难了。
问题的一部分在于:即使你知道正确的脚本,设计出用户可以参与的应用和协议、构造出使用这些协议的交易,在每次设计出新的构造时都需要大量的专门开发工作。任何形式的灵活性通常都诉诸丑陋的模板匹配来检测兼容的脚本,而每一个增补项都需要更多工程资源用于分析和质保。
能不能让比特币应用可以跟任何脚本一起工作,而不是仅仅能运行少数为之设计的脚本呢?这样我们就不会限于只能使用一次性的设计,并且可以开始设计那些构造和使用实时生成脚本的应用,只看用户的专门需求是什么。钱包的开发者也可以引入更多基于脚本的选择,同时维持与其它钱包的互操作性。
下面我们要介绍 Miniscript,这是一种以结构化的方式来表示比特币脚本的编程语言,从而,它能为高效分析、组合、通用签名等等前景赋能。
比如有这样一个比特币脚本:
<A> OP_CHECKSIG OP_IFDUP OP_NOTIF OP_DUP OP_HASH160 <hash160(B)> OP_EQUALVERIFY OP_CHECKSIGVERIFY <144> OP_CSV OP_ENDIF
这里的 A 和 B 是公钥。这个脚本可以转化成 Miniscript 记法:
or_d(c:pk(A),and_v(vc:pk_h(B),older(144)))
这种记法使之更加清楚:脚本的语义想确保这笔资金在花费时要么得到了 A 的签名,要么是在 144 个区块后得到了 B 的签名。一大部分有意义的脚本都可以用这种办法来编写。
让脚本编程人类可读(至少工程师可读)只是 Miniscript 的特性之一。它的主要目标是在 Script 上实现自动推理(automated reasoning),就如下面的使用场景所示的一样。
如今,使用比特币脚本构造复杂花费条件的难度高得没有必要,因为它需要为每一个新的用途开发、测试和部署专门的软件。Miniscript 可以通用化任意的花费条件集合,从而覆盖这些应用场景;而且,通常比专门的解决方案更加简单也更可靠。
其中一种用途是为实现给定的一组花费条件找出最优的脚本。在比特币的 Script 中,它有许多不同的方法来要求一个签名、描述和运算(conjunction)以及或运算(disjunction)、实现一个门限签名。即使是对资深的比特币 Script 开发者,正确的选择也依赖于不同条件被满足的相对概率,而这本身是难以计算的。我们的 在线编译器,也可以 作为 C++ source 来使用,也是 rust-miniscript 库的一部分,可以即时找出对应于给定的一个花费方式的最优 Miniscript 实现。
引言中的示例可以通过编译下面的条件来获得:
or(99@pk(A),1@and(pk(B),older(144)))
这种方法表示,or 的左分支(A 签名)有 99% 的概率出现,而右分支(B 在 144 个区块后签名)只有 1% 的概率出现。
对 Script 的许多应用来说,找出有效率的脚本之后,还有一个常见的障碍是不同的花费机制之间缺乏互操作性。希望实现长期时间锁或者复杂多签名要求的用户,可能因为担心交易对手没有(或者不愿意)使用合适的软件来理解并花费这些条件所控制的资金而却步。
而 Miniscript 因为直接呈现花费条件,可以将任意的条件(policies,后文也译为 “花费方式”)表达得使任何人都可以:
用户不需要担心所有参与者是否都使用了兼容的软件,以及这个软件是否能存活到资金的时间锁解锁的那一天。
他们也不需要担心自己的需要可能会变化然后跟当前所用的软件不兼容,因此用户可以得到保证,比特币的 Script 不会捆住他们的手脚。
与签名问题相关的问题是 储备金证明问题,就是一个公司如何证明自己 可以 花费一组比特币资金而又不必实际上花费它们。虽然这样的工具已经有了,比如 Blockstream 的 Proof of Reserves Tool,但业内还未形成通用的标准。没有 Miniscript,也可能无法形成标准,因为当前大家使用的托管方案太多样了。
我们先来看一个比特币 Script 开发者被互操作性的需要困住的例子。设想一个公司,托管着大量的比特币,并且希望这些资金只能在获得大多数董事的同意之后才能花费。但是,一些独立董事希望使用自己已有的钱包软件和硬件,而这些软硬件有复杂的签名设置,要动用放在多个不同位置的私钥;而且他们不想要一种只能使用特定设备来签名的方案。
没有 Miniscript,想要生成可以兼容所有签名者的要求、同时向所有签名者保证所生成的脚本可靠又完整、并且它们的钱包软件会兼容这个结果,将变成一个无法解决的问题。
使用 Miniscript,这些董事可以简单地在自己的钱包软件中组合这些花费方式,从而建构出一个描述了一个门限要求的花费方式,然后将它编译到 Miniscript。他们可以直接验证这个编译器的输出与最初的花费方式相匹配,而且最初的花费方式满足了每个人的要求。然后,他们可以使用任何兼容 Miniscript 的软件来计算接收资金的地址、在花费时收集签名、将这些签名组合成一笔有效的交易。
一个简单的理论案例:一个公司正在设置一个由两位董事参与的定制化多签名存储方案。一个董事已经在用 Blockstream Green 钱包(账户初始配置为 2-2,一段时间后会变成 1-2),而另一位董事正在使用 Electrum 钱包(标准的 1-1)。如果没有工具来组合安全的、可以互操作的脚本,我们是不可能让使用 Green 钱包的董事将自己的花费方式变成公司多签名设置的一个 “参与者” 的。但如果 Green 钱包以及构造这个公司多签的软件都支持 Miniscript,那么双方都可以继续使用自己喜欢的钱包,而且都无需知晓背后的脚本是什么。
Miniscript 威力的一个具体案例可以在 Blockstream 的 Liquid 侧链 中找到。一个当前正在开发的技术,内部称为 “ 动态联盟 ”的,允许当前的 Liquid 成员管理新成员的加入,以及更新控制着这个联盟所托管资金的花费条件的脚本。Miniscript 使联盟成员可以快速而高效地建构出这样的脚本 —— 实际上,Miniscript 编译器发现了当前的 Liquid 脚本 的一个更短的 22 字节的版本,轻轻松松就比最初我们煞费苦心人工优化的脚本节约了 5%。但更重要的是,它还使得联盟成员可以自动验证目标脚本的重要特性,从而减少联盟成员一个一个相互协作的需要,以及为目标脚本执行昂贵的人工安全审计的需要。
具体来说,联盟成员可以自动化验证目标脚本包括了:
Miniscript 也使他们能够验证新联盟的参与者是否能够花费旧联盟所控制的资金。这种检查对于保证交易不会导致资金损失是极为关键的,对想要把资金转移到这个系统的用户也是如此;而如果没有 Miniscript,在现实中也几乎不可能。
Miniscript 的想法形成于 2018 年夏天,是当时正在开发的多个想法的集大成者。在 7 月中旬,Pieter Wuille 为 Bitcoin Core 钱包引入了输出描述符(output descriptor),这是一种描述 Bitcoin Core 所支持的许多不同地址类型的通用方法。同时,那个夏天在 Blockstream 实习的 Andy Chow 提出了部分签名的比特币交易(PSBT,Partially Signed Bitcoin Transaction,由 BIP 174 详述)协议,它作为一种钱包互操作性协议,在钱包领域获得了越来越多的关注。
PSBT 的一个关键部分是 定稿器,某个参与者要负责收集签名者包含在部分签名的比特币交易中的数据并组合成一笔真正的比特币交易。这个组合过程需要理解被签名满足的脚本,这就意味着启用 PSBT 的钱包,如果要做一些复杂的事情,就必须实现自己的专用的定稿器,而这又需要冗余开发并限制了互操作性。
Blockstream 的 Andrew Poelstra 一直在努力为 rust-bitcoin(Rust 编程语言的一个通用比特币库)接受一种 PSBT 实现。这个实现是由 Carl Dong 提出的,但并未包含通用到足以支持该库的所有用户的定稿器。Poelstra 看到 IRC 频道里面 有人说“如果你有一种高度结构化的脚本模板,那你即使并不真的理解脚本也没关系了”,这个想法成了 Miniscript 的内核。
不相关的是,Poelstra 和 Wuille 一直在开发一个跟托管有关的项目,并因为缺乏可用于复杂的多参与者脚本的标准工具而遭受挫折。他们两位在 2018 年 8 月碰面讨论这个问题。Wuille 建议实现这些 “高度结构化的脚本模板” 作为 Bitcoin Coin 的输出描述符的一个插件。
随着这个插件成形,它开始分成两个东西:一个是比特币 Script 的结构化子集,也就是 Miniscript;一个是更简单的 “花费方式语言”,可以直接表示花费条件,并且可以编译成 Miniscript。在 2019 年 1 月, Wuille 在斯坦福区块链大会上演示了初步成果。
接下来,5 月,Sanket Kanjalkar 加入 Blockstream 开展三个月的实习,专门为 Miniscript 实现工具,并帮助集成到 Bitcoin Core。有了他的帮助,Miniscript 得以完成并多次重新设计成更小、更高效、更容易分析并且抗变形性(against malleability)更好的形式。最后的一组变更是为了验证一大批随机的 Miniscript 兼容脚本是否符合比特币的共识和标准规则。这些迭代的结果就是今天的 Miniscript。
Miniscript 基于并整合了比特币生态系统中的许多其它项目。具体来说,如上所述,Miniscript 延伸了 Bitcoin Core 钱包的 输出描述符,并与 PSBT 结合来启用完全通用的更新器和定稿器。
Miniscript 可以 跟 Ivy 相比较,Ivy 是另一种为了让比特币 Script 的高级特性更易用而设计的语言。不过,虽然 Ivy 可以编译成 Script,Miniscript 是 Script(的子集)的直接表示,意味着 “miniscript 程序” 的正确性和可靠性可以高效地验证。Miniscript 也支持许多其它形式的静态分析,而 Script 和 Ivy 都不可以。
Miniscript 的花费方式语言跟 Ivy 相似,两者都是抽象,都必须编译成 Script 才能在区块链上使用。不过,Miniscript 的花费方式语言跟 Miniscript 自身的结构相似,所以容易验证编译器的输出是否与编译器的输入相匹配 —— 实际上,你甚至可以手动验证 —— 也容易验证它是否与用户的期待相匹配。
另一种跟 Miniscript 相关的区块链语言是 Blocksteam 的 Simplicity。跟 Miniscript 一样, Simplicity 是一种设计成可以直接嵌入区块链交易中的低级语言。此外,Simplicity 也支持许多形式的静态分析,这在部署区块链合约时是至关重要的(但它的一些替代品,比如以太坊的 EVM,从设计上就使得这一点非常难甚至不可能实现)。
Miniscript 与 Simplicity 的区别在于,后者很强大,足以表达任何可计算的函数,而 Miniscript 的表达范围非常有限:它可以表达签名要求、时间锁、哈希原像,以及这些元素的任意组合。这种表达范围上的缩减使得 Miniscript 易于为它所覆盖的应用场景开展分析,更重要的是,这允许它在现有的比特币区块链上工作。相反,Simplicity 就跟比特币 Script 截然不同,依然处于其开发的早期阶段。
在设计 Miniscript 时,我们的目标是让比特币 Script 更加易用。虽然许多工作致力于研究和提议 Script 和比特币共识规则的变更以增加额外的特性,我们感觉到,基础设施的缺失使我们甚至无法通用、安全、可组合并且可互操作地使用已经存在的特性。
这部分工作还没有完成。我们有两个功能性的 Miniscript 实现(C++ 和 Rust)以及花费方式编译器,但为了让这些技术便于使用,我们需要将它们整合进常用的软件中。有了兼容 Miniscript 的 PSBT 实现(更新器和定稿器),许多 PSBT 签名器(包括基于硬件钱包的)将可以用在复杂的脚本中,即使没有明确的支持也可以。这个编译器也可以优化,因为在从花费方式到脚本的转换中,还有许多优化方法尚未被考虑。
在这个过程中,我们学到了许多东西:
OP_CHECKMULTISIG(VERIFY)
的密钥的数量,将它算进每个脚本不能超过 201 个非 push 操作码的限制中。有兴趣使用 Miniscript 来开发的开发者可以从我们的 在线编译器和分析器 开始研究 Miniscript 的构造。也许我们的 rust-miniscript 应用案例 也能帮到你。
我们欢迎对 C++ miniscript 和 rust-miniscript 库的贡献,你也可以在 Freenode 上的 IRC 频道 ##miniscirpt 关注我们团队,了解跟 Miniscript 有关的讨论!
(完)
- 本文转载自: btcstudy.org/2022/03/07/... , 如有侵权请联系管理员删除。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!