跳转到正文
buybitcoinsmart

术语表 /开发者参考

OP_EQUAL

OP_EQUAL 是什么?
OP_EQUAL 逐字节比较栈顶的两个元素,并压入真或假的结果,它是每个 pay-to-script-hash 输出中的最后一个操作码。

字节0x87 完成比特币真正需要的唯一一种比较:这两段数据是否完全相同?这种比较针对原始字节,而不是针对数字,所以该脚本语言另设了一个用于算术相等的操作码。您发送到以3开头的地址的每一笔付款,其脚本都以这一条指令结尾。

运作方式

两个元素出栈,一个元素入栈:两者相符时压入单个字节0x01,不相符时压入一个空元素。比特币把空元素视为假,因此后续的任何指令都可以检验这一结果。

逐字节比较比听上去更严格。人们认为是同一个数字的两个值,可能是不同的字节串,而该操作码判定它们不相等。对于它的实际用途,这是正确的行为:它用于比较哈希值和原像,任何细微的差异都应导致失败,这也是算术结果改用 OP_NUMEQUAL 来比较的原因。

值得注意的特性在于它不做的事:它留下一个结果,而不是对结果采取动作。脚本只有在栈顶剩下的元素为真时才算成功执行,因此以该操作码结尾的脚本是在提出一个问题,并让结果直接作为答案。Bitcoin Core 的 cleanstack 规则还要求不得留下任何其他内容,对于脚本哈希的花费来说,这意味着恰好只留下一个真值,别无其他。

最后这一点的影响比看上去更大。Pay-to-script-hash 并不是关于哈希脚本的一般规则,而是针对一个精确的23字节模式的规则:一个哈希操作码、一次20字节的推送,以及末尾的这个操作码。如果改用合并的 verify 形式来写同样的逻辑,特殊处理就不适用,赎回脚本不会被提取或执行,该输出的表现就像普通的哈希谜题,任何猜出原像的人都可以花费。

在哪里会遇到它

在区块浏览器上,以3开头的地址上的每一个未花费输出都显示相同的三个标记的汇编,并以此结尾。交易所向您发送的每一笔封装 SegWit 提币也是如此。

它也出现在哈希锁定合约中。闪电网络的支付脚本对一个秘密值取哈希,并将结果与一个固定值比较,这使得收款方一旦披露32字节的原像,支付就能在多个跳点之间完成结算。链间的原子交换使用相同的结构。

OP_EQUAL vs OP_EQUALVERIFY

OP_EQUALVERIFY 就是内置了检验的 OP_EQUAL。字节0x88 执行相同的比较,如果结果为假则立即中止脚本,成功时栈上不留任何内容。在两者之间选择,取决于后面还要做什么。当比较本身就是脚本的最终答案时,使用普通形式,pay-to-script-hash 即是如此。当比较只是若干条件之一、执行必须继续时,使用 verify 形式,传统的单密钥模板在检验签名之前就是这样做的。与分别写出比较指令和单独的验证指令相比,verify 形式还能节省一个字节,这在脚本的每个字节都位于交易的非见证部分、每字节占四个权重单位的时代要重要得多。

请勿混淆

常见问题

OP_EQUAL 和 OP_EQUALVERIFY 有什么区别?

普通形式在栈上留下真或假,供其他指令读取,而 verify 形式在两个元素不同时会立即中止脚本。Pay-to-script-hash 使用普通形式,因为这一比较就是脚本的最终答案。

它比较的是数字还是字节?

比较的是字节,不做任何解释。表示同一个数字的两种编码在这里是不相等的,这正是比较哈希值时所需要的,也是算术比较使用另一个操作码的原因。

相关术语

开发者参考中的更多术语

阅读本页英文版