BSV 交易签名相关的技术名词

在介绍 BSV 交易的签名时,出现了不少技术名词。可能有一些历史原因、翻译的差别,抑或是习惯叫法的不同,导致大家给同样的东西起了不同的名字。这虽没有大的问题,但十分影响交流。

本文将试着对签名相关的技术名词做一个梳理和对应。

像和原像

对原始数据做哈希运算,可以得到其对应的数据指纹(数据摘要):

$$hash(m) = d$$

我们称:

  • $d$ 是 $m$ 的(image)
  • $m$ 是 $d$ 的原像(preimage)

交易摘要和交易原像

在对 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 对我的指导和帮助,以及对本文内容的审阅和优化。