主页 > imtoken钱包转usdt > 以太坊账户及余额查询
以太坊账户及余额查询
imtoken钱包转usdt 2023-12-01 05:13:57
参考
账户状态stateTrie
Block.Header.Root即stateRoot,是一棵PMT树,存储了所有账户的最新状态信息,比如账户余额。
Root 是一个哈希值。 可以通过Root在数据库中找到stateTrie的根节点,然后用sha3(ethereumAddress)得到最终要查找的路径,然后根据路径一步步找到每个账户rlp(ethereumAccount)
每个用户都有一个Account,分为普通账户和合约账户两种
type Account struct {
Nonce uint64 //Nonce:账户发起交易的次数
Balance *big.Int //该账户的余额
Root common.Hash //存储树MPT,它是所有合约数据存储的地方
CodeHash []byte //合约代码的Hash值 注:[合约]表示该项仅对合约账户有效
}
每个用户对应一个StateObject,StateObject对应stateTrie中的位置,表示一个账户的动态变化结果值
type stateObject struct {
address common.Address
addrHash common.Hash // hash of ethereum address of the account
data Account
db *StateDB
}
余额查询过程 查询获取当前最新的块,然后获取lastBlock.header.Root 首先从本地缓存中查看是否有stateObject的热点数据,如果没有则根据Root在数据库中找到对应的根节点,然后根据MPT树中的Address Arrangement在数据库中找到对应的根节点以太坊官网查余额,找到对应的stateObject,通过stateObject找到对应的Account以太坊官网查余额,得到Account中的余额
func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Big, error) {
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
if state == nil || err != nil {
return nil, err
}
return (*hexutil.Big)(state.GetBalance(address)), state.Error()
}
func (self *StateDB) getStateObject(addr common.Address) (stateObject *stateObject) {
if obj := self.stateObjects[addr]; obj != nil {
return obj
}
enc, err := self.trie.TryGet(addr[:])
}
func (self *StateDB) GetBalance(addr common.Address) *big.Int {
stateObject := self.getStateObject(addr)
if stateObject != nil {
return stateObject.Balance()
}
return common.Big0
}
state_object.go
func (self *stateObject) Balance() *big.Int {
return self.data.Balance
}