modify go-etheruem vendor lib with methods that allow for unpacking of events into maps of interfaces
This commit is contained in:
parent
8ce75fe5ad
commit
5307de2b97
18
vendor/github.com/ethereum/go-ethereum/accounts/abi/abi.go
generated
vendored
18
vendor/github.com/ethereum/go-ethereum/accounts/abi/abi.go
generated
vendored
@ -91,6 +91,24 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) (err error) {
|
||||
return fmt.Errorf("abi: could not locate named method or event")
|
||||
}
|
||||
|
||||
// Unpack output into a map according to the abi specification
|
||||
func (abi ABI) UnpackIntoMap(v map[string]interface{}, name string, output []byte) (err error) {
|
||||
if len(output) == 0 {
|
||||
return fmt.Errorf("abi: unmarshalling empty output")
|
||||
}
|
||||
// since there can't be naming collisions with contracts and events,
|
||||
// we need to decide whether we're calling a method or an event
|
||||
if method, ok := abi.Methods[name]; ok {
|
||||
if len(output)%32 != 0 {
|
||||
return fmt.Errorf("abi: improperly formatted output")
|
||||
}
|
||||
return method.Outputs.Unpack(v, output)
|
||||
} else if event, ok := abi.Events[name]; ok {
|
||||
return event.Inputs.UnpackIntoMap(v, output)
|
||||
}
|
||||
return fmt.Errorf("abi: could not locate named method or event")
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements json.Unmarshaler interface
|
||||
func (abi *ABI) UnmarshalJSON(data []byte) error {
|
||||
var fields []struct {
|
||||
|
40
vendor/github.com/ethereum/go-ethereum/accounts/abi/argument.go
generated
vendored
40
vendor/github.com/ethereum/go-ethereum/accounts/abi/argument.go
generated
vendored
@ -100,6 +100,16 @@ func (arguments Arguments) Unpack(v interface{}, data []byte) error {
|
||||
return arguments.unpackAtomic(v, marshalledValues)
|
||||
}
|
||||
|
||||
// Unpack performs the operation hexdata -> Go format
|
||||
func (arguments Arguments) UnpackIntoMap(v map[string]interface{}, data []byte) error {
|
||||
marshalledValues, err := arguments.UnpackValues(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return arguments.unpackIntoMap(v, marshalledValues)
|
||||
}
|
||||
|
||||
func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interface{}) error {
|
||||
|
||||
var (
|
||||
@ -159,6 +169,36 @@ func (arguments Arguments) unpackTuple(v interface{}, marshalledValues []interfa
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unpack arguments into map
|
||||
func (arguments Arguments) unpackIntoMap(v map[string]interface{}, marshalledValues []interface{}) error {
|
||||
// Make sure fields exist in map
|
||||
exists := make(map[string]bool)
|
||||
for _, arg := range arguments {
|
||||
field := arg.Name
|
||||
if field == "" {
|
||||
return fmt.Errorf("abi: purely underscored output cannot unpack to map")
|
||||
}
|
||||
if exists[field] {
|
||||
return fmt.Errorf("abi: multiple outputs mapping to the same map field '%s'", field)
|
||||
}
|
||||
exists[field] = true
|
||||
}
|
||||
|
||||
for name, _ := range exists {
|
||||
_, ok := v[name]
|
||||
if !ok {
|
||||
return fmt.Errorf("abi: output map missing argument name")
|
||||
}
|
||||
}
|
||||
|
||||
for i, arg := range arguments.NonIndexed() {
|
||||
reflectValue := reflect.ValueOf(marshalledValues[i])
|
||||
v[arg.Name] = reflectValue
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// unpackAtomic unpacks ( hexdata -> go ) a single value
|
||||
func (arguments Arguments) unpackAtomic(v interface{}, marshalledValues []interface{}) error {
|
||||
if len(marshalledValues) != 1 {
|
||||
|
16
vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/base.go
generated
vendored
16
vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/base.go
generated
vendored
@ -340,6 +340,22 @@ func (c *BoundContract) UnpackLog(out interface{}, event string, log types.Log)
|
||||
return parseTopics(out, indexed, log.Topics[1:])
|
||||
}
|
||||
|
||||
// UnpackLogIntoMap unpacks a retrieved log into the provided map.
|
||||
func (c *BoundContract) UnpackLogIntoMap(out map[string]interface{}, event string, log types.Log) error {
|
||||
if len(log.Data) > 0 {
|
||||
if err := c.abi.UnpackIntoMap(out, event, log.Data); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
var indexed abi.Arguments
|
||||
for _, arg := range c.abi.Events[event].Inputs {
|
||||
if arg.Indexed {
|
||||
indexed = append(indexed, arg)
|
||||
}
|
||||
}
|
||||
return parseTopicsIntoMap(out, indexed, log.Topics[1:])
|
||||
}
|
||||
|
||||
// ensureContext is a helper method to ensure a context is not nil, even if the
|
||||
// user specified it as such.
|
||||
func ensureContext(ctx context.Context) context.Context {
|
||||
|
39
vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/topics.go
generated
vendored
39
vendor/github.com/ethereum/go-ethereum/accounts/abi/bind/topics.go
generated
vendored
@ -187,3 +187,42 @@ func parseTopics(out interface{}, fields abi.Arguments, topics []common.Hash) er
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseTopics 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:
|
||||
if topics[0][common.HashLength-1] == 1 {
|
||||
out[arg.Name] = true
|
||||
} else {
|
||||
out[arg.Name] = false
|
||||
}
|
||||
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.BytesTy, abi.FixedBytesTy:
|
||||
out[arg.Name] = topics[0][:]
|
||||
default:
|
||||
}
|
||||
|
||||
topics = topics[1:]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user