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/ 生成一对私钥和地址,整体演算一遍。
私钥L2M6qFzrdDEv7eRT7p94Zf4QShLdWjicFpkiCro12CrRbCDb8ke3
以L
开头,这是 WIF 压缩格式的私钥。
用这个工具,Base58Check 反解之后为(我加了空格)
80 98fd2a819a382f8e142e38242f6caf2a2f6f58e7fe6ca5f23c5b0818b15b4ba6 01 236803e8 |
私钥为98fd2a819a382f8e142e38242f6caf2a2f6f58e7fe6ca5f23c5b0818b15b4ba6
。
计算出对应的公钥点为
x = da52d817a5ae3555f36a94528322eb47016f1334b798f5b4fa614a892dabb3ea |
公钥为02da52d817a5ae3555f36a94528322eb47016f1334b798f5b4fa614a892dabb3ea
(P2PK 交易需要这个值)。
用这个工具,计算公钥 HASH160 后的结果,得到公钥哈希(P2PKH 交易需要这个值)为
710a35053db4296dc5f3476d10ae93924bc55c9a |
对公钥哈希做 Base58Check 编码,按规定添加0x00
版本前缀。
类型 | 版本前缀的值(十六进制) | Base58Check之后的前缀 |
---|---|---|
P2PKH地址 | 00 | 1 |
P2SH地址 | 05 | 3 |
得到地址
1BJhat1AMGYbT9HYJxVekoCaPaqB9ZyTyF |
编码过程如下。
# payload |
需要注意的是,从 P2PKH 地址只能反解出公钥哈希的值,而无法知道公钥本身,因为哈希是不可逆的,无法从公钥哈希计算公钥。
由于在 Base58Check 编码时加入了特定前缀0x00
,所以这类地址都以1
开头,方便识别。
地址中包含了校验和,能有效防止转录过程中的错误,这也是为什么不直接使用公钥哈希的原因。
当你在 App 里发送比特币到某个1
开头的地址时,App 知道这是一个 P2PKH 地址,先校验地址是不是合法,再反解出编码前的公钥哈希,创建 P2PKH 交易,完成支付。
普通用户可以直接使用地址来收发比特币,而不用了解幕后细节,因为它们被地址隐藏了。
P2SH 地址
同样的,对于 P2SH 交易中用到的脚本哈希,也可以这么干。
但编码时,会使用0x05
的版本前缀,所以 P2SH 地址都以3
开头,形如347N1Thc213QqfYCz3PZkjoJpNv5b14kBd
。
交易40eee3ae1760e3a8532263678cdf64569e6ad06abc133af64f735e52562bccc8
,
{ |
输出支付到了脚本哈希e9c3dd0c07aac76179ebc76a6c78d4d67c6c160a
,让我们计算一下对应的地址。
# payload |
同样的,从 P2SH 地址只能反解出脚本哈希的值,而无法知道赎回脚本的具体内容。
当你在 App 里发送比特币到某个3
开头的地址时,App 知道这是一个 P2SH 地址,先校验地址是不是合法,再反解出编码前的脚本哈希,创建 P2SH 交易,完成支付。
总结
地址是公钥哈希或脚本哈希的 Base58Check 编码,这个编码是可逆的。
P2PKH 地址都以1
开头,P2SH 地址都以3
开头。
结合之前的文章,你知道:
- 在比特币系统里其实没有“地址”的概念,交易输出会被锁定脚本锁定,与公钥哈希或脚本哈希关联
- 地址是公钥哈希或脚本哈希的可逆编码,定义“地址”是为了方便用户使用,封装幕后细节,简化操作
- 从私钥可以计算公钥,从公钥可以计算地址,但反过来都不成立
- 私钥十分重要,拥有私钥就拥有了其对应公钥上锁定的比特币