比特幣鎖定腳本及地址解析

概述

    當你閱讀本文時,我假定你是一個比特幣的開發者,並且對比特幣的代碼細節有一定的興趣。尤其是你在處理比特幣的地址轉換(我們看到的和代碼用到的地址格式)時有一些疑惑的時候,也許本文能夠幫助到你。

鎖定腳本類型

比特幣地址對應的鎖定腳本(ScriptPubKey)主要類型:P2PKH P2SH P2WSH P2WPKH P2SH-P2WSH P2SH-P2WPKH,不同的鎖定腳本類型是由不同的地址生成的。

鎖定腳本對應的地址類型

  1. 公鑰生成地址過程:私鑰->公鑰->地址。公鑰分爲壓縮和非壓縮格式。

私鑰、公鑰、地址關係

公鑰生成私鑰過程

 

  1. 不同的鎖定腳本依賴的源數據生成。對應關係如下

腳本類型

源類型

地址長度

P2PKH

公鑰

20

P2SH

腳本

20

P2WPKH

公鑰

20

P2WSH

腳本

32

P2SH-P2WSH

公鑰

20

P2SH-P2WPKH

腳本

20

  1. 地址的表現形式

實際上我們看到的地址是經過Bash58編碼或bech32編碼的地址,地址中添加了地址類型和校驗碼所以不同的地址開頭會呈現不同的數值。生成鎖定腳本的時候要解碼數據並且去掉地址類型碼。

不同地址的標誌位對照表如下:

地址類型

網絡類型

對應的地址標誌位

編碼類型

說明

P2PKH地址

main

0x00

Base58

支付到比特幣地址的交易包含支付公鑰哈希腳本(P2PKH)。由P2PKH 腳本鎖定

的交易輸出可以通過給出由相應私鑰創建的公鑰和數字簽名來解鎖(消費)

testnet

0x6F

Base58

regtest

0x6F

Base58

P2SH地址

main

0x05

Base58

P2SH 地址是基於Base58 編碼的一個含有20 個字節哈希的腳本。P2SH 地址採用

“5”前綴。這導致基於Base58 編碼的地址以“3”開頭。P2SH 地址隱藏了所有的復

雜性,因此,運用其進行支付的人將不會看到腳本。

testnet

0xC4

Base58

regtest

0xC4

Base58

P2WPKH地址

main

"bc"

Bech32

P2WPKH地址是腳本做HASH160得到20位的地址經過Bech32編碼後顯示

testnet

"tb"

Bech32

regtest

"bcrt"

Bech32

P2WSH地址

main

"bc"

Bech32

P2WSH地址是腳本做HASH256得到到32位的地址經過Bech32編碼後顯示

testnet

"tb"

Bech32

regtest

"bcrt"

Bech32

P2SH-P2WPKH地址

main

0x05

Base58

P2SH-P2WPK地址是爲了滿足舊錢包的需求,將P2WPKH對應的鎖定腳本轉換到普通的P2SH地址格式。

testnet

0xC4

Base58

regtest

0xC4

Base58

P2SH-P2WSH地址

main

0x05

Base58

P2SH-P2SH地址是爲了滿足舊錢包的需求,將P2WPKH對應的鎖定腳本轉換到普通的P2SH地址格式。

testnet

0xC4

Base58

regtest

0xC4

Base58

 

 

鎖定腳本的結構

P2PKH:

是利用公鑰的哈希,相對來說比較簡單,現在新版本的錢包應用的越來越少。

OP_DUP OP_HASH160 OPCODE_LEN ADDR OP_EQUALVERIFY OP_CHECKSIG

對應的字節表示 0x76 0xa9 0x14 20字節地址 0x88 0xac

P2PKH長度:25字節

OPCODE_LEN:0x14 即 地址ADDR的長度

ADDR:是由公鑰生成的20字節

P2SH:

利用了腳本的哈希,並且鎖定腳本相較於P2PKH更加簡潔。由於腳本更加複雜,可以根據需要設計不同的邏輯控制,因此應用會被廣泛應用。鎖定腳本中表示簡單,但是贖回腳本和簽名處變的複雜了。

OP_HASH160 OPCODE_LEN ADDR OP_EQUAL

對應的字節表示: 0xa9 0x14 20字節地址 0x87

P2SH長度:23

OPCODE_LEN:0x14 即 地址ADDR的長度

ADDR:是由腳本經過HASH160生成的20字節

P2WPKH:

是隔離見證中公鑰地址的表示,格式主要是爲了與非隔離見證的鎖定腳本區別。舊錢包是不支持的。

VER OPCODE_LEN ADDR

對應的字節表示 0x00 0x14 20字節地址

P2WPKH長度:22

0x00: 版本號,固定0

OPCODE_LEN:0x14 即 地址ADDR的長度

ADDR:是由公鑰生成的20字節

P2WSH:

是隔離見證中腳本地址的表示,格式主要是爲了與非隔離見證的鎖定腳本區別。舊錢包是不支持的。因爲可以用到複雜腳本,因此可以做複雜邏輯應用。

VER OPCODE_LEN ADDR

對應的字節表示 0x00 0x20 32字節地址

P2WSH長度:34

0x00: 版本號,固定0

OPCODE_LEN:0x20 即 地址ADDR的長度

P2SH-P2WPKH:

P2SH-P2WPKH是對P2WPKH進行HASH160得到20字節地址,此地址可在P2SH中應用,與普通的P2SH地址沒有任何區別。格式見P2SH

P2SH-P2WSH

P2SH-P2WSH是對P2WSH進行HASH160得到20字節地址,此地址可在P2SH中應用,與普通的P2SH地址沒有任何區別。格式見P2SH

比特幣地址類型:

比特幣地址類型分爲3中格式: legacy p2sh-segwit bech32

legacy類型實際上就是取公鑰或腳本的HASH160值得到20位字節地址。

p2sh-segwit:對應生成P2SH-P2WPKH 和 P2SH-P2WSH中的地址

bech32:對應生成P2WPKH 和 P2WSH中的地址

 

隔離見證中的公鑰類型

隔離見證中生成地址用到的公鑰必須是壓縮的公鑰,否則可能會無法贖回此地址的幣。

隔離見證地址用長度32或20來判定地址是由腳本或公鑰生成的,0(版本)開頭表示是隔離見證地址。

 

腳本中的地址和錢包中的地址區別

    我們在UI上看到的地址是帶有地址類型碼並且經過Bash58或Bech32編碼後的地址的字符串,因此與實際地址長度並不符合。當我們傳入此地址後,會解碼並去除類型碼,並根據類型碼生成不同的ScriptPubkey(P2PKH P2SH P2WSH P2WPKH P2SH-P2WSH P2SH-P2WPKH)。

各種地址樣子如下:

P2PKH地址:

      顯示的地址:mgjswfb6eXcmuJgLxvMxAo1tth2QCyyPYt

實際地址16進製表示:0x0d 0x69 0xe6 0x9c 0x75 0x72 0x53 0x4c 0xa3 0x5d 0xdd 0x12 0x64 0x6f 0x90 0x8b 0xf0 0x7b 0xf7 0xb6

 

P2SH地址:

顯示的地址:2Mz5nE8zyxQDMZawYZ6cqbHZZdkih5CwQjU

實際地址16進製表示:0x4a 0xff 0xa1 0xed 0x45 0x54 0x17 0x5a 0x00 0xd6 0x54 0x78 0x8d 0x34 0xf3 0x13 0xd7 0x38 0x02 0xdd

 

P2WSH地址:

      顯示的地址:bcrt1qja4c5mpjw8hjlatgwud56naunfykxwupk65yev

      實際地址16進製表示:0x14 0x97 0x6b 0x8a 0x6c 0x32 0x71 0xef 0x2f 0xf5 0x68 0x77 0x1b 0x4d 0x4f 0xbc 0x9a 0x49 0x63 0x3b 0x81

 

P2WPKH地址:

      顯示的地址:bcrt1q09zjqeetautmyzrxn9d2pu5c5glv6zcmj3qx5axrltslu90p88pqykxdv4

      實際地址16進製表示:0x20 0x79 0x45 0x20 0x67 0x2b 0xef 0x17 0xb2 0x08 0x66 0x99 0x5a 0xa0 0xf2 0x98 0xa2 0x3e 0xcd 0x0b 0x1b 0x94 0x40 0x6a 0x74 0xc3 0xfa 0xe1 0xfe 0x15 0xe1 0x39 0xc2

總結:

      P2PKH、P2SH:是現在所有錢包都支持的格式,應用最廣。

      P2WPKH、P2WSH是隔離見證的標準格式,判定簡單,相對比較新,很多舊錢包沒有支持,但隨着隔離見證技術的應用(隔離見證優點及特性請查看相關資料,目前很火的閃電網絡就應用了隔離見證技術),會有更多的錢包支持。

      P2SH-P2WPKH、P2SH-P2WSH是爲了支持舊錢包對P2WPKH、 P2WSH做的升值,應用此格式,舊錢包可以創建給隔離見證地址的交易, 對於P2SH-P2WPKH、P2SH-P2WSH作爲輸入的簽名過程會更復雜一些。

 

由於能力有限,文中有錯誤的地方請指正,我將及時更正。

參考:

《精通比特幣》第二版

 bitcoin代碼

 libwally-core代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章