mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-25 06:06:44 +00:00
add functionality for unpacking transaction log to event parameters
This commit is contained in:
parent
828e1e35fd
commit
04bdfa0605
1 changed files with 26 additions and 16 deletions
|
|
@ -232,7 +232,8 @@ var (
|
||||||
|
|
||||||
// Unpack output in v according to the abi specification
|
// Unpack output in v according to the abi specification
|
||||||
func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
||||||
var method = abi.Methods[name]
|
var method, ok = abi.Methods[name]
|
||||||
|
var args []Argument
|
||||||
|
|
||||||
if len(output) == 0 {
|
if len(output) == 0 {
|
||||||
return fmt.Errorf("abi: unmarshalling empty output")
|
return fmt.Errorf("abi: unmarshalling empty output")
|
||||||
|
|
@ -244,18 +245,27 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
||||||
return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
|
return fmt.Errorf("abi: Unpack(non-pointer %T)", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
args = method.Outputs
|
||||||
|
} else {
|
||||||
|
var event, ok = abi.Events[name]
|
||||||
|
if ok {
|
||||||
|
args = event.Inputs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
value = valueOf.Elem()
|
value = valueOf.Elem()
|
||||||
typ = value.Type()
|
typ = value.Type()
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(method.Outputs) > 1 {
|
if len(args) > 1 {
|
||||||
switch value.Kind() {
|
switch value.Kind() {
|
||||||
// struct will match named return values to the struct's field
|
// struct will match named return values to the struct's field
|
||||||
// names
|
// names
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
for i := 0; i < len(method.Outputs); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
marshalledValue, err := toGoType(i, method.Outputs[i], output)
|
marshalledValue, err := toGoType(i, args[i], output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -264,8 +274,8 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
||||||
for j := 0; j < typ.NumField(); j++ {
|
for j := 0; j < typ.NumField(); j++ {
|
||||||
field := typ.Field(j)
|
field := typ.Field(j)
|
||||||
// TODO read tags: `abi:"fieldName"`
|
// TODO read tags: `abi:"fieldName"`
|
||||||
if field.Name == strings.ToUpper(method.Outputs[i].Name[:1])+method.Outputs[i].Name[1:] {
|
if field.Name == strings.ToUpper(args[i].Name[:1])+args[i].Name[1:] {
|
||||||
if err := set(value.Field(j), reflectValue, method.Outputs[i]); err != nil {
|
if err := set(value.Field(j), reflectValue, args[i]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -278,17 +288,17 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
||||||
|
|
||||||
// if the slice already contains values, set those instead of the interface slice itself.
|
// if the slice already contains values, set those instead of the interface slice itself.
|
||||||
if value.Len() > 0 {
|
if value.Len() > 0 {
|
||||||
if len(method.Outputs) > value.Len() {
|
if len(args) > value.Len() {
|
||||||
return fmt.Errorf("abi: cannot marshal in to slices of unequal size (require: %v, got: %v)", len(method.Outputs), value.Len())
|
return fmt.Errorf("abi: cannot marshal in to slices of unequal size (require: %v, got: %v)", len(args), value.Len())
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < len(method.Outputs); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
marshalledValue, err := toGoType(i, method.Outputs[i], output)
|
marshalledValue, err := toGoType(i, args[i], output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
reflectValue := reflect.ValueOf(marshalledValue)
|
reflectValue := reflect.ValueOf(marshalledValue)
|
||||||
if err := set(value.Index(i).Elem(), reflectValue, method.Outputs[i]); err != nil {
|
if err := set(value.Index(i).Elem(), reflectValue, args[i]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -297,9 +307,9 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
||||||
|
|
||||||
// create a new slice and start appending the unmarshalled
|
// create a new slice and start appending the unmarshalled
|
||||||
// values to the new interface slice.
|
// values to the new interface slice.
|
||||||
z := reflect.MakeSlice(typ, 0, len(method.Outputs))
|
z := reflect.MakeSlice(typ, 0, len(args))
|
||||||
for i := 0; i < len(method.Outputs); i++ {
|
for i := 0; i < len(args); i++ {
|
||||||
marshalledValue, err := toGoType(i, method.Outputs[i], output)
|
marshalledValue, err := toGoType(i, args[i], output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -311,11 +321,11 @@ func (abi ABI) Unpack(v interface{}, name string, output []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
marshalledValue, err := toGoType(0, method.Outputs[0], output)
|
marshalledValue, err := toGoType(0, args[0], output)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := set(value, reflect.ValueOf(marshalledValue), method.Outputs[0]); err != nil {
|
if err := set(value, reflect.ValueOf(marshalledValue), args[0]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue