比特幣技術 — 交易的驗簽原理

作者:林冠宏 / 指尖下的幽靈。轉載者,請: 務必標明出處。

博客://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. 為什麼以太坊的驗簽方式和比特幣的差異這麼大?

答:賬戶模型的不同,導致了這樣的結果。