1 比特币地址的生成过程
第一步
生成32个字节,且最大不超过FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141的随机数。
一共256位。
python脚本生成私钥secrets.randbits(256)
在比特币源码中GetStrongRandBytes方法来生成

随机数有几个来源,首先通过OpenSSL RNG拿到一个随机数,第二个来源是操作系统本身的随机数,如果硬件允许的话还可以加上硬件底层编程获取的随机数作为第三个来源
第二步
- 采用椭圆曲线数字签名算法ECDSA-secp256k1将私钥(32字节)映射成公钥(65字节)(前缀04+Y公钥+X公钥)
椭圆曲线上面的坐标系一个点是32字节 所以公钥是65字节。加上前面的04版本号。
比特币核心便是用secp256k1_ec_pubkey_create()函数来根据之前生成的私钥产生对应的公钥
使用openssl库来计算公钥
int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed);
这个椭圆曲线的方程为
y2 = x3+ax+b a=0 b =7
第三步

(1)
对公钥进行两次哈希运算,第一次通过 SHA-256 算法结果后,对结果再进行一次 RIPEMD-160 运算 得到20字节的加密公钥
(2)
对加密版公钥添加一个字节网络标识。比特币一共有两个网络:主网和测试网。如果我们需要生成一个主网地址,就要在加密版公钥开头添加 0x00
(3)
将第二步的结果做两个SHA256运算。得到的结果去后面的四个字节。加到第二步的后面。到现在为止一共有1+20+4个字节了
第四步
将第三步的结果使用base58转换成可读性的地址形式,之所以不用base64是丢弃调几个容易混淆的词0 和O i I 等
以上都是调用https://github.com/bitcoin-core/secp256k1
库的函数实现
2 以太坊地址生成过程
第一步 生成私钥
key, err := newKey(rand)
privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand)
第二步生成公钥
1.和之前的比特币一样,通过椭圆曲线。只是前面加了个版本号04.一共65字节
- 把公钥去掉04,剩下的进行keccak-256的哈希,得到长度64字节的16进制字串,丢掉前面24个,拿后40个,再加上"0x",即为以太坊地址
- 取上一步结果取后20bytes即以太坊地址
以太坊还有个合约地址
以太坊合约的地址是根据创建者(sender)的地址以及创建者发送过的交易数量(nonce)来计算确定的。 sender和nonce 进行RLP编码,然后用Keccak-256 进行hash计算。