Ethereum源码阅读笔记-accounts

转载请注明出处:www.huamo.online
字节杭州 求贤若渴:

  1. https://job.toutiao.com/s/JXTdQaH
  2. https://job.toutiao.com/s/JXTMWW3
  3. https://job.toutiao.com/s/JXT1tpC
  4. https://job.toutiao.com/s/JXTdu6h

go-ethereum/accounts

accounts包实现了高层的以太坊账号管理模块

首先看accounts.go中的Account结构体:Account结构体描述了一个以太坊账号,可以定位到一个指定地址上,这个地址由结构体中的Account.URL字段定义,Account.URL字段是可选的。结构体中的另一个字段Account.Address是必选的,该地址是由私钥衍生出来。

1
2
3
4
5
6
// accounts/accounts.go

type Account struct {
Address common.Address `json:"address"` // Ethereum account address derived from the key
URL URL `json:"url"` // Optional resource locator within a backend
}

接下来是Wallet接口:Wallet接口代表了一个可能包含一个或多个账号的软件或者硬件钱包。这些账号由同样的随机种子产生。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// account/accounts.go

type Wallet interface {
// URL检索该钱包可达的规范路径,上层用它来定义来自多个后端的所有钱包的排序顺序。
URL() URL

// Status返回一个文本状态,用于帮助用户获悉目前的钱包状态。
// 当钱包可能遇到任何故障的时候,它也会返回一个错误信息。
Status() (string, error)

// Open初始化对一个钱包实例的访问。
// 这并不意味着解锁或解密账户密钥,而只是简单的建立与硬件钱包的一个连接,或是访问本源种子。
// passphrase参数可能会,也可能不会被一个特定的钱包实现用到。
// 不提供无密码Open方法的原因是为了努力实现统一的钱包处理,而忽略不同的后端提供商。
// 请注意:如果你Open了一个钱包,你必须要Close它以释放各种已分配的资源(在使用硬件钱包时这一点尤为重要)。
Open(passphrase string) error

// Close释放一个已打开钱包实例持有的所有资源。
Close() error

// Accounts检索钱包当前所知的签名账户列表。
// 对于分层确定性钱包(hierarchical deterministic wallet),该列表不会是详尽全面的。
// 而只是包含那些在账户导出过程中显式固定下来的账户。
Accounts() []Account

// Contains返回一个账户是否是这个特定钱包的一部分。
Contains(account Account) bool

// Derive(导出,派生)试图在指定的导出路径上显式的导出分层确定性账户。如果需要,导出的账户会被添加到该钱包的跟踪账户列表中。
Derive(path DerivationPath, pin bool) (Account, error)

// SelfDerive设置一个基本账户导出路径,从中钱包尝试发现非零账户,并自动将他们加入到跟踪账户列表中。
// 请注意,自导出会将指定路径的最后一个组成部分递增,而不是降为子路径,以允许发现从非零组件开始的账户。
// 你可以用一个空的ChainStateReader调用SelfDerive来禁用自动账户发现功能。
SelfDerive(base DerivationPath, chain ethereum.ChainStateReader)

// SignHash请求钱包对指定的hash串签名。
// 它仅通过给定账户中包含的地址来查找账户,或可选的借助于账户内嵌的URL字段中的任意位置元数据查找账户。
// 如果钱包需要额外的身份验证来签名请求(例如:使用一个密码来解密账户,或者一个PIN码来验证交易),这时会返回一个AuthNeededError实例。
// 这个AuthNeededError实例包含了一些信息告知用户需要哪些字段或操作。
// 用户可以通过SignHashWithPassphrase,或者其他方式(比如:解锁keystore中的账户)来进行重试。
SignHash(account Account, hash []byte) ([]byte, error)


// SignTx请求钱包对给定的交易进行签名。
// 它仅通过给定账户中包含的地址来查找账户,或可选的借助于账户内嵌的URL字段中的任意位置元数据查找账户。
// 如果钱包需要额外的身份验证来签名请求(例如:使用一个密码来解密账户,或者一个PIN码来验证交易),这时会返回一个AuthNeededError实例。
// 这个AuthNeededError实例包含了一些信息告知用户需要哪些字段或操作。
// 用户可以通过SignTxWithPassphrase,或者其他方式(比如:解锁keystore中的账户)来进行重试。
SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)

// SignHashWithPassphrase请求钱包使用给定的passphrase作为额外的身份验证信息,来对给定的hash串签名。
// 它仅通过给定账户中包含的地址来查找账户,或可选的借助于账户内嵌的URL字段中的任意位置元数据查找账户。
SignHashWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error)

// SignTxWithPassphrase请求钱包使用给定的passphrase作为额外的身份验证信息,来对给定的交易签名。
// 它仅通过给定账户中包含的地址来查找账户,或可选的借助于账户内嵌的URL字段中的任意位置元数据查找账户。
SignTxWithPassphrase(account Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error)
}

accounts.go中还有一个Backend接口,它是一个“钱包提供商”,可能包含一批可以签名交易并根据请求签名交易的账户。

1
2
3
4
5
6
7
8
9
10
11
12
// account/accounts.go

type Backend interface {

// Wallets可检索出后端目前知道的钱包列表。
// 返回的钱包默认情况下不会打开。对于软件HD钱包,这意味着没有解密任何基础种子;对于硬件钱包,这意味着没有建立实际连接。
// 所产生的钱包列表将根据其后端分配的内部URL按字母顺序排序。由于钱包(特别是硬件钱包)可能会来来去去,因此在随后的检索重试中,同一个钱包可能会出现列表中的不同位置。
Wallets() []Wallet

// Subscribe会创建一个异步订阅,当该后端检测到一个钱包到来或者离开的时候,将会收到通知。
Subscribe(sink chan<- WalletEvent) event.Subscription
}

Backend.Subscribe()中,订阅的事件类型为WalletEvent类型,下面来看看WalletEvent的定义,它是一个结构体,表示检测到钱包到来或离开时,由一个账户后端触发的事件。

1
2
3
4
5
6
// account/accounts.go

type WalletEvent struct {
Wallet Wallet // 到来或者离开的钱包实例
Kind WalletEventType // 在系统中触发的事件类型
}

其中事件类型由WalletEventType类型表示,它本质上是一个int,只是为了区分不同的事件,以太坊共有3种钱包事件类型,分别为钱包到来钱包打开钱包离开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// account/accounts.go

// WalletEventType代表了由钱包订阅子系统可以触发的不同事件类型。分为以下3种
type WalletEventType int

const (
// WalletArrived在检测到一个新钱包时触发,通过USB插入,或者在keystore中通过一个文件系统事件通知到。
WalletArrived WalletEventType = iota

// WalletOpened当一个钱包被成功打开时触发,目的是为了启动后台进程,例如自动密钥派生。
WalletOpened

// WalletDropped当一个钱包离开时触发。
WalletDropped
)

转载请注明出处:www.huamo.online