mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 10:22:23 +00:00
first impl of eth_getProof
This commit is contained in:
parent
7eb0a7c8bb
commit
9ee871a1c7
4 changed files with 86 additions and 0 deletions
|
|
@ -31,6 +31,15 @@ func ToHex(b []byte) string {
|
||||||
return "0x" + hex
|
return "0x" + hex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// creates a array of hex-string based on []byte
|
||||||
|
func ToHexArray(b [][]byte) []string {
|
||||||
|
r := make([]string, len(b))
|
||||||
|
for i := range b {
|
||||||
|
r[i] = ToHex(b[i])
|
||||||
|
}
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
// FromHex returns the bytes represented by the hexadecimal string s.
|
// FromHex returns the bytes represented by the hexadecimal string s.
|
||||||
// s may be prefixed with "0x".
|
// s may be prefixed with "0x".
|
||||||
func FromHex(s string) []byte {
|
func FromHex(s string) []byte {
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,32 @@ func (self *StateDB) GetState(addr common.Address, hash common.Hash) common.Hash
|
||||||
return common.Hash{}
|
return common.Hash{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MerkleProof
|
||||||
|
type ProofList [][]byte
|
||||||
|
|
||||||
|
func (n *ProofList) Put(key []byte, value []byte) error {
|
||||||
|
*n = append(*n, value)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the MerkleProof for a given Account
|
||||||
|
func (self *StateDB) GetProof(a common.Address) [][]byte {
|
||||||
|
var proof ProofList
|
||||||
|
self.trie.Prove(crypto.Keccak256(a.Bytes()), 0, &proof)
|
||||||
|
return [][]byte(proof)
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the StorageProof for given key
|
||||||
|
func (self *StateDB) GetStorageProof(a common.Address, key common.Hash) [][]byte {
|
||||||
|
trie := self.StorageTrie(a)
|
||||||
|
if trie == nil {
|
||||||
|
return [][]byte{}
|
||||||
|
}
|
||||||
|
var proof ProofList
|
||||||
|
trie.Prove(crypto.Keccak256(key.Bytes()), 0, &proof)
|
||||||
|
return [][]byte(proof)
|
||||||
|
}
|
||||||
|
|
||||||
// GetCommittedState retrieves a value from the given account's committed storage trie.
|
// GetCommittedState retrieves a value from the given account's committed storage trie.
|
||||||
func (self *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
|
func (self *StateDB) GetCommittedState(addr common.Address, hash common.Hash) common.Hash {
|
||||||
stateObject := self.getStateObject(addr)
|
stateObject := self.getStateObject(addr)
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@ type StateDB interface {
|
||||||
SetNonce(common.Address, uint64)
|
SetNonce(common.Address, uint64)
|
||||||
|
|
||||||
GetCodeHash(common.Address) common.Hash
|
GetCodeHash(common.Address) common.Hash
|
||||||
|
GetProof(common.Address) [][]byte
|
||||||
|
GetStorageProof(common.Address, common.Hash) [][]byte
|
||||||
GetCode(common.Address) []byte
|
GetCode(common.Address) []byte
|
||||||
SetCode(common.Address, []byte)
|
SetCode(common.Address, []byte)
|
||||||
GetCodeSize(common.Address) int
|
GetCodeSize(common.Address) int
|
||||||
|
|
|
||||||
|
|
@ -502,6 +502,55 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add
|
||||||
return (*hexutil.Big)(state.GetBalance(address)), state.Error()
|
return (*hexutil.Big)(state.GetBalance(address)), state.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBalance returns the amount of wei for the given address in the state of the
|
||||||
|
// given block number. The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta
|
||||||
|
// block numbers are also allowed.
|
||||||
|
func (s *PublicBlockChainAPI) GetProof(ctx context.Context, address common.Address, storageKeys []string, blockNr rpc.BlockNumber) (map[string]interface{}, error) {
|
||||||
|
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
|
||||||
|
if state == nil || err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
storageTrie := state.StorageTrie(address)
|
||||||
|
storageHash := types.EmptyRootHash
|
||||||
|
codeHash := state.GetCodeHash(address)
|
||||||
|
storageProof := make([]map[string]interface{}, len(storageKeys))
|
||||||
|
|
||||||
|
if storageTrie != nil {
|
||||||
|
storageHash = storageTrie.Hash()
|
||||||
|
} else {
|
||||||
|
codeHash = crypto.Keccak256Hash(nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range storageKeys {
|
||||||
|
if storageTrie != nil {
|
||||||
|
storageProof[i] = map[string]interface{}{
|
||||||
|
"key": storageKeys[i],
|
||||||
|
"value": state.GetState(address, common.HexToHash(storageKeys[i])),
|
||||||
|
"proof": common.ToHexArray(state.GetStorageProof(address, common.HexToHash(storageKeys[i]))),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
storageProof[i] = map[string]interface{}{
|
||||||
|
"key": storageKeys[i],
|
||||||
|
"value": common.Hash{},
|
||||||
|
"proof": []string{},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := map[string]interface{}{
|
||||||
|
"address": address,
|
||||||
|
"accountProof": common.ToHexArray(state.GetProof(address)),
|
||||||
|
"balance": (*hexutil.Big)(state.GetBalance(address)),
|
||||||
|
"codeHash": codeHash,
|
||||||
|
"nonce": hexutil.Uint64(state.GetNonce(address)),
|
||||||
|
"storageHash": storageHash,
|
||||||
|
"storageProof": storageProof,
|
||||||
|
}
|
||||||
|
|
||||||
|
return fields, state.Error()
|
||||||
|
}
|
||||||
|
|
||||||
// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all
|
// GetBlockByNumber returns the requested block. When blockNr is -1 the chain head is returned. When fullTx is true all
|
||||||
// transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
|
// transactions in the block are returned in full detail, otherwise only the transaction hash is returned.
|
||||||
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue