跳转到正文
buybitcoinsmart

术语表 /开发者参考

OP_DUP

OP_DUP 是什么?
OP_DUP 复制栈顶元素以便使用两次,这正是标准的 pay-to-public-key-hash 脚本既能对您的公钥计算哈希、又能用它进行验证的原因。

一个字节,0x76,只做一件事。比特币脚本(Bitcoin Script)没有变量,只有栈,因此一条指令消耗的元素在下一条指令运行之前就已消失,复制是重复使用它的唯一办法。它是25字节脚本中四个实际运行的操作码里的第一个,而该脚本保护着几乎所有以1开头的比特币地址。

运作方式

之所以必须复制,是因为验证需要把同一个公钥用于两个互不相容的目的。输出只锁定了一个哈希,因此必须先对公钥计算哈希并加以比对,才能证明这是正确的公钥。随后的签名检查需要公钥本身,而比对时它已被消耗。

请完整跟踪一次传统(legacy)支出。花费者的数据以签名的形式进入栈,公钥位于签名之上。OP_DUP 复制出公钥的第二份。OP_HASH160 用该副本的20字节摘要替换它。输出压入已锁定的20字节,OP_EQUALVERIFY 消耗这两者,一旦不匹配就中止整个脚本,此时 OP_CHECKSIG 面对的正是原始公钥和签名,恰好是它所需要的。一共五步,没有分支,没有循环,每次的成本固定。

该操作码要计入两项上限,但自身并不耗费高昂资源。它是 Taproot 之前的脚本可包含的201条实际运行指令之一,它所做的复制也计入各栈合计1,000个元素的上限。对于单密钥支出,这两项都无关紧要;而在一个没有循环、但在一连串条件中复制的脚本里,这两项都很重要。

在哪里会遇到它

查看任何花费以1开头地址的交易,其输出脚本都以 OP_DUP 开头。区块浏览器会把它显示为汇编表示中的第一个词。

更有意思的是它在不出现的情况下运行的地方。原生 SegWit 的单密钥输出不包含任何逻辑,只有一个版本字节和一个20字节的哈希,但 BIP-141指示节点依据该哈希构建经典模板并照常执行。因此,网络上每一笔 P2WPKH 支出仍会触发该操作码,而它在区块中的任何位置都不会出现。您得到了同样的行为,却无需支付该字节过去所占用的四个权重单位。

脚本哈希输出和 Taproot 的密钥路径支出则完全跳过它。P2SH 输出直接比对哈希,Taproot 的密钥支出则不涉及任何脚本,直接依据输出密钥验证签名。这是对 SegWit 和 Taproot 实际作用的最小例证:与其说是新增能力,不如说是把同样的检查重新安排,使区块链为获得这些检查而需要承载的字节更少。

常见问题

脚本为什么需要复制东西?

因为比特币脚本(Bitcoin Script)有栈而没有变量。每条指令都会消耗它所读取的内容,因此,一个要先计算哈希、再用于签名检查的公钥,必须在第一步将其销毁之前先复制出来。

相关术语

开发者参考中的更多术语

阅读本页英文版