From ece58f00b51fa31d76e934d468ab7e42a86db518 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Wed, 6 Mar 2024 14:11:15 +0800 Subject: [PATCH] ethapi: add method eth_getAccountInfo --- core/state/statedb.go | 30 ++++++++++++++++++++++++++++++ internal/ethapi/api.go | 18 ++++++++++++++++++ internal/jsre/deps/web3.js | 8 ++++++++ 3 files changed, 56 insertions(+) diff --git a/core/state/statedb.go b/core/state/statedb.go index 8b374fda65..4bedebe8b3 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -83,6 +83,14 @@ type StateDB struct { lock sync.Mutex } +type AccountInfo struct { + CodeSize int + Nonce uint64 + Balance *big.Int + CodeHash common.Hash + StorageHash common.Hash +} + func (self *StateDB) SubRefund(gas uint64) { self.journal = append(self.journal, refundChange{ prev: self.refund}) @@ -262,6 +270,28 @@ func (self *StateDB) GetCodeHash(addr common.Address) common.Hash { return common.BytesToHash(stateObject.CodeHash()) } +func (self *StateDB) GetAccountInfo(addr common.Address) *AccountInfo { + result := AccountInfo{} + + stateObject := self.getStateObject(addr) + if stateObject == nil { + result.Balance = common.Big0 + return &result + } + + if stateObject.code != nil { + result.CodeSize = len(stateObject.code) + } else { + result.CodeSize, _ = self.db.ContractCodeSize(stateObject.addrHash, common.BytesToHash(stateObject.CodeHash())) + } + result.Nonce = stateObject.Nonce() + result.Balance = stateObject.Balance() + result.CodeHash = common.BytesToHash(stateObject.CodeHash()) + result.StorageHash = stateObject.Root() + + return &result +} + func (self *StateDB) GetState(addr common.Address, bhash common.Hash) common.Hash { stateObject := self.getStateObject(addr) if stateObject != nil { diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 242584e863..519d4490ab 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -623,6 +623,24 @@ func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Addres return code, state.Error() } +// GetAccountInfo returns the information at the given address in the state for the given block number. +func (s *PublicBlockChainAPI) GetAccountInfo(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (map[string]interface{}, error) { + state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) + if state == nil || err != nil { + return nil, err + } + info := state.GetAccountInfo(address) + result := map[string]interface{}{ + "address": address, + "balance": (*hexutil.Big)(info.Balance), + "codeSize": info.CodeSize, + "codeHash": info.CodeHash, + "nonce": info.Nonce, + "storageHash": info.StorageHash, + } + return result, nil +} + // GetStorageAt returns the storage from the state at the given address, key and // block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block // numbers are also allowed. diff --git a/internal/jsre/deps/web3.js b/internal/jsre/deps/web3.js index 95b0d1aaf7..5c7236ed14 100644 --- a/internal/jsre/deps/web3.js +++ b/internal/jsre/deps/web3.js @@ -5329,6 +5329,13 @@ var methods = function () { inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter] }); + var getAccountInfo = new Method({ + name: 'getAccountInfo', + call: 'eth_getAccountInfo', + params: 2, + inputFormatter: [formatters.inputAddressFormatter, formatters.inputDefaultBlockNumberFormatter] + }); + var getBlock = new Method({ name: 'getBlock', call: blockCall, @@ -5513,6 +5520,7 @@ var methods = function () { getBalance, getStorageAt, getCode, + getAccountInfo, getBlock, getBlockSigners, getStakerROI,