术语表 /开发者参考
公钥脚本
又称 scriptPubKey、锁定脚本、Pubkey script。
- 公钥脚本是什么?
- 公钥脚本是附在每个交易输出上的一小段比特币脚本(Bitcoin Script),规定了该输出中的比特币再次转移之前必须满足的条件。
比特币并不存放在地址中,而是存放在输出里,每个输出由一个公钥脚本保护。Bitcoin Core 把这个字段称为 scriptPubKey,对于普通的现代输出,它的长度为22或34字节。当您把地址交给别人时,等于交给对方一份配方,对方的钱包据此写出公钥脚本。
运作方式
序列化交易中的每个输出依次包含三部分:以聪为单位的8字节金额、长度前缀和公钥脚本本身。输出中没有任何内容指明收款人。脚本就是收款人,而地址只是其中那几个字节带校验和的编码。
如今链上几乎所有输出都属于五种模板。传统的 pay-to-public-key-hash 锁定脚本长25字节,在20字节的哈希两侧共有四个操作码。pay-to-script-hash 锁定脚本长23字节,以 OP_EQUAL 结尾。相比之下,原生 SegWit 刻意做得很简单:一个版本字节加一次数据推送,单个公钥为22字节,脚本哈希为34字节,输出中完全没有逻辑。Taproot 同样为34字节,由一个版本字节和32字节的公钥组成。
中继策略只认这份简短的清单,拒绝转发其他任何格式,因此您无法自创输出格式并指望钱包向其付款。在这一点上,共识规则比中继策略宽松,但实际效果是这五种模板就是全部可选项。
这个名称是历史遗留。在最早的交易中,脚本确实包含公钥:创世区块的 coinbase 输出为67字节,包含一个65字节的未压缩公钥,后接 OP_CHECKSIG,您可以在 Bitcoin Core 自身的源代码中读到。向哈希而非公钥付款在2011年成为通行做法,如今大多数公钥脚本完全不含公钥,只含对公钥的承诺。
在哪里会遇到它
让任何节点解码一笔原始交易,每个输出都带有一个 scriptPubKey 对象,包含四个字段:便于阅读的汇编形式、原始十六进制、类型字符串,以及该类型对应的地址。区块浏览器显示的是同样的内容,通常改称锁定脚本或输出脚本。
钱包的仅观察设置也在这里。导入地址,就是告诉您的软件要在链上扫描哪些公钥脚本,因此在专业工具中,描述符(一种可生成某个密钥能产生的全部脚本的定义)已取代了逐个地址导入。
实用的识读技巧很简单。如果脚本以0开头且含20字节,花费它的人只需一个签名和一个便宜的输入。如果含32字节,背后就有一份您看不到的合约。如果以1开头且含32字节,则是 Taproot,它可能是单个密钥,也可能是一整棵条件树,外表却完全相同。
公钥脚本 vs 签名脚本
公钥脚本提出问题,签名脚本尝试作答,两者由不同的人在不同的时间写成。向您付款的人根据您提供的地址写出公钥脚本,并支付这些字节的费用。您日后花费时再写签名脚本,并自行支付这些字节的费用。因此,向 Taproot 地址付款,发送方的成本略高于向传统地址付款,而您日后转移这笔比特币时能节省得多得多。这两种脚本也是分别运行的,而不是合并成一个程序,这一改动在2010年作出,原因是最初的合并执行方式被发现可被利用。