accounts/abi: generic unpacking of event logs into map[string]interface{} (#18440)
Add methods that allow for the unpacking of event logs into maps (allows for agnostic unpacking of logs)
This commit is contained in:
committed by
Guillaume Ballet
parent
86e77900c5
commit
cd79bc61a9
@ -17,6 +17,7 @@
|
||||
package bind
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
@ -191,3 +192,50 @@ func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) er
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseTopicsIntoMap converts the indexed topic field-value pairs into map key-value pairs
|
||||
func parseTopicsIntoMap(out map[string]interface{}, fields abi.Arguments, topics []common.Hash) error {
|
||||
// Sanity check that the fields and topics match up
|
||||
if len(fields) != len(topics) {
|
||||
return errors.New("topic/field count mismatch")
|
||||
}
|
||||
// Iterate over all the fields and reconstruct them from topics
|
||||
for _, arg := range fields {
|
||||
if !arg.Indexed {
|
||||
return errors.New("non-indexed field in topic reconstruction")
|
||||
}
|
||||
|
||||
switch arg.Type.T {
|
||||
case abi.BoolTy:
|
||||
out[arg.Name] = topics[0][common.HashLength-1] == 1
|
||||
case abi.IntTy, abi.UintTy:
|
||||
num := new(big.Int).SetBytes(topics[0][:])
|
||||
out[arg.Name] = num
|
||||
case abi.AddressTy:
|
||||
var addr common.Address
|
||||
copy(addr[:], topics[0][common.HashLength-common.AddressLength:])
|
||||
out[arg.Name] = addr
|
||||
case abi.HashTy:
|
||||
out[arg.Name] = topics[0]
|
||||
case abi.FixedBytesTy:
|
||||
out[arg.Name] = topics[0][:]
|
||||
case abi.StringTy, abi.BytesTy, abi.SliceTy, abi.ArrayTy:
|
||||
// Array types (including strings and bytes) have their keccak256 hashes stored in the topic- not a hash
|
||||
// whose bytes can be decoded to the actual value- so the best we can do is retrieve that hash
|
||||
out[arg.Name] = topics[0]
|
||||
case abi.FunctionTy:
|
||||
if garbage := binary.BigEndian.Uint64(topics[0][0:8]); garbage != 0 {
|
||||
return fmt.Errorf("bind: got improperly encoded function type, got %v", topics[0].Bytes())
|
||||
}
|
||||
var tmp [24]byte
|
||||
copy(tmp[:], topics[0][8:32])
|
||||
out[arg.Name] = tmp
|
||||
default: // Not handling tuples
|
||||
return fmt.Errorf("unsupported indexed type: %v", arg.Type)
|
||||
}
|
||||
|
||||
topics = topics[1:]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user