比特币技术 — 交易的验签原理

作者:林冠宏 / 指尖下的幽灵。转载者,请: 务必标明出处。

博客://www.cnblogs.com/linguanh/

掘金://juejin.im/user/1785262612681997

GitHub : //github.com/af913337456/

出版的书籍:


本文风格采用单刀直入方式。

前提信息

  1. 私钥 可以推出 公钥;
  2. 公钥 可以推出 公钥哈希;
  3. 1 和 2 皆不能反推。

发交易时 — 签名数据的组成

花费比特币的一个输入,即花费 input 的时候,在构建交易的时候,签名阶段需要在 input 结构中,携带上签名数据体,即 signature_script。其核心结构如下:

{
    "outpoint":{
        "tx_hash": "",
        "index": 0
    },
    "signature_script": object,
    ...
}

关键在 signature_script 中,它的组成有几部分,结合下面源码片段可知。

signature_script = 其它 + signature + pkData

image.png

上面等式右边的其它,代表是一些比特币虚拟机的操作码,我们忽略它。然后,signature 私钥是对交易签名的真实数据,pkData 是从私钥privKey 推出的公钥哈希(pubkeyHash)。

发交易时 — 接受者的 output 组成

output 即输出,可以在里面指明转账的收款人是谁,收多少数值的 btc,其结构是:

{
    "value": 1,
    "pk_script": []byte
}

pk_script 是字节数组,它对应着脚本字节数据。比特币拥有很多不同的脚步(script)结构:

P2PKH, P2SH, P2WSH, P2WPKH …

下面拿 P2PKH 做例子。结合下面源码截图可知其字节数组结构是:

OP_DUP OP_HASH160 pubKeyHash OP_EQUALVERIFY OP_CHECKSIG

image.png

OP_DUP OP_HASH160 这些是什么?这些是比特币虚拟机的操作码,OP是英文operation的缩写,操作码的本质是16进制数字。想详细了解它们,可以购买本人的第二本书籍,内含详细技术分析,包含虚拟机。

上面的 P2PKH 结构,虚拟机在运行它的时候,代码执行流程如下:

  1. OP_DUP: 执行复制栈顶数据操作,然后该数据放置栈顶;
  2. OP_HASH160: 执行对栈顶数据进行 ripemd160 哈希运算操作。160 前,会先进行一次 sha256(data);
  3. OP_EQUALVERIFY: 执行对比栈顶的两个数据操作,如果相等都被移除;
  4. OP_CHECKSIG: 执行验证签名操作,这里会用到 pubKeyHash

记住这个 pubKeyHash,它是后面验签要用到的,它是公钥哈希。

验签

上面内容把验签需要的数据都准备好了,验签名步骤如下:

  1. 节点接收到交易后,从新交易的数据中获取到 input 结构中的 signature_script(scriptSign), tx_hash, index 参数;
  2. 使用 1 中的 tx_hash,index 找到这笔 input 所对应的 output (UTXO模型),设为 A ;
  3. 从 A 中得到 pk_script 脚本指令,以及它里面的 pubKeyHash
  4. 从 signature_script 按照字节范围得到 pkData,即 pubKey(公钥);
  5. 从 pubKey 中推出 pubKeyHash_1,比较 pubKeyHash_1 == pubKeyHash
  6. 结束验签。

课后解答

  1. 为什么 P2PKH 脚步中不直接存放 pubKey 而放 pubKeyHash?

答:为了隐藏收款人的公钥。

  1. 为什么以太坊的验签方式和比特币的差异这么大?

答:账户模型的不同,导致了这样的结果。