Bitcoin Script 是表达花费条件的语言。每个交易输出,也就是附带下一次使用条件的一笔金额,都带有这些条件。想花费它的人必须满足条件。Script 帮助回答一个简单的问题:这笔交易是否有权使用这笔特定的资金?
Alice 收到 20 000 sat,也就是两万个比特币最小单位。网络不会以她的姓名开立账户,而是创建一个交易输出:一笔金额,以及今后花费它的条件。在被花费之前,这个输出称为 UTXO。普通付款的条件通常要求用对应的密钥签名。Alice 日后付款时,她的钱包选取这个输出,在新交易的输入中引用它,并生成数字签名。钱包使用私钥完成签名,但不会把私钥发送出去;其他人通过公钥验证签名。仅知道 Alice 的收款地址并不够。原始输出的条件记录在 scriptPubKey 字段中,Bitcoin Script 规定如何检查这些条件是否满足。节点不是认得 Alice 的办事员,而是检查规则的计算机。除了签名,它还要检查同一个输出是否已经被花费等事项。只有满足所有适用规则,交易才有效。 [4] [2]
普通付款的条件由钱包构建。请按钱包的说明备份;在兼容钱包中用备份词正常恢复,并不意味着必须手动保存每个脚本。但在需要多个签名的 Multisig 等复杂安排中,一个参与者的备份词可能无法描述完整的花费方式。 日常使用应选择采用经过验证流程的钱包,而不是手工用十六进制编写脚本。输出描述符说明脚本类型、密钥及其派生方式,帮助恢复后的钱包确定要查找什么。要恢复较复杂的安排,仅有私钥可能不够。还应保存必要的脚本和密钥来源信息,也就是密钥从哪里、以什么方式派生,并验证预期使用的花费路径。 [11]
下面的章节介绍条件如何在交易内部编码;日常付款并不要求掌握这些知识。scriptSig 字段和称为 witness 的部分提供验证数据。哈希是数据的指纹,时间锁则禁止在规定的门槛之前花费。可以把栈想象成一叠从顶部取放的数据项。 Script 使用栈处理数据:把值放入栈中,再由称为操作码的指令取出、比较或以其他方式处理它们。签名指令负责验证签名;私钥和签名生成不属于这个验证过程。该语言可以组合签名、哈希条件和时间锁,但没有通用循环,也不是图灵完备的,也就是说,它无法表达通用编程语言能表达的所有计算。节点必须使用与相应输出类型及脚本版本匹配的准确规则。 [1] [3]
P2PKH (Pay to Public Key Hash) 输出通常采用 OP_DUP OP_HASH160 <PubKeyHash> OP_EQUALVERIFY OP_CHECKSIG 这一形式。输入在 scriptSig 中提供签名和公钥。验证过程先检查公钥的哈希是否与输出中的值相符,再验证签名。因此,仅仅知道地址或公钥,并不足以花费这样的输出。使用私钥的是签名的钱包,而不是检查交易的节点。 [1]
P2SH 按 BIP16 在输出中保存脚本的哈希。花费它的输入提供对应的 redeemScript,也就是在花费时公开的脚本,以及必要的数据。其 scriptSig 只能包含把数据压入栈中的指令。节点先检查哈希是否匹配,再利用栈中剩余的数据项执行 redeemScript。哈希正确本身还不够,还必须满足这个脚本的条件。 [5]
在 SegWit 版本 0 中,验证所需数据被移到交易中称为 witness 的部分。它是数据项列表,本身并不是脚本。P2WPKH 使用签名和公钥;P2WSH 还包含 witnessScript,其 SHA256 哈希必须与输出匹配。原生 SegWit 的 scriptSig 为空。包装在 P2SH 中时,scriptSig 只包含压入相应 witness 程序的指令,实际验证数据仍然放在 witness 中。 [6]
签名验证针对的是按规定流程从交易派生出的消息。SIGHASH 模式决定签名保护交易的哪些部分不被修改。因此,不能想当然地认为每个签名都覆盖整笔交易。BIP143 对 SegWit 版本 0 的签名操作始终纳入被花费输出的金额。钱包必须掌握正确数据以及选用的模式;Script 验证时不会判断签名者的意图。 [7]
Taproot 按 BIP341 提供两种花费 P2TR (Pay to Taproot) 输出的方式。密钥路径根据输出公钥验证 Schnorr 签名,无须公开脚本。脚本路径则公开选定的脚本和控制块,即 control block,后者证明脚本与输出的关联。树中的其他脚本不必公开。公开脚本适用的规则也取决于相应叶子的版本。 [8]
BIP342 为版本 0xc0 的 Taproot 叶子定义了 Tapscript。这里的签名指令使用 Schnorr 签名,OP_CHECKSIGADD 可以构造需要多个签名的条件。旧的 OP_CHECKMULTISIG 在执行时被禁止。它不沿用之前 10 000 字节的脚本长度上限,也不沿用按旧规则计数的 201 个操作码上限。签名操作次数受依据 witness 大小计算的预算限制,栈的限制则仍然存在。因此,不能把某个版本的限制说成整个 Script 都具备的共同特性。 [9]
共识规则决定一笔花费在区块内是否有效。交易的标准性是指节点对未确认交易进入 Mempool 及后续转发所施加的额外本地规则,并不是制定标准的过程。因此,一笔符合共识的交易未必会被通常的节点转发。Tapscript 中的 OP_SUCCESSx 尤其需要注意:此前的检查成功后,一旦在解码时识别到它,脚本验证就会在常规执行和栈检查之前以成功结束。这是为未来扩展预留的空间,不是普通、安全的花费条件。 [10] [9]
要获得更完整的理解,请将本词条与以下词条结合阅读: 交易, Multisig, Timelock, Taproot. 反向关联还来自: Hash, SHA-256, 共识规则, Timelock.