1 比特幣地址的生成過程
第一步
生成32個字節(jié)睛约,且最大不超過FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141的隨機(jī)數(shù)硝逢。
一共256位晕讲。
python腳本生成私鑰secrets.randbits(256)
在比特幣源碼中GetStrongRandBytes方法來生成
隨機(jī)數(shù)有幾個來源组橄,首先通過OpenSSL RNG拿到一個隨機(jī)數(shù)衣吠,第二個來源是操作系統(tǒng)本身的隨機(jī)數(shù)帆赢,如果硬件允許的話還可以加上硬件底層編程獲取的隨機(jī)數(shù)作為第三個來源
第二步
- 采用橢圓曲線數(shù)字簽名算法ECDSA-secp256k1將私鑰(32字節(jié))映射成公鑰(65字節(jié))(前綴04+Y公鑰+X公鑰)
橢圓曲線上面的坐標(biāo)系一個點(diǎn)是32字節(jié) 所以公鑰是65字節(jié)小压。加上前面的04版本號。
比特幣核心便是用secp256k1_ec_pubkey_create()函數(shù)來根據(jù)之前生成的私鑰產(chǎn)生對應(yīng)的公鑰
使用openssl庫來計(jì)算公鑰
int ret = secp256k1_ec_pubkey_create(secp256k1_context, (unsigned char*)result.begin(), &clen, begin(), fCompressed);
這個橢圓曲線的方程為
y2 = x3+ax+b a=0 b =7
第三步
(1)
對公鑰進(jìn)行兩次哈希運(yùn)算椰于,第一次通過 SHA-256 算法結(jié)果后怠益,對結(jié)果再進(jìn)行一次 RIPEMD-160 運(yùn)算 得到20字節(jié)的加密公鑰
(2)
對加密版公鑰添加一個字節(jié)網(wǎng)絡(luò)標(biāo)識。比特幣一共有兩個網(wǎng)絡(luò):主網(wǎng)和測試網(wǎng)瘾婿。如果我們需要生成一個主網(wǎng)地址蜻牢,就要在加密版公鑰開頭添加 0x00
(3)
將第二步的結(jié)果做兩個SHA256運(yùn)算。得到的結(jié)果去后面的四個字節(jié)偏陪。加到第二步的后面抢呆。到現(xiàn)在為止一共有1+20+4個字節(jié)了
第四步
將第三步的結(jié)果使用base58轉(zhuǎn)換成可讀性的地址形式,之所以不用base64是丟棄調(diào)幾個容易混淆的詞0 和O i I 等
以上都是調(diào)用https://github.com/bitcoin-core/secp256k1
庫的函數(shù)實(shí)現(xiàn)
2 以太坊地址生成過程
第一步 生成私鑰
key, err := newKey(rand)
privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand)
第二步生成公鑰
1.和之前的比特幣一樣笛谦,通過橢圓曲線抱虐。只是前面加了個版本號04.一共65字節(jié)
- 把公鑰去掉04,剩下的進(jìn)行keccak-256的哈希饥脑,得到長度64字節(jié)的16進(jìn)制字串恳邀,丟掉前面24個懦冰,拿后40個,再加上"0x"轩娶,即為以太坊地址
- 取上一步結(jié)果取后20bytes即以太坊地址
以太坊還有個合約地址
以太坊合約的地址是根據(jù)創(chuàng)建者(sender)的地址以及創(chuàng)建者發(fā)送過的交易數(shù)量(nonce)來計(jì)算確定的儿奶。 sender
和nonce
進(jìn)行RLP編碼,然后用Keccak-256
進(jìn)行hash計(jì)算鳄抒。