accounts 包实现了 eth 客户端的钱包和账户管理.
账号的数据结构:
- typeAccount struct {
- Address common.Address JSON:"address" // Ethereum account addressderived from the key
- URLURL JSON:"url" // Optional resource locator within a backend
- }
钱包 interface, 是指包含了一个或多个账户的软件钱包或者硬件钱包
- type Wallet struct {
- URL() URL // URL 用来获取这个钱包可以访问的规范路径. 它会被上层使用用来从所有的后端的钱包来排序.
- Status() (string, error) // 用来返回一个文本值用来标识当前钱包的状态. 同时也会返回一个 error 用来标识钱包遇到的任何错误.
- Open(passphrase string) error //Open 初始化对钱包实例的访问. 如果你 open 了一个钱包, 你必须 close 它.
- Close() error // Close 释放由 Open 方法占用的任何资源.
- Accounts() []Account // Accounts 用来获取钱包发现了账户列表. 对于分层次的钱包, 这个列表不会详尽的列出所有的账号, 而是只包含在帐户派生期间明确固定的帐户.
- Derive(path DerivationPath, pin bool) (Account,error) //Derive 尝试在指定的派生路径上显式派生出分层确定性帐户. 如果 pin 为 true, 派生帐户将被添加到钱包的跟踪帐户列表中.
- SelfDerive(base DerivationPath,chain ethereum.ChainStateReader) //SelfDerive 设置一个基本帐户导出路径, 从中钱包尝试发现非零帐户, 并自动将其添加到跟踪帐户列表中.
- SignHash(account Account, hash []byte)([]byte, error) // SignHash 请求钱包来给传入的 hash 进行签名.
- SignTx(account Account, tx*types.Transaction, chainID *big.Int) (*types.Transaction, error) // SignTx 请求钱包对指定的交易进行签名.
- SignHashWithPassphrase(accountAccount, passphrase string, hash []byte) ([]byte, error) //SignHashWithPassphrase 请求钱包使用给定的 passphrase 来签名给定的 hash
- SignTxWithPassphrase(accountAccount, passphrase string, tx *types.Transaction, chainID *big.Int)(*types.Transaction, error) // SignHashWithPassphrase 请求钱包使用给定的 passphrase 来签名给定的 transaction
- }
后端 Backend,Backend 是一个钱包提供器. 可以包含一批账号. 他们可以根据请求签署交易.
- type Backend struct {
- Wallets() []wallet // Wallets 获取当前能够查找到的钱包
- Subscribe(sink chan <-WalletEvent) event.Subscription // 订阅创建异步订阅, 以便在后端检测到钱包的到达或离开时接收通知.
- }
- manager.go
Manager 是一个包含所有东西的账户管理工具. 可以和所有的 Backends 来通信来签署交易.
eth 账户定义, 在 accounts.keystore.key.go 中定义
eth 账户主要包含三条信息, ID, 地址和公私钥对.
- type Keystruct {
- IDuuid.UUID
- Address common.Address
- PrivateKey ecdsa.PrivateKey
- }
eth 创建账户的流程:
1, 用户输入一个密码 (passphrase string)
2, 内部通过椭圆曲线算法随机生成一个公私密钥对 (internal.ethapi.apinewAccount 方法)
3, 对公钥 hash 得到地址
4, 对密码使用 scrypt 算法加密, 得到加密后的密码 derivedKey
5, 用 derivedKey 的对私钥使用 AES-CTR 算法加密, 得到密文 cipherText
6, 对 derivedKey 和 cipherText 进行 hash 得到 Mac, 这个 Mac 实际上起到了签名的作用, 在解密的时候去验证合法性, 防止别人篡改
7, 保存账号地址和加密过程中写死或随机生成的参数到 JSON 文件中, 也就是就是上面的文件
创建账号的核心代码:(accounts.keystore.keystore_passphrase.go)
中的 EncryptKey 方法
funcEncryptKey(keyKey,authstring,scryptN,scryptPint) ([]byte,error)
其中, key 是加密的账号, 包含 ID, 公私钥, 地址
auth 是用户输入的密码
scryptN, 是 scrypt 算法中的 N
scryptP,scrypt 算法中的 P
derivedKey, err := scrypt.Key(authArray, salt, scryptN, scryptR, scryptP, scryptDKLen)
对用户名输入的密码使用 scrypt 加密, 返回一个 derivedKey
来源: http://www.bubuko.com/infodetail-2811597.html