跳转到正文
buybitcoinsmart

术语表 /开发者参考

Bitcoin Script

又称比特币脚本。

Bitcoin Script 是什么?
比特币脚本是每笔比特币输出所携带的一种基于栈的小型脚本语言,用于设定在这些比特币再次被花费之前,花费者必须满足的条件。

币并不是发送给某个人的。它们被锁定在一段简短的程序之后,而花费比特币就是提供数据,使该程序执行结束时栈顶为真值。该语言没有循环,也没有递归,传统脚本最多只能有10,000字节和201项操作,因此验证者始终知道运算会结束。这就是比特币从未出现过失控合约的原因。

运作方式

比特币脚本是一种从左到右读取的栈式机器,除此之外不做任何事。

数据推入栈中;操作从栈中弹出其参数,再把结果推回栈中。脚本没有变量,没有向后跳转,也无法读取正在验证的交易之外的任何内容。脚本在执行完毕且无错误、栈顶为真值时即为成功。

花费时有两部分相遇。被花费的输出带有锁,称为公钥脚本。花费它的输入带有证明,对较旧的输出称为签名脚本,对隔离见证输出称为见证。二者按先后顺序运行,栈在两者之间传递,绝不会拼接成一个程序。这一分离是早期引入的,因为当时发现,如果花费方能够向锁定一侧注入操作符,就可以改写花费条件。

比特币历史上最常见的脚本值得完整读一遍。一个 pay-to-public-key-hash 输出包含 OP_DUP、OP_HASH160、一个20字节的哈希、OP_EQUALVERIFY 和 OP_CHECKSIG。花费方提供一个签名和一个公钥。执行时先推入两者,复制公钥,把副本哈希为20字节,推入预期的哈希,比较两者,若不一致则中止,然后针对交易本身的序列化数据验证签名。共六个步骤,传统地址的全部安全性都建立在这六步之上。

这些限制是刻意设定的,也十分精确。传统脚本或 P2SH 脚本不得超过10,000字节或201项非推入操作。栈上的单个元素不得超过520字节。栈中不得容纳超过1,000个元素。单个 OP_CHECKMULTISIG 不得指定超过20个公钥。每一项上限的存在,都是为了无论有人写出什么脚本,验证一个区块的成本都保持有界。

该语言已经扩展过两次,方法是赋予保留的空操作码以实际含义。BIP65 在2015年12月定义了 OP_CHECKLOCKTIMEVERIFY,使输出可以在指定时间或区块高度之前拒绝被花费。BIP112 对 OP_CHECKSEQUENCEVERIFY 做了同样的事,该操作码自2016年7月的区块419,328起生效,增加了从币被确认时起计的相对时间锁。正是这两个操作码,使闪电网络通道、带截止期限的担保托管以及带时间锁的继承方案得以存在。

购买比特币时为何重要

您提币的地址是一种脚本类型,这一选择会体现在您下一笔手续费上。

花费一个传统 pay-to-public-key-hash 输入大约需要148虚拟字节。花费一个原生隔离见证输入大约需要68,因为 BIP141 引入的见证折扣按四分之一的费率计收见证数据,而 taproot 密钥路径花费则更小。在20 sat/vB 的费率下,这一差距就是小额提币的大部分成本,而且每次转移比特币都会重复发生。如果交易所允许您选择提币地址格式,选用较新的格式就是一项永久性的折扣。

脚本同样是多签金库的实质所在。2-of-3的安排就是一段脚本,指定三个公钥并要求两个签名,而某台设备能否如实显示并签署这样的脚本,本站的硬件钱包评测对此有直接讨论。任何基于时间锁的继承计划也是如此:只有仍有人持有该脚本,币才能找回,因此输出描述符(重建该脚本的纯文本配方)应与助记词一起纳入您的备份。

一项实用警告:当某个平台拒绝向您粘贴的地址发送时,原因几乎总是其提币代码无法构建该脚本类型,而不是您的地址有误。在转移您在意的余额之前,请先用少量资金测试任何不熟悉的地址格式。

1,840亿比特币漏洞与中本聪关闭的操作码

在2010年8月15日,区块74,638中包含一笔交易,创造了184,467,440,737.09551616比特币,分为两个输出,每个约922亿。

检查交易输出是否超过输入的代码使用定长有符号算术,而大到足以使该算术溢出的输出,其总和会变成负数,因此检查得以通过。大约五小时内出现了已修补的客户端,诚实链在高度74,691超过了问题链。这些币从未存在于人们实际使用的链上。

这一事件,加上字符串和算术操作中一系列相关漏洞,就是十五个操作码被永久禁用的原因:OP_CAT、OP_SUBSTR、OP_LEFT、OP_RIGHT、OP_INVERT、OP_AND、OP_OR、OP_XOR、OP_2MUL、OP_2DIV、OP_MUL、OP_DIV、OP_MOD、OP_LSHIFT 和 OP_RSHIFT。脚本中只要包含其中任何一个,该交易即无效,无论是否被执行。这次禁用是在时间压力下采取的粗糙手段,撤销其中一部分仍是正在进行的工作:BIP347 提议在 tapscript 中恢复 OP_CAT,那里较新的限制使其被滥用的难度大得多。

比特币脚本 vs tapscript

tapscript 是重新划定规则的比特币脚本,仅适用于 taproot 脚本路径花费之内。BIP342 取消了10,000字节的脚本大小上限和201项操作的上限,禁用了 OP_CHECKMULTISIG 和 OP_CHECKMULTISIGVERIFY,并增加 OP_CHECKSIGADD 作为替代,使多重签名策略可以批量验证。签名检查改为按预算计量而非计数:每个输入获得50加其见证序列化大小的预算,每次执行签名检查消耗其中的50。栈式机器相同,计量方式不同。

比特币脚本 vs 公钥脚本

比特币脚本是语言;公钥脚本是用该语言写成的一个程序。输出包含公钥脚本,即锁。花费它的输入包含签名脚本或见证,即钥匙。二者都是比特币脚本,而把其中任何一个简单地称为“脚本”,是阅读原始交易时最常见的混淆来源,因为这两半是分别求值的,而收到币时只有其中一半被承诺锁定。

请勿混淆

常见问题

比特币脚本(Bitcoin Script)是图灵完备的吗?

不是,而且这是有意为之。它没有循环,也没有递归,传统脚本被限制在10,000字节和201次操作以内,因此验证者可以在运行脚本之前就确定其成本上限。正因如此,比特币从未需要按 gas 计量。

购买比特币需要了解比特币脚本吗?

不需要,但您提币所用的地址类型就是一种脚本类型,并且决定了您的手续费。花费一个传统输入约需148虚拟字节,而原生 segwit 输入约为68虚拟字节,taproot 则更低。

为什么有这么多比特币操作码被禁用?

原因是2010年发现的漏洞,其中包括在区块74,638中凭空创造出1,840亿枚比特币的数值溢出。十五个字符串和算术操作码被关闭,目前 BIP347 提议在 tapscript 中恢复 OP_CAT,因为那里的限制更严格。

比特币能实现智能合约吗?

在一定限度内可以。多重签名规则、绝对和相对时间锁以及哈希锁都属于普通的比特币脚本,闪电网络完全由它们构建而成。它做不到的是循环、调用自身,或读取交易之外的任何数据。

接着阅读

相关术语

开发者参考中的更多术语

阅读本页英文版