比特币和以太坊的生成地址的流程都是是:私钥 -> 公钥 -> 地址。因此地址的生成需要三步:
1.生成一个随机的私钥(32字节)
2.通过私钥生成公钥(64字节)
3.通过公钥得到地址(20字节)
其中私钥key为32字节随机数,公钥pubKey为通过secp256k1椭圆曲线计算得到的(pubKey=[key]·G)。
以太坊和比特币的区分仅仅是由公钥推导得到地址这一步不同。
比特币
比特币地址分为压缩型公钥地址和非压缩型公钥地址。区别仅在于公钥是否进行了简单压缩
非压缩型
第一步:私钥 (private key)产生
伪随机数产生的256bit私钥示例:
8F72F6B29E6E225A36B68DFE333C7CE5E55D83249D3D2CD6332671FA445C4DD3
第二步:公钥 (public key)
1. 拿私钥产生256bit私钥经secp256k1椭圆曲线推出的公钥(前缀04+X公钥+Y公钥):
04
06CCAE7536386DA2C5ADD428B099C7658814CA837F94FADE365D0EC6B1519385
FF83EC5F2C0C8F016A32134589F7B9E97ACBFEFD2EF12A91FA622B38A1449EEB
2. 计算公钥的 SHA-256 哈希值(32bytes):
2572e5f4a8e77ddf5bb35b9e61c61f66455a4a24bcfd6cb190a8e8ff48fc097d
3. 取上一步结果,计算 RIPEMD-160 哈希值(20bytes):
0b14f003d63ab31aef5fedde2b504699547dd1f6
4. 取上一步结果,前面加入地址版本号(比特币主网版本号“0x00”):
000b14f003d63ab31aef5fedde2b504699547dd1f6
5. 取上一步结果,计算两次 SHA-256 哈希值(32bytes)
---1--- ddc2270f93cc84cc6869dd373f3c340bbf5cb9a8f5559297cc9e5d947aab2536
---2--- 869ac57b83ccf75ca9da8895823562fffb611e3c297d9c2d4612aeeb32850078
6. 取上一步结果的前4个字节(8位十六进制)
869ac57b
7. hash of public key,把这4个字节加在第4步的结果后面,作为校验(这就是比特币地址的16进制形态)
000b14f003d63ab31aef5fedde2b504699547dd1f6869ac57b
第三步:地址 (address)
最终给用户使用的:用base58编码变换一下地址(这就是最常见的比特币地址形态)
121bWssvSgsA9SKjR4DbYncEAoJjmBFwog
大部分比特币地址由公钥通过 base58Check 编码而来,把公钥地址从 512-Bit 哈希到 160-Bit ,但并不是所有的比特币地址都是公钥推导出来,也有可能是通过脚本建立在比特币网络中的虚拟币(比如彩色币)的脚本标识。
压缩型
对于压缩公钥生成地址时,则只取非压缩公钥的X部分即可。和非压缩型公钥地址的区别,仅在于上面公钥部分的第1步。
从上面的输出示例中可以看到 public key 一共有 130 个 16 进制的字符,共 520 个字节,其中的前缀为 04,这里的 04 表示该公钥为 非压缩格式,即完整存储了 x 和 y 坐标(各 256 个 bits),但是从 secp256k1 的椭圆曲线方式可以看到,只要知道其中一个坐标值,另外一个坐标值都是可以通过解方程得出的,因为可以只存储其中一个坐标,这样就可以节约 256 个 bits,从而引入了 压缩格式 的公钥。
上面的 04 前缀表示 非压缩格式,如果为压缩格式,则前缀为 02 或 03,有两个前缀主要是因为方程(y² = x³ + ax + b)的左侧的 y 为平方根,可能为正或者为负。同一个私钥对应的两种不同公钥示例如下:
# 私钥生成公钥示例(非压缩公钥)
private key: de97fdbdb823a197603e1f2cb8b1bded3824147e88ebd47367ba82d4b5600d73 public key: 047c91259636a5a16538e0603636f06c532dd6f2bb42f8dd33fa0cdb39546cf449612f3eaf15db9443b7e0668ef22187de9059633eb23112643a38771c630db911
# 私钥生成公钥示例(压缩公钥)
private key: de97fdbdb823a197603e1f2cb8b1bded3824147e88ebd47367ba82d4b5600d73 public key compressed: 037c91259636a5a16538e0603636f06c532dd6f2bb42f8dd33fa0cdb39546cf449
以太坊
和比特币相比,在私钥生成公钥这一步其实是一样的,区别在公钥推导地址第一部分,以太坊中非圧缩型公钥的处理就简单粗暴很多了,下图为由私钥生成地址的过程。
第一步:私钥 (private key)
伪随机数产生的256bit私钥示例(256bit 16进制32字节)
18e14a7b6a307f426a94f8114701e7c8e774e7f9a47e2c2035db29a206321725
第二步:公钥 (public key)
1. 采用椭圆曲线数字签名算法ECDSA-secp256k1将私钥(32字节)映射成公钥(65字节)(前缀04+X公钥+Y公钥):
04
50863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352
2cd470243453a299fa9e77237716103abc11a1df38855ed6f2ee187e9c582ba62. 拿公钥(非压缩公钥)来hash,计算公钥的 Keccak-256 哈希值(32bytes):
fc12ad814631ba689f7abe671016f75c54c607f082ae6b0881fac0abeda21781
3. 取上一步结果取后20bytes即以太坊地址:
1016f75c54c607f082ae6b0881fac0abeda21781
第三步:地址 (address)
0x1016f75c54c607f082ae6b0881fac0abeda21781
笔记参考: