跳转到正文
buybitcoinsmart

术语表 /开发者参考

OP_CHECKMULTISIG

OP_CHECKMULTISIG 是什么?
OP_CHECKMULTISIG 可一步完成一组签名与一份公钥列表的验证,而 Taproot 花费完全不能使用它,因为它会阻碍批量验证。

规定于 BIP-11。

字节0xae 使共享托管成为可能:它依次弹出一个密钥数量、相应数量的公钥、一个所需签名数量、相应数量的签名,最后再多弹出一个元素。共识规则允许单次调用最多包含20个密钥。正因如此,公司可以要求五名高管中有三名批准才能提币,而其中任何一人都无法单独操作。

运作方式

验证是沿两份列表的一次遍历,而不是搜索。该操作码按顺序遍历签名,并将每个签名与后续的公钥逐一比对,因此签名出现的相对顺序必须与其所对应的公钥一致。若提交一个有效的2-of-3,但将两个签名对调,脚本就会失败,这是人们手工组装多重签名花费时常见的困惑原因。

堆堆堆栈在执行后总会少一个元素,而且一直如此。最初的实现会多弹出一个从未使用的元素,这一错误无法在不破坏所有现有币的前提下移除。签名者因此学会先压入一个占位元素,BIP-147则要求该元素必须为空,自区块481,824起生效,从而堵住了由此产生的可延展性问题。

成本计量是它的麻烦所在。一次裸调用无论实际包含多少个密钥,都按20次签名操作计费,除非其前面紧跟一个小数字操作码,此时按该数字计费。一个区块的签名操作成本上限为80,000单位,而中继策略在单个 pay-to-script-hash 输入中最多允许其中的15个。是这个策略数字,而不是该操作码自身的20个上限,决定了脚本地址的联合签名者最多为十五人。

Tapscript 则直接将其废除。BIP-342规定,该操作码及其 verify 变体一旦出现在 Taproot 叶子中就会失败,因为用一次操作将一批 Schnorr 签名与一份列表进行比对,会破坏 Schnorr 之所以有价值的批量验证。

在哪里会遇到它

为每个闪电网络通道提供资金的2-of-2输出使用 OP_CHECKMULTISIG,仅此一项就使该操作码出现在网络中相当大一部分脚本花费中。企业财库、较早的点对点交易市场上的担保托管安排,以及 Taproot 之前建立的交易所冷存储也使用它,通常是脚本哈希内的2-of-3。

裸调用是指密钥直接放在输出中、前面没有哈希,最多三个密钥时符合中继标准,但几乎无人使用,因为发送方要为每个密钥付费,而且在任何一枚币移动之前,整个安排就已公开。2014年,该格式一度成为在链上存储文件的一种方式,这也是每当有人调整中继策略时,数据存储之争仍会重新出现的部分原因。

如果您现在要设置共享托管,您的钱包更可能生成使用计数式替代方案的 Taproot 安排,或者在兼容性比手续费更重要时生成 P2WSH 脚本。

OP_CHECKMULTISIG vs P2SH 多重签名

OP_CHECKMULTISIG 是一条指令,而 P2SH 多重签名是对它的一种封装方式。操作码说明如何检查签名阈值;封装方式则说明该阈值隐藏在哈希之后,并在花费时才披露。同一条指令可以出现在密钥一目了然的裸输出中,也可以出现在以3开头的地址背后的赎回脚本中,或者出现在 bc1q 地址背后的见证脚本中,三者的验证逻辑完全相同,成本和隐私性却相差极大。不能做的是在 Taproot 叶子中使用这条指令,因此现代的签名阈值方案是用另一个完全不同的操作码构建的。

请勿混淆

常见问题

为什么所有签名都有效,我的多重签名花费仍然失败?

几乎总是因为签名顺序有误。该操作码并行遍历两份列表,因此签名出现的相对顺序必须与其公钥一致,而且它不会回头重试之前的密钥。

该操作码正在从比特币中移除吗?

它在旧版脚本和 SegWit 版本0脚本中仍然有效,并将继续有效,因为现有的币依赖于它。Taproot 叶子不能使用它,因此新的签名阈值方案使用 OP_CHECKSIGADD 构建,后者逐个统计已验证的签名。

接着阅读

相关术语

开发者参考中的更多术语

阅读本页英文版