比特币锁定脚本及地址解析(p2pkh p2sh p2wpkh p2wsh格式)

概述

    当你阅读本文时,我假定你是一个比特币的开发者,并且对比特币的代码细节有一定的兴趣。尤其是你在处理比特币的地址转换(我们看到的和代码用到的地址格式)时有一些疑惑的时候,也许本文能够帮助到你。

锁定脚本类型

比特币地址对应的锁定脚本(ScriptPubKey)主要类型:P2PKH P2SH P2WSH P2WPKH P2SH-P2WSH P2SH-P2WPKH,不同的锁定脚本类型是由不同的地址生成的。

锁定脚本对应的地址类型

  1. 公钥生成地址过程:私钥->公钥->地址。公钥分为压缩和非压缩格式。

比特币锁定脚本及地址解析(p2pkh p2sh p2wpkh p2wsh格式)_第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代码

你可能感兴趣的:(技术文档)