0%

btcd源码解析——签名机制(2)——签名流程

在前一篇博客中,我们介绍了比特币签名机制的基础知识。本篇博客我们将从原理层介绍签名流程。下一篇博客btcd源码层面讲解签名流程。

III. 签名流程——原理层

正如我们在第II节中所述,比特币主要包含6种组合签名类型。对应于每一种签名类型,签名的流程也不同。 本节将针对两大类(无修饰类和有修饰类)进行分别介绍。对于每一大类,也将首先讲解各种签名类型下共有的一些签名流程,然后按小节分别讲解每一种签名类型种特有的流程。 本节主要从原理层面进行介绍,下一节将展示对应的源码实现。 此外,需要声明的是,本小节使用到的多幅图片都摘自电子书Bitcoin Developer Reference的III.E节。

A. 无修饰类

本小节首先介绍无修饰类中一些共有的签名流程。 如上篇博客中的II.B小节所述,无修饰类中的message是包含了所有input的。但这里的包含并不是简单直接的包含,而是对所有input进行处理后的包含。 我们以图1为例进行共有签名流程的介绍:

  1. 在后面的内容中,我们都是以第一个input (vin[0])为例进行介绍,其他input也是同理。
  2. 签名部分填充在vin[0]的的scriptSigLenscriptSig中,也即图中红色框中。
  3. 对于vin[0]而言,签名之前scriptSigLenscriptSig中是没有内容的。其借助于vout[0]中的scriptPubkey进行填充。具体而言,将vout[0]中的scriptPubkey去除OP_CODESEP操作码后,将其内容和长度分别填充到scriptSigscriptSigLen中。如图2中黄色框所示。
  4. 对于其他input(如vin[1])而言,scriptSigLenscriptSig分别填充为0值和空值,如图2中暗绿色框所示。
以上便是无修饰类的签名类型共有的签名流程。以下分小节分别介绍每种特定类型的签名流程。
图1
图2

1. SIGHASH_ALL类型

如前所述,SIGHASH_ALL类型中的message包含了全部的outputs和修改后的inputs。 如图2所示,其中TxNew的灰色部分即为message的内容。

2. SIGHASH_NONE类型

如前所述,SIGHASH_NONE类型中的message包含全部的input但不包含任何output。 如图3所示,output的数目被置为0,message中不包含任何output。此外,nSequence也被置为0值。
图3

3. SIGHASH_SINGLE类型

如前所述,SIGHASH_NONE类型中的message包含全部的input,且只包含对应当前inputoutput。 如图4所示,黄色框表示message中只包含vout[0]的内容。此外,nSequence也被置为0值,output的数目被置为当前inputindex+1(如红色框所示)。
图4

B. 有修饰类

本小节首先介绍有修饰类中一些共有的签名流程。如前所述,SIGHASH_ANYONECANPAY修饰后的message不包含其他input. 如图5所示:

  1. 对于vin[0]而言,scriptSigLenscriptSig也分别填充scriptPubkey去除OP_CODESEP操作码后的内容。
  2. 其他input (如vin[1]) 的内容不被包含
  3. input的数目被置为1,如图5中的红色框所示。
    图5

以下分小节分别介绍每种特定类型的签名流程。

1. SIGHASH_ALL | SIGHASH_ANYONECANPAY类型

图5中TxNew的灰色部分也表示了SIGHASH_ALL | SIGHASH_ANYONECANPAY类型的message内容。 对比III.A小节中的图1,两者除了input外,message中的其他内容完全一致。

2. SIGHASH_NONE | SIGHASH_ANYONECANPAY类型

该类型和III.B.1小节的区别主要在output部分,其message内容如图6的灰色部分所示。
图6

3. SIGHASH_SINGLE | SIGHASH_ANYONECANPAY类型

该类型和III.B.1.小节的区别也是在output部分,其message内容如图7的灰色部分所示。
图7

C. 示例

本篇博客的最后,强烈推荐读者阅读比特币中对交易进行签名的详细过程. 该博客以SIGHASH_ALL类型为例,非常详细清晰地介绍了交易的签名流程。 当然,也强烈推荐读者继续阅读下一篇博客btcd源码解析 —— 签名机制(3) —— 源码分析.