比特币地址的生成与格式解析
我们先带着如下问题开始我们的编程工作:
私钥、公钥和地址有什么关系?
什么是WIF?
Base58 和 Bech32 是什么?为什么有不同的编码方式?
不同格式的地址有什么区别?它们的长度为什么不一样?
想要产生私钥、公钥和地址,其实很简单,一句代码就可以,我们先动手运行如下代码:
使用python的bitcoinlib库编程
from bitcoinlib.keys import Key
# 生成比特币钱包
key = Key()
# 生成私钥
private_key_hex = key.private_hex # 32 字节(256-bit)
private_key_wif = key.wif() # Base58Check 编码
# 生成公钥
public_key_compressed = key.public_hex # 33 字节,压缩格式
public_key_uncompressed = key.public_uncompressed_hex # 65 字节,未压缩格式
# 生成不同格式的比特币地址
legacy_address = key.address() # P2PKH (Base58, 1...)
segwit_native_address = key.address(encoding='bech32') # P2WPKH (Bech32, bc1q...)
segwit_p2sh_address = key.address(encoding='base58', script_type='p2sh') # P2SH-P2WPKH (3...)
taproot_address = key.address(script_type='p2tr') # P2TR (Bech32m, bc1p...)
# 打印结果
print("===== 比特币钱包信息 =====")
print(f"私钥(HEX): {private_key_hex}")
print(f"私钥(WIF): {private_key_wif}")
print(f"公钥(压缩): {public_key_compressed}")
print(f"公钥(未压缩): {public_key_uncompressed}")
print("\n地址类型:")
print(f"Legacy (P2PKH, Base58): {legacy_address}")
print(f"Segwit Native (P2WPKH, Bech32): {segwit_native_address}")
print(f"Segwit P2SH (P2SH-P2WPKH, Base58): {segwit_p2sh_address}")
print(f"Taproot (P2TR, Bech32m): {taproot_address}"
我这次的运行结果如下:
===== 比特币钱包信息 =====
私钥(HEX): e9873d79c6d87dc0fb6a5778633389dfa5c32fa27f99b5199abf2f9848ee0289
私钥(WIF): L1aW4aubDFB7yfras2S1mN3bqg9w3KmCPSM3Qh4rQG9E1e84n5Bd
公钥(压缩): 0250be5fc44ec580c387bf45df275aaa8b27e2d7716af31f10eeed357d126bb4d3
公钥(未压缩): 0450be5fc44ec580c387bf45df275aaa8b27e2d7716af31f10eeed357d126bb4d3...
地址类型:
Legacy (P2PKH, Base58): 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
Segwit Native (P2WPKH, Bech32): bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kygt080
Segwit P2SH (P2SH-P2WPKH, Base58): 3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy
Taproot (P2TR, Bech32m): bc1plz0h3rlj2zvn88pgywqtr9k3df3p75p3ltuxh0
大家一定要动手运行一下。
看到这里,我们来解释下之前的疑问:
1、比特币的私钥、公钥和地址的关系是什么?
可以简单理解如下:
私钥:随机生成的 256 位(32 字节)数据,用于签名交易。比如e9873d79c6d87dc0fb6a5778633389dfa5c32fa27f99b5199abf2f9848ee0289。
数一数:e9873d79c6d87dc0fb6a5778633389dfa5c32fa27f99b5199abf2f9848ee0289有多少字符?
没错64个字符,也就是64个HEX(16进制)字符。请记住:每4位(四个bit)就可以压缩为一个HEX字符;每两个HEX就可以压缩为一个字节(Bite)。私钥就是256位,或64个HEX字符,或者32字节。不同的进制,也就是一个占位符能包含的信息量。
什么是WIF?
比特币私钥一般不会直接用 64 HEX 形式,而是用 WIF(Base58Check 编码) 进行格式化,方便存储和导入钱包,虽然我个人也没有觉得方便了多少。
WIF 格式转换过程, 看不懂可以直接忽略:
1.添加版本前缀
•主网(Mainnet): 0x80
•测试网(Testnet): 0xEF
例如:
80e9873d79c6d87dc0fb6a5778633389dfa5c32fa27f99b5199abf2f9848ee0289
2.计算两次 SHA-256
•SHA256(SHA256(80e9...0289))
•取前 4 字节 作为校验和
结果是一个 51 或 52 个字符的字符串,比如
L1aW4aubDFB7yfras2S1mN3bqg9w3KmCPSM3Qh4rQG9E1e84n5Bd
•L 开头的 WIF 表示主网压缩私钥
•K 开头的 WIF 表示主网未压缩私钥
•c 开头的 WIF 表示测试网私钥
总结,WIF 只是比特币私钥的 Base58Check 编码,方便存储和导入钱包。
公钥:通过椭圆曲线加密(secp256k1)从私钥推导出。公钥有压缩和压缩之分,但我们碰到的基本都是压缩公钥,33个字节,比如0250be5fc44ec580c387bf45df275aaa8b27e2d7716af31f10eeed357d126bb4d3(算一下多少个字符?)
地址:公钥经过哈希处理(SHA-256 + RIPEMD-160)并进行不同格式编码,生成可用于交易的地址。
SHA-256(Secure Hash Algorithm 256-bit)是一种广泛应用的加密哈希函数,会将公钥转换为 256 位(32 字节)的哈希值。
RIPEMD-160(RACE Integrity Primitives Evaluation Message Digest 160-bit)是一种更短的哈希算法,它会进一步压缩 SHA-256 的输出,生成 160 位(20 字节)的哈希值,作为公钥哈希(PubKeyHash,记住这个单词)。
如何进行编码,请见后面我们介绍base58和bech32。
3、进制与编码:Base58 和 Bech32
比特币的编码格式主要有 Base58Check 和 Bech32:
Base58Check:用于 P2PKH 和 P2SH 地址,避免混淆字符(0、O、I、l),提高可读性。
Bech32:用于 SegWit 地址(P2WPKH 和 P2TR),更高效,带错误校验机制。
4、比特币地址类型介绍
P2PKH(Pay-to-PubKey Hash)
经典的比特币地址格式。
基于公钥哈希(RIPEMD-160 + SHA-256)。
使用 Base58Check 编码,地址以
1
开头。示例地址:
1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa
比特币地址格式,P2PKH(Pay-to-Public-Key-Hash),字面意思是把钱支付到公钥对应的哈希,但其实更精确的概念不仅仅是直接支付给公钥哈希本身,而是支付给一个包含公钥哈希的锁定脚本(scriptPubKey,记住这个单词)。这在以后我们讲UTXO模型的时候很详细的讲。
P2SH(Pay-to-Script Hash)
用于多重签名地址和嵌套的 SegWit 地址。Pay-to-Script Hash 顾名思义,把钱打到一个脚本哈希。这个脚本script,常常说的是一个多签(Multisig)的脚本。
使用 Base58Check 编码,地址以
3
开头。示例地址:
3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy
P2WPKH(Pay-to-Witness PubKey Hash)
隔离见证(SegWit)地址格式。SegWit和Taproot是我们本书要详细介绍的技术。
使用 Bech32 编码,地址以
bc1q
开头。比 P2PKH 交易效率更高,手续费更低。
示例地址:
bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kygt080
P2TR(Pay-to-Taproot)
采用 Taproot 技术,进一步提升隐私性和效率。
使用 Bech32m 编码,地址以
bc1p
开头。适用于复杂的智能合约和多签方案。
示例地址:
bc1plz0h3rlj2zvn88pgywqtr9k3df3p75p3ltuxh0
地址格式和字节数
地址类型
编码格式
原始数据大小
最终地址长度
前缀
P2PKH
Base58Check
25 字节
34 字符左右
1...
P2SH
Base58Check
25 字节
34 字符左右
3...
P2WPKH
Bech32
21 字节
42~46 字符
bc1q...
P2TR
Bech32m
33 字节
58~62 字符
bc1p...
总结
私钥(HEX 32字节) → WIF(Base58Check 编码) 方便存储。
公钥(33/65字节) → 比特币地址(Base58 / Bech32 编码) 用于收款。
SegWit(Bech32)和Taproot(Bech32m) 具有更好的安全性和效率,逐步替代 Base58 地址。
Last updated