天天看點

[學習筆記] 比特币的位址P2PKH 位址P2SH 位址總結參考

https://aaron67.cc/2019/01/04/bitcoin-address/

Alice 向 Bob 支付比特币:

  • 使用 P2PK 交易,需要知道 Bob 的公鑰,鎖定腳本為

    [Bob的公鑰] OP_CHECKSIG

  • 使用 P2PKH 交易,需要知道 Bob 的公鑰或 Bob 的公鑰哈希,鎖定腳本為

    OP_DUP OP_HASH160 [Bob的公鑰哈希] OP_EQUALVERIFY OP_CHECKSIG

  • 使用 P2SH 交易,需要知道 Bob 的腳本哈希,鎖定腳本為

    OP_HASH160 [Bob的腳本哈希] OP_EQUAL

了解了交易的細節,你可能會疑惑,這與日常收發比特币時的情況好像不太一樣。

接收比特币時,通常會使用一串跟銀行卡号類似的“神奇代碼”,作為收款“位址”,形如

1BJhat1AMGYbT9HYJxVekoCaPaqB9ZyTyF

這篇文章介紹位址是怎麼計算的。

P2PKH 位址

一句話解釋,P2PKH 位址是 Base58Check 編碼的公鑰哈希。

我們用 App 支付比特币到某個位址,App 會先将位址反解成公鑰哈希,然後構造一筆 P2PKH 交易,完成支付。

因為 Base58Check 編碼是可逆的,是以可以這麼做。

用 https://www.bitaddress.org/ 生成一對私鑰和位址,整體演算一遍。

[學習筆記] 比特币的位址P2PKH 位址P2SH 位址總結參考

私鑰

L2M6qFzrdDEv7eRT7p94Zf4QShLdWjicFpkiCro12CrRbCDb8ke3

L

開頭,這是 WIF 壓縮格式的私鑰。

用這個工具,Base58Check 反解之後為(我加了空格)

80 98fd2a819a382f8e142e38242f6caf2a2f6f58e7fe6ca5f23c5b0818b15b4ba6 01 236803e8
           

私鑰為

98fd2a819a382f8e142e38242f6caf2a2f6f58e7fe6ca5f23c5b0818b15b4ba6

計算出對應的公鑰點為

x = da52d817a5ae3555f36a94528322eb47016f1334b798f5b4fa614a892dabb3ea
y = f314bf38816673c55c1708cf1e36b55c936db97618d6460c4d223be83bec7788
           

公鑰為

02da52d817a5ae3555f36a94528322eb47016f1334b798f5b4fa614a892dabb3ea

(P2PK 交易需要這個值)。

用這個工具,計算公鑰 HASH160 後的結果,得到公鑰哈希(P2PKH 交易需要這個值)為

710a35053db4296dc5f3476d10ae93924bc55c9a
           

對公鑰哈希做 Base58Check 編碼,按規定添加

0x00

版本字首。

類型 版本字首的值(十六進制) Base58Check之後的字首
P2PKH位址 00 1
P2SH位址 05 3

得到位址

1BJhat1AMGYbT9HYJxVekoCaPaqB9ZyTyF
           

編碼過程如下。

# payload
710a35053db4296dc5f3476d10ae93924bc55c9a

# S1 = version + payload
00 710a35053db4296dc5f3476d10ae93924bc55c9a

# S2 = SHA256(SHA256(S1))
5f91f9a69fc02d537c93e41b127b2f5081fd25f82683c1eebe3c54aae1f83130

# S2的前4位元組是Checksum
5f91f9a6

# S3 = S1 + Checksum
00 710a35053db4296dc5f3476d10ae93924bc55c9a 5f91f9a6

# 位址 = Base58(S3)
1BJhat1AMGYbT9HYJxVekoCaPaqB9ZyTyF
           

需要注意的是,從 P2PKH 位址隻能反解出公鑰哈希的值,而無法知道公鑰本身,因為哈希是不可逆的,無法從公鑰哈希計算公鑰。

由于在 Base58Check 編碼時加入了特定字首

0x00

,是以這類位址都以

1

開頭,友善識别。

位址中包含了校驗和,能有效防止轉錄過程中的錯誤,這也是為什麼不直接使用公鑰哈希的原因。

當你在 App 裡發送比特币到某個

1

開頭的位址時,App 知道這是一個 P2PKH 位址,先校驗位址是不是合法,再反解出編碼前的公鑰哈希,建立 P2PKH 交易,完成支付。

普通使用者可以直接使用位址來收發比特币,而不用了解幕後細節,因為它們被位址隐藏了。

P2SH 位址

同樣的,對于 P2SH 交易中用到的腳本哈希,也可以這麼幹。

但編碼時,會使用

0x05

的版本字首,是以 P2SH 位址都以

3

開頭,形如

347N1Thc213QqfYCz3PZkjoJpNv5b14kBd

[學習筆記] 比特币的位址P2PKH 位址P2SH 位址總結參考

交易

40eee3ae1760e3a8532263678cdf64569e6ad06abc133af64f735e52562bccc8

{
   "txid":"40eee3ae1760e3a8532263678cdf64569e6ad06abc133af64f735e52562bccc8",
   "hash":"40eee3ae1760e3a8532263678cdf64569e6ad06abc133af64f735e52562bccc8",
   "version":1,
   "size":189,
   "vsize":189,
   "weight":756,
   "locktime":0,
   "vin":[
      {
         "txid":"42a3fdd7d7baea12221f259f38549930b47cec288b55e4a8facc3c899f4775da",
         "vout":0,
         "scriptSig":{
            "asm":"3044022048d1468895910edafe53d4ec4209192cc3a8f0f21e7b9811f83b5e419bfb57e002203fef249b56682dbbb1528d4338969abb14583858488a3a766f609185efe68bca[ALL] 031a455dab5e1f614e574a2f4f12f22990717e93899695fb0d81e4ac2dcfd25d00",
            "hex":"473044022048d1468895910edafe53d4ec4209192cc3a8f0f21e7b9811f83b5e419bfb57e002203fef249b56682dbbb1528d4338969abb14583858488a3a766f609185efe68bca0121031a455dab5e1f614e574a2f4f12f22990717e93899695fb0d81e4ac2dcfd25d00"
         },
         "sequence":4294967295
      }
   ],
   "vout":[
      {
         "value":0.0099,
         "n":0,
         "scriptPubKey":{
            "asm":"OP_HASH160 e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a OP_EQUAL",
            "hex":"a914e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a87",
            "reqSigs":1,
            "type":"scripthash",
            "addresses":[
               "3P14159f73E4gFr7JterCCQh9QjiTjiZrG"
            ]
         }
      }
   ]
}
           

輸出支付到了腳本哈希

e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a

,讓我們計算一下對應的位址。

# payload
e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a

# S1 = version + payload
05 e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a

# S2 = SHA256(SHA256(S1))
# http://bit.ly/2RoiDBu
7f297f3156a14d114af23b33c339817a1241afcb52a154d19683c67c538b7278

# S2的前4位元組是Checksum
7f297f31

# S3 = S1 + Checksum
05 e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a 7f297f31

# 位址 = Base58(S3)
# https://incoherency.co.uk/base58/
3P14159f73E4gFr7JterCCQh9QjiTjiZrG
           

同樣的,從 P2SH 位址隻能反解出腳本哈希的值,而無法知道贖回腳本的具體内容。

當你在 App 裡發送比特币到某個

3

開頭的位址時,App 知道這是一個 P2SH 位址,先校驗位址是不是合法,再反解出編碼前的腳本哈希,建立 P2SH 交易,完成支付。

總結

位址是公鑰哈希或腳本哈希的 Base58Check 編碼,這個編碼是可逆的。

P2PKH 位址都以

1

開頭,P2SH 位址都以

3

開頭。

結合之前的文章,你知道:

  • 在比特币系統裡其實沒有“位址”的概念,交易輸出會被鎖定腳本鎖定,與公鑰哈希或腳本哈希關聯
  • 位址是公鑰哈希或腳本哈希的可逆編碼,定義“位址”是為了友善使用者使用,封裝幕後細節,簡化操作
  • 從私鑰可以計算公鑰,從公鑰可以計算位址,但反過來都不成立
  • 私鑰十分重要,擁有私鑰就擁有了其對應公鑰上鎖定的比特币
[學習筆記] 比特币的位址P2PKH 位址P2SH 位址總結參考

參考

  • 精通比特币(第二版)譯文 原文

繼續閱讀