geth创建外部账号的流程

匿名 (未验证) 提交于 2019-12-03 00:22:01

命令的代码执行流程

一、寻找命令入口

1.1. go-ethereum工程/cmd/geth/main.go

func init() {

//从这里知道,与account命令相关的代码在accountCommand.go文件中

}

1.2. 打开 cms/geth/accountcmd.go

Subcommands:[]cli.Command{

...................

{

从这里可以知道 new 命令的执行函数在accountCreate函数中

................

二、accountCreate函数执行流程

// accountcmd.go

funcaccountCreate(ctx *cli.Context) error {

加载配置文件, 获取keydir,scryptN, scryptP

提示输入密码

//这里创建地址,生成公钥和私钥

打印地址

}

/////////////////////////////////////////////////////////////////////////

//accounts/keystore/keystore_passphrase.go

//具体表现为生成一对公私钥,再由私钥算出地址并构建一个自定义的Key

// StoreKey generatesa key, encrypts with 'auth' and stores in the given directory
func StoreKey(dir, auth string, scryptN, scryptPint) (common.Address, error) {
storeNewKey(&keyStorePassphrase{dir,scryptN, scryptP}, crand.Reader, auth)
return a.Address,err
}

/////////////////////////////////////////////////////////////////////////////

//accounts/keystore/key.go

func storeNewKey(ks keyStore, rand io.Reader, authstring) (*Key, accounts.Account, error) {
newKey//生成密钥对
if err !=nil {
return nil, accounts.Account{},err

//私钥被保存到磁盘,保存前使用密码加密,密钥文件存储在你的以太坊客户端keystore 子目录中
if err :=ks.StoreKey(a.URL.Path, key, auth)

return nil,a, err

return key,a, err
}

----------------------------------------------

func newKey(rand io.Reader) (*Key, error) {

// ecdsa椭圆曲线数字签名算法,这里使用ecdsa生成一对公私钥,并选择的是secp256k1曲线。

if err !=nil {
return nil,err

return newKeyFromECDSA(privateKeyECDSA),nil
}

---------------------------------------------------

// GenerateKeygenerates a public and private key pair.
func GenerateKey(c elliptic.Curve, rand io.Reader)(*PrivateKey, error) {

if err !=nil {
return nil,err

//生成私钥


//生成公钥
return priv,nil
}

---------------------------------------------------------------------------------------

func newKeyFromECDSA(privateKeyECDSA*ecdsa.PrivateKey) *Key {



//地址是公钥转过来的,仅20字节


return key
}

-------------------------------------------------------------------------------------

func PubkeyToAddress(p ecdsa.PublicKey)common.Address {

return common.BytesToAddress(Keccak256(pubBytes[1:])[12//公钥经过Keccak-256
}

-------------------------------------------------------------------------------------

func BytesToAddress(b []byte) Address {
var aAddress

return a
}

--------------------------------------------------------------------------------------------

func (a *Address) SetBytes(b []byte) {
if len(b)> len(a) {
AddressLength等于20

AddressLength//取后20字节(160bit, 即40个16进制字符)作为地址
}

三、总结

每个账户都由一对钥匙定义,一个私钥(PrivateKey)和一个公钥(Public Key)。 账户以地址为索引,地址由公钥衍生而来,取公钥的最后20个字节。每对私钥/地址都编码在一个钥匙文件里(Keystore)。

地址的生成的流程是:私钥 -> 公钥 -> 地址。因此地址的生成需要三步:

1由secp256k1曲线生成私钥,是由随机的256bit组成(32字节)

2、采用椭圆曲线数字签名算法(ECDSA)将私钥映射成公钥(64字节)

3、公钥经过Keccak-256单向散列函数变成了256bit,然后取160bit作为地址(20字节)


注意:私钥极其重要,用户输入的密码用来对私钥加密,加密后的密钥文件被保存到keystore目录下。密钥文件最好经常换密码,并以多种形式存放最为妥当。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!