未分类

以太坊账户相关

以太坊账户相关

主要和两个类有关,一个是

libethereum/Account.cpp

另外一个是

libweb3jsonrpc/AccountHolder.cpp

Account类

原作者的注释是:


/**
 * Models the state of a single Ethereum account.
 * Used to cache a portion of the full Ethereum state. State keeps a mapping of Address's to Accounts.
 *
 * Aside from storing the nonce and balance, the account may also be "dead" (where isAlive() returns false).
 * This allows State to explicitly store the notion of a deleted account in it's cache. kill() can be used
 * for this.
 *
 * For the account's storage, the class operates a cache. baseRoot() specifies the base state of the storage
 * given as the Trie root to be looked up in the state database. Alterations beyond this base are specified
 * in the overlay, stored in this class and retrieved with storageOverlay(). setStorage allows the overlay
 * to be altered.
 *
 * The constructor allows you to create an one of a number of "types" of accounts. The default constructor
 * makes a dead account (this is ignored by State when writing out the Trie). Another three allow a basic
 * or contract account to be specified along with an initial balance. The fina two allow either a basic or
 * a contract account to be created with arbitrary values.
 */

可以看出,基本就是有关账户的各种基本状态。

AccountHolder类

原作者的注释如下:


/**
 * Manages real accounts (where we know the secret key) and proxy accounts (where transactions
 * to be sent from these accounts are forwarded to a proxy on the other side).
 */

容易看出就是对账户进行管理的类。

同时还应注意,还有个

keyManager

类,这个类是用来管理账户密钥的,里面有个

defautPath

函数,这个函数返回存放密钥文件的默认文件夹,在博主这里,默认文件夹是

home/pcx/.web3/keys

其中博主电脑的用户名就是"pcx", 这个文件是个json格式的文件,包括混淆参数等各种参数(不包括余额),调用

personal_newAccount

函数的时候就用到了这个 keyManager 。这儿有个意外的发现,不过没测试过,当以太坊处于test模式的时候,储存的账户文件是暂时的,结束后直接删除。再就是创建账户的时候,最终创建的账户并不会直接落盘存储,在本节点"结束"的时候才会存入本地的数据库。导入外部账户不能直接复制粘贴那个

json

文件,得用

./aleth account import

这样的操作,如果不这么干的话,控制台会直接崩溃掉(shit ethconsole),本人觉得,这个和data里面的那个

keys.info

以及

keys.info.salt

有关,本人试过直接复制另外节点的这个文件,替换本地节点的这个文件,最后崩溃了,但是没试过同时将这两个文件以及那个

json

文件同时替换。

再就是两个节点同时用一个账户挖矿是没有任何问题的。根据作者的原文注释,一般执行流程有两种模式,一个是

initialize  execute  finalize

如果

execute

出错就执行

go

第二种模式就是首先执行

call/create

然后执行

accrueSubState

如果前者执行失败的话就执行

go

。在挖矿之前会执行一个

wouldSeal

函数,这个函数只会检查是否有

author

这个

author

就是在

miner.setEtherbase

里面确定的挖矿者,但是这个不存在检查这个author是否在其他节点挖矿的代码。在最后的

commitToSeal

中调用了一个

applyRewards

函数,这个函数调用了一个

addBalance

函数,这个函数定义在

Account.cpp

里面,按照作者的注释,这个函数应该定义在

AccountHolder

里面才是,这儿有点疑问。同时这个

addBalance

State.cpp

里面也有定义,但是就只是对

Account.cpp

里面的那个的一个扩充,添加了一个检查步骤,但最终调用的还是那个函数。同时,并未发现检查其他节点是否用这个账户挖矿的相关代码,只进行了对前面叔叔区块,奶奶区块的检查,按照原作者的话来说就是 whatever they are 检查就是了。

在发送交易的时候就是按照上面提到的那三步走的步骤来的,在半年前写的博客中提到进行账户的检查是在

initialize

里面进行的,不是在

execute

里面执行的,这个发送交易的账户和挖矿的账户是同一个账户,也并未发现检查其他节点的相关代码,只要本节点存有相关的密钥文件,就可以直接解锁账户,并完成交易的发送,并不需要管其他节点具体是咋样。

最后有个小插曲,就是有个

enact

函数,在半年前的博客中备注是区块状态的检查,但是现在发现是用来算区块难度的,但是不知道为啥,在调用

eth.getBalance

这个函数的时候调用了这个

enact

函数,不应该啊,这个疑点留给以后去研究。

One Comment

Leave a Reply

邮箱地址不会被公开。 必填项已用*标注