diff --git a/execution/evm/abi/abi.go b/execution/evm/abi/abi.go index 627f2e19d..2c2e990dc 100644 --- a/execution/evm/abi/abi.go +++ b/execution/evm/abi/abi.go @@ -846,6 +846,9 @@ func readArgSpec(argsJ []ArgumentJSON) ([]Argument, error) { args[i].EVM = EVMBytes{M: 0} case "string": args[i].EVM = EVMString{} + default: + // Assume it is a type of Contract + args[i].EVM = EVMAddress{} } } @@ -856,7 +859,15 @@ func ReadAbiSpec(specBytes []byte) (*AbiSpec, error) { var specJ []AbiSpecJSON err := json.Unmarshal(specBytes, &specJ) if err != nil { - return nil, err + // The abi spec file might a bin file, with the Abi under the Abi field in json + var binFile struct { + Abi []AbiSpecJSON + } + err = json.Unmarshal(specBytes, &binFile) + if err != nil { + return nil, err + } + specJ = binFile.Abi } abiSpec := AbiSpec{ @@ -919,6 +930,32 @@ func ReadAbiSpecFile(filename string) (*AbiSpec, error) { return ReadAbiSpec(specBytes) } +// MergeAbiSpec takes multiple AbiSpecs and merges them into once structure. Note that +// the same function name or event name can occur in different abis, so there might be +// some information loss. +func MergeAbiSpec(abiSpec []*AbiSpec) *AbiSpec { + newSpec := AbiSpec{ + Events: make(map[string]EventSpec), + EventsById: make(map[EventID]EventSpec), + Functions: make(map[string]FunctionSpec), + } + + for _, s := range abiSpec { + for n, f := range s.Functions { + newSpec.Functions[n] = f + } + + // Different Abis can have the Event name, but with a different signature + // Loop over the signatures, as these are less likely to have collisions + for _, e := range s.EventsById { + newSpec.Events[e.Name] = e + newSpec.EventsById[e.EventID] = e + } + } + + return &newSpec +} + func EVMTypeFromReflect(v reflect.Type) Argument { arg := Argument{Name: v.Name()}