在介绍 BSV 交易的签名时,出现了不少技术名词。可能有一些历史原因、翻译的差别,抑或是习惯叫法的不同,导致大家给同样的东西起了不同的名字。这虽没有大的问题,但十分影响交流。
本文将试着对签名相关的技术名词做一个梳理和对应。
像和原像
对原始数据做哈希运算,可以得到其对应的数据指纹(数据摘要):
$$hash(m) = d$$
我们称:
交易摘要和交易原像
在对 BSV 交易签名时,我们会先根据原始交易为每个输入计算它对应的交易摘要(这是我“自创”的词),然后为每个输入做 ECDSA 签名。
交易摘要由 10 个部分构成,在 BIP-143 中定义。我们说,这个交易摘要就是被签名的消息。
在输入的解锁脚本中,有 1 个字节的标记数据,用来指示交易摘要具体的计算方式,一共有 6 种可能。我们把这个标记称为 SIGHASH 标记(SIGHASH flags)。在其它资料中,SIGHASH 标记常见的名称还包括:
- SIGHASH type(s)
- Signature type(s)
- Signature Hash type(s)
在某些特定的上下文中,也可以直接用 SIGHASH 来表示。请注意,这里的 SIGHASH 一般会大写。
ECDSA 算法会对消息做哈希。
在对输入签名时,选取的哈希方法是 SHA256 双哈希(double-SHA256,也常用 hash256 表示)。一般的,我们把交易摘要哈希后的结果,称为 sighash。请注意,这里的 sighash 一般会小写。
$$hash256(交易摘要) = sighash$$
sighash 是 SignatureHash 的缩写。在比特币节点的早期实现中有一个叫 SignatureHash 的函数,用于根据交易输入和当前交易计算要签名的消息对应的哈希,所以常用 sighash 来表示这个函数的计算结果。
uint256 SignatureHash(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); |
结合刚才像和原像的概念,在 sCrypt 中,会把交易摘要称为 sighash preimage,可以翻译成 sighash 原像或交易原像。
BSV 交易原像的一些历史:
- 在很久以前,为了能对整个交易签名,会直接把序列化后的交易数据作为 sighash preimage 的一部分
- 后来提出了 BIP-143,改用 hashPrevouts、hashSequence 和 hashOutputs 三个摘要来简化
- 2017 年 Bitcoin Core(BTC)分叉时,Bitcoin Cash(BCH)在代码里再次修改了 SignatureHash 方法(新增值为 0x40 的 FORKID)来避免重放攻击(replay attack)。对之前没有 FORKID 的交易(之前交易的 FORKID 值相当于是 0),通过调用原来的方法来实现向后兼容(Backward Compatibility)
- BSV 和 BCH 目前使用的都是兼容 BIP-143 的 sighash preimage 算法
致谢
特别感谢 nChain Research Team 的 Wei Zhang 对我的指导和帮助,以及对本文内容的审阅和优化。