比特币提供了世界上第一种智能合约编程语言.脚本,正如这种语言所称的那样,让用户可以对可以花费硬币的不同条件进行编码.但是,虽然这是一个革命性的概念,但它并不容易使用,尤其是对于更复杂的支出条件.编写复杂的合同以及验证合同是否完成了它应该做的事情都容易出现人为错误.然而,尤其是在涉及金钱的情况下,对条件的正确解释至关重要.
在过去的一年里,区块链工程师 Andrew Poelstra,Pieter Wuille 和 Sanket Kanjalkar 着手改进这一点.通过将 Script 剥离到其基本要素,他们的"新"编程语言 -  - " Miniscript " -  - 抽象了复杂性,应该让比特币编程对每个参与者来说更容易,更安全.
"从理论上讲,Miniscript 比脚本更具限制性,"Blockstream 研究总监兼 Miniscript 联合设计师 Andrew Poelstra 告诉比特币杂志."但它可以完成人们实际使用脚本所做的一切."
让我们从头开始.
每笔比特币交易都由两个主要部分组成:输入和输出,两者都由代码片段组成.输入"解锁"硬币,输出再次"锁定"硬币,指定在哪些条件下它们可以在后续交易输入中解锁.这种要求通常包括有效的加密签名,但还有更多的可能性;例如,可能必须经过一定的时间才能花费硬币或必须包含特定的秘密数字.
交易中的这些代码是用脚本创建的,脚本是一种专为比特币设计的编程语言.Script 的灵感来自 Forth,这是一种 1960 年代发明的编程语言,最初设计用于操作射电望远镜.然而,脚本经过调整,使其更适合比特币.
例如,Script 没有产生"循环"的操作码(指令):该语言不支持无限次执行相同的计算.在比特币中,不需要无限次地执行相同的计算,因为比特币节点实际上并不计算交易 -  - 它们验证交易.(有关为什么会出现这种情况的更多技术解释,请参阅Blockstream 工程师 Russell O'Connor 的这篇文章.)
脚本也是"无类型的".这意味着可以以不同的方式解释和使用计算结果.例如,有效签名的结果可以是"真",但"真"又可以被解释并用作数字"1",随后在数学方程中使用:"真"加"真"将相加最多为"2",例如,如果至少需要两个有效签名,则这可能意味着提供了足够的签名.
这给我们带来了本文上下文中 Script 最重要的属性:很难"推理".这实质上意味着计算结果可以用多种方式解释.例如,即使签名无效,也可以编写脚本以使交易由于某些其他原因仍然有效.
Poelstra 解释说:"比特币脚本中有一些操作码会做一些非常荒谬的事情." "比如,将签名解释为真/假值,然后分支;将该布尔值转换为数字,然后索引到堆栈中,并根据该数字重新排列堆栈.它如何做到这一点的具体规则非常疯狂."
这可能会使 Script 难以使用.特别是如果花费("解锁")硬币的要求变得更加复杂,交易的作者可能会无意中在代码中包含一些内容,允许在与预期不同的条件下花费硬币.相反,交易的接收者可能没有注意到这种怪癖,并且会将他的硬币丢失给注意到的攻击者.
以下是这些问题如何限制 Script 有用性的具体示例.
Blockstream Green 钱包具有标准的"共同签名"设置.钱包用户控制两个密钥之一,Blockstream 控制另一个.资金可以通过两种方式使用.首先,每当用户想要花费硬币时,他们都会对交易进行签名并请求 Blockstream 对其进行签名.Blockstream 通常会这样做,尽管这可能需要用户确认他们确实想通过辅助方式进行交易,例如电子邮件确认.但是 Blockstream 的最终可能会出现问题 -  - 可能是公司消失或丢失了密钥,或者由于其他原因无法签署.在这种情况下,用户仍然有一个后备解决方案来花费他们的比特币:在时间锁定到期后,他们可以在预定的时间过去后创建一个有效的交易.也许一个月.
这工作正常,但也有局限性.用户不能再使用比特币的智能合约潜力,即使他们可能希望在设置结束时增加更多的灵活性.
Poelstra 说:"现在 Green 有一个固定的脚本供所有客户使用,基本上只是一个简单的多重签名." "但实际上,我们不应该关心脚本说了什么.我们关心的是:在一些超时之前,没有我们的签名,币是不可能花掉的吗?如果用户想对我们使用一些疯狂的政策,只要满足我们关心的一个条件,我们应该能够支持它."
例如,用户可能希望让他们的亲人在一年过去后花费硬币,以防他们去世.或者,也许用户实际上是一家公司,它想要创建一个多重签名设置,其中三分之二的董事会成员可以一起使用硬币(与 Blockstream 结合使用).
目前,这在技术上可以通过比特币脚本实现.但是,这需要用户设计自定义设置,而 Blockstream 需要参与此自定义设置.
"但如果用户给我们一个任意的脚本,我们就无法判断我们关心的那个条件是否得到满足,因为所有脚本行为的总集真的很复杂,"Poelstra 解释说."例如,如果脚本似乎需要签名,我们需要考虑如果用户不签名会发生什么.会不会被骗到让币被花掉?"
简而言之,Miniscript 是 Script 的"精简版":从"Script 工具包"中选择的"工具",使其更易于使用且更易于人类验证.这些工具都是经过精心挑选的,几乎可以用 Script 完成任何事情 -  - 只有一些边缘例外,无论如何都没有人实际使用.因此,尽管一行 Miniscript 仍然是有效的 Script 行,但它通过防止代码出现意外的,可能是非预期的结果,从本质上避免了人为错误.
以上面的问题为例,使用 Miniscript,用户可以轻松地设计设置,以便 Blockstream 可以轻松检查其一个条件是否满足.具体来说,Blockstream 可以看到,只有在签名或一个月过去后才能使用资金 -  - 无论用户在设置结束时包含哪些其他条件,无论是额外的时间锁或多重签名还是其他任何东西.使用 Miniscript,不会有任何意外的怪癖会覆盖 Blockstream 的结局.
Miniscript 非常简单和可预测,事实上,设置总是可以变成决策树:设置的可视化("图片编码"),这很容易推理.
例如,下面的可视化显示了一个设置,其中三分之二的用户需要签名才能移动硬币.作为备用选项,可以使用紧急钥匙移动硬币,但必须经过一段时间后才能移动.
Miniscript 的可视化 [作者注:感谢 Tejaswi Nadahalli指出早期对可视化的描述是不正确的.]
"使用 Miniscript,Blockstream 可以轻松参与更复杂的设置 -  - 我们将脚本解码成一棵树,然后检查树的每个叶子,询问 (a) 这个叶子是否有超时条件?或者(b)这片叶子需要我们的签名吗?" 波尔斯特拉说.
如果两个问题的答案都是肯定的,则 Blockstream 可以参与.
虽然 Miniscript 是一项正在进行的工作,但它的早期版本已经发布并可以使用.
为了使编写 Miniscript 的过程更加容易,Wuille 还设计了一种"策略语言".策略语言真的很像它自己的编程语言.在用这种策略语言对硬币可以花费的条件进行编程之后,它可以被编译("翻译")成 Miniscript,因此被编译成有效的脚本,以包含在比特币交易输出中.
这种策略语言的一大额外好处是它会自动编译成最好,最高效的 Miniscript 版本,这取决于脚本实际编码的内容.
"关于 Miniscript 的事情是它基本上是脚本......你有很多不同的方式来写 'or',有很多方式来写 'and',有些比其他的更有效,"Poelstra 说."策略语言只有一个'或',一个'和'等等,而 Pieter [Wuille] 编写了这个超级优化的编译器,它将为您将其转换为 Miniscript,并以最佳方式进行."