转载请注明出处: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文件,内容包括:明文地址
明文
UUIDkeystore版本号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