专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > Go

边学边读(2),go-ethereum 创建账户

发布时间:2011-06-29 17:56:03 文章来源:www.iduyao.cn 采编人员:星星草
边学边读(二),go-ethereum 创建账户
<!--?xml version="1.0" encoding="UTF-8"?-->
从创建账户的代码开始:personal.newAccount()
创建一个账户我打印了一些调试信息,这些信息是插入在rpc的执行模块中的,为了方便调试我每个方法执行后都打印如下日志
[rpc_execute_result] reply=[<common.Address Value> <error Value>] ; {NewAccount  func(*eth.PrivateAccountAPI, string) (common.Address, error) <func(*eth.PrivateAccountAPI, string) (common.Address, error) Value> %!s(int=3)} ; args=[<*eth.PrivateAccountAPI Value> 123456]
 
从上面这段日志可以看出,创建账户 返回的是一个 Address
reply=[<common.Address Value> <error Value>]
 
具体实现在 eth.PrivateAccountAPI 这个对象的 NewAccount 方法中 
{NewAccount  func(*eth.PrivateAccountAPI, string) ...
 
我传给这个方法的参数,也就是我的密码是 123456
[<*eth.PrivateAccountAPI Value> 123456]
 
那么我们很容易就能找到 eth.PrivateAccountAPI 的源码 go-ethereum/eth/api.go 
// PrivateAccountAPI provides an API to access accounts managed by this node.
// It offers methods to create, (un)lock en list accounts. Some methods accept
// passwords and are therefore considered private by default.
type PrivateAccountAPI struct {
   am     *accounts.Manager
   txPool *core.TxPool
   txMu   *sync.Mutex
   gpo    *GasPriceOracle
}
我们看到 am 这个属性,是 accounts.Manager 类型,猜也猜出来他是干什么的了
// NewAccount will create a new account and returns the address for the new account.
func (*PrivateAccountAPI) NewAccount(password string) (common.Addresserror) {
   accerr := s.am.NewAccount(password)
   if err == nil {
      return acc.Addressnil
   }
   return common.Address{}, err
}
 
再看 NewAccount 的实现,果不其然是用 s.am.NewAccount 实现的这个功能,那么将目标转向 accounts.Manager
源码在 go-ethereum/accounts/account_manager.go 中;
 
// NewAccount generates a new key and stores it into the key directory,
// encrypting it with the passphrase.
func (am *Manager) NewAccount(passphrase string) (Accounterror) {
   _accounterr := storeNewKey(am.keyStore, crand.Readerpassphrase)
   if err != nil {
      return Account{}, err
   }
   // Add the account to the cache immediately rather
   // than waiting for file system notifications to pick it up.
   am.cache.add(account)
   return accountnil
}
 
前面都是结构性的东西只要仔细找大家都能找到,想要看懂 storeNewKey 方法的具体实现,可能需要了解一些 椭圆曲线 相关知识,以及椭圆曲线在非对称加密中的具体应用,但不知道有没有这个必要;
毕竟 openssl 用了这么多年,又有多少人真正关注过 RSA 呢?
 
创建账户一直看到生成一个私钥文件到 keystore 目录就可以了,本着这个目的继续往下看;
 
go-ethereum/accounts/key.go 中可以找到 storeNewKey 方法 
func storeNewKey(ks keyStorerand io.Readerauth string) (*KeyAccounterror) {
   keyerr := newKey(rand)
   if err != nil {
      return nil, Account{}, err
   }
   := Account{Addresskey.AddressFileks.JoinPath(keyFileName(key.Address))}
   if err := ks.StoreKey(a.Filekeyauth); err != nil {
      zeroKey(key.PrivateKey)
      return nil, a, err
   }
   return key, a, err
}
 
到 newKey 方法瞧一瞧
func newKey(rand io.Reader) (*Keyerror) {
   privateKeyECDSAerr := ecdsa.GenerateKey(secp256k1.S256(), rand)
   if err != nil {
      return nil, err
   }
   return newKeyFromECDSA(privateKeyECDSA), nil
}
 
神秘的椭圆曲线签名算法就藏在 ecdsa 中,ecdsa.GenerateKey 根据随机数 rand 生成了一个私钥 privateKeyECDSA
看到这才知道 ecdsa 是 go 标准库中提供的 api;
 
ks.StoreKey 这个方法在 go-ethereum/accounts/key_store_passphrase.go 中可以找到具体实现
func (ks keyStorePassphrase) StoreKey(filename stringkey *Keyauth stringerror {
   keyjsonerr := EncryptKey(keyauthks.scryptNks.scryptP)
   if err != nil {
      return err
   }
   return writeKeyFile(filename, keyjson)
}
 
看到这里,就看到这里吧,生成账户的代码基本上就看完了,使用 椭圆曲线生成私钥,再用私钥生成公钥然后把它们存储在 keystore 目录中,其实关键就是那个加密算法,但是看不懂,其余的都不重要。 
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

  • ModernUI课程:定义一个Logo

    ModernUI教程:定义一个Logo ModernWindow的标题栏包含了一块区域用来显示自定义的窗体Logo: 这个窗体logo通过ModernWindow.LogoD...

  • Django忘记管理员账号和密码的解决方法

    Django忘记管理员账号和密码的解决办法 看着Django的教程学习搭建网站,结果忘记第一次创建的账号和密码了。结果搭建成功以后,一直...

  • GO语言小结(1)——基本知识

    GO语言总结(1)——基本知识 1、注释(与C++一样)   行注释://  块注释:/*   ...  */ 2、标识符   可以这么说,除了数字开头...

  • golang 惯用的文件读取方式

    golang 常用的文件读取方式 Golang 的文件读取方法很多,刚上手时不知道怎么选择,所以贴在此处便后速查。 一次性读取 小文件推荐一...

  • 查询深圳市通相关信息

    查询深圳通相关信息 用 HTTP.GET 从开放 API 中查询深圳通信息,然后将 JSON 数据存入结构体中,再格式化输出。 注意:获取的并不是实...

  • Go语言设计模式实践:结合(Composite)

    Go语言设计模式实践:组合(Composite) 关于本系列 这个系列首先是关于Go语言实践的。在项目中实际使用Go语言也有段时间了,一个体会就...

  • 列出索引和遍历目录

    列出目录和遍历目录 获取目录列表用 ioutil.ReadDir(),遍历目录用 filepath.Walk(),使用方法请参考文章示例。 示例代码: package ma...

  • io 包的惯用接口速记

    io 包的常用接口速记 我没有 C/C++ 基础,没有接口的概念,且从 Python 投奔而来,Python 的极简主义(一个结果往往只提供一个方法),让我在...

  • 代理服务扩充

    代理服务扩展 之前自己实现了一个代理服务,当时考虑的是只要支持SOCKS5就好了,因为我经常用CHROME,配合着SwitchySharp,体验还是很棒...

  • 文件的创造与打开

    文件的创建与打开 文件操作是个很重要的话题,使用也非常频繁,熟悉如何操作文件是必不可少的。Golang 对文件的支持是在 os package ...

热门推荐: