@ -508,6 +508,72 @@ func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Add
return ( * hexutil . Big ) ( state . GetBalance ( address ) ) , state . Error ( )
}
// Result structs for GetProof
type AccountResult struct {
Address common . Address ` json:"address" `
AccountProof [ ] string ` json:"accountProof" `
Balance * hexutil . Big ` json:"balance" `
CodeHash common . Hash ` json:"codeHash" `
Nonce hexutil . Uint64 ` json:"nonce" `
StorageHash common . Hash ` json:"storageHash" `
StorageProof [ ] StorageResult ` json:"storageProof" `
}
type StorageResult struct {
Key string ` json:"key" `
Value * hexutil . Big ` json:"value" `
Proof [ ] string ` json:"proof" `
}
// GetProof returns the Merkle-proof for a given account and optionally some storage keys.
func ( s * PublicBlockChainAPI ) GetProof ( ctx context . Context , address common . Address , storageKeys [ ] string , blockNr rpc . BlockNumber ) ( * AccountResult , 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 ( [ ] StorageResult , len ( storageKeys ) )
// if we have a storageTrie, (which means the account exists), we can update the storagehash
if storageTrie != nil {
storageHash = storageTrie . Hash ( )
} else {
// no storageTrie means the account does not exist, so the codeHash is the hash of an empty bytearray.
codeHash = crypto . Keccak256Hash ( nil )
}
// create the proof for the storageKeys
for i , key := range storageKeys {
if storageTrie != nil {
proof , storageError := state . GetStorageProof ( address , common . HexToHash ( key ) )
if storageError != nil {
return nil , storageError
}
storageProof [ i ] = StorageResult { key , ( * hexutil . Big ) ( state . GetState ( address , common . HexToHash ( key ) ) . Big ( ) ) , common . ToHexArray ( proof ) }
} else {
storageProof [ i ] = StorageResult { key , & hexutil . Big { } , [ ] string { } }
}
}
// create the accountProof
accountProof , proofErr := state . GetProof ( address )
if proofErr != nil {
return nil , proofErr
}
return & AccountResult {
Address : address ,
AccountProof : common . ToHexArray ( accountProof ) ,
Balance : ( * hexutil . Big ) ( state . GetBalance ( address ) ) ,
CodeHash : codeHash ,
Nonce : hexutil . Uint64 ( state . GetNonce ( address ) ) ,
StorageHash : storageHash ,
StorageProof : storageProof ,
} , state . Error ( )
}
// 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.
func ( s * PublicBlockChainAPI ) GetBlockByNumber ( ctx context . Context , blockNr rpc . BlockNumber , fullTx bool ) ( map [ string ] interface { } , error ) {