转载请注明出处:www.huamo.online
字节杭州 求贤若渴:
new
一个账号
1 | $ geth account new --datadir "./datadir1" |
这样就创建了一个新的账号,地址为26add576232dad627a9102015a7b11763e98f85b
,密码为12345678
,keystore
文件存在了./datadir1/keystore
中
address为20个字节,即16进制表示为40位。
背后的故事
入口:accountCreate()
在cmd/geth/accountcmd.go
中找到了geth account new
命令的入口:
1 | // cmd/geth/accountcmd.go |
发现入口方法为accountCreate()
。该方法
首先读取命令行输入的参数以更新geth中的各种配置
然后确定下来几个重要的参数:
scryptN, scryptP, keydir
,前两个用于加密生成的密钥,最后一个用于存放keystore
文件。获取密码:要么读取
--password
指定的密码文件第一行;要么让用户从命令行提供。使用
keystore.StoreKey()
生成账户。
1 | // cmd/geth/accountcmd.go |
核心:storeNewKey()
进入keystore.StoreKey()
,发现主要是调用了storeNewKey()
方法生成密钥和地址,storeNewKey()
方法传入了一个crand.Reader
,一个跨平台的伪随机数产生器。
storeNewKey()
在顶层做了全部的工作,包括:
调用
newKey()
生成私钥和账户地址。newKey()
的实现包括:依赖于
crand.Reader
随机数产生器,使用ECDSA
生成私钥privKey
,该privKey
结构体包含了pubKey
和D
,其中D
非常重要,仅依靠D
就能还原出对应的公私钥。依赖生成的
pubKey
计算出一个[20]byte
,这就是以太坊的账户地址。
根据地址和前述的
datadir
参数,构建出以太坊的Account
对象。调用
StoreKey()
加密私钥,写入keystore
文件中。StoreKey()
的实现包括:基于
scryptN
,scryptP
,password
,使用scrypt
算法生成加密KEY
基于加密
KEY
,使用AES
算法对生成的私钥key.D
加密,只需要D
就可以还原出公私钥。原子写入
keystore
文件,内容包括:明文地址
明文
UUID
keystore
版本号3
加密的
D
以及周边的解密线索。
new
一个账户整个过程结束。
1 | // accounts/keystore/key.go |
通过公钥生成地址的方法由如下函数PubkeyToAddress()
生成。
1 | // crypto/crypto.go |
最后一步就是加密密钥并写入keystore
文件中。
1 | // accounts/keystore/keystore_passphrase.go |
参考文章
keystore介绍:https://ethfans.org/posts/what-is-an-ethereum-keystore-file
scrypt算法介绍:https://www.tarsnap.com/scrypt/scrypt.pdf
转载请注明出处:www.huamo.online