From 22695b1a1c92a34e9e0b5b95a88d5c1090bd29b5 Mon Sep 17 00:00:00 2001 From: luka-ciric-ethernal Date: Fri, 18 Oct 2024 13:02:39 +0200 Subject: [PATCH] Refactor ABI parsing to use compiler.IOField instead of custom ArgumentStr struct --- abi/abi.go | 48 ++++++++++----------------------------- abi/encoding_test.go | 12 +++++----- abi/type.go | 13 ++++++----- abi/type_test.go | 45 ++++++++++++++++++------------------ compiler/solidity.go | 24 ++++++++++---------- compiler/solidity_test.go | 2 +- 6 files changed, 61 insertions(+), 83 deletions(-) diff --git a/abi/abi.go b/abi/abi.go index 349b7d28..542cdf2d 100644 --- a/abi/abi.go +++ b/abi/abi.go @@ -88,21 +88,6 @@ func NewABI(s string) (*ABI, error) { return NewABIFromReader(bytes.NewReader([]byte(s))) } -func toArgStr(args []compiler.IOField) []*ArgumentStr { - res := make([]*ArgumentStr, len(args)) - for i, arg := range args { - res[i] = &ArgumentStr{ - Name: arg.Name, - Type: arg.Type, - Indexed: arg.Indexed, - Components: toArgStr(arg.Components), - InternalType: arg.InternalType, - } - } - - return res -} - func NewABIFromSlice(abi []compiler.AbiField) (*ABI, error) { a := &ABI{} @@ -112,7 +97,7 @@ func NewABIFromSlice(abi []compiler.AbiField) (*ABI, error) { if a.Constructor != nil { return nil, fmt.Errorf("multiple constructor declaration") } - input, err := NewTupleTypeFromArgs(toArgStr(field.Inputs)) + input, err := NewTupleTypeFromFields(field.Inputs) if err != nil { panic(err) } @@ -126,11 +111,11 @@ func NewABIFromSlice(abi []compiler.AbiField) (*ABI, error) { c = true } - inputs, err := NewTupleTypeFromArgs(toArgStr(field.Inputs)) + inputs, err := NewTupleTypeFromFields(field.Inputs) if err != nil { panic(err) } - outputs, err := NewTupleTypeFromArgs(toArgStr(field.Outputs)) + outputs, err := NewTupleTypeFromFields(field.Outputs) if err != nil { panic(err) } @@ -143,7 +128,7 @@ func NewABIFromSlice(abi []compiler.AbiField) (*ABI, error) { a.addMethod(method) case "event": - input, err := NewTupleTypeFromArgs(toArgStr(field.Inputs)) + input, err := NewTupleTypeFromFields(field.Inputs) if err != nil { panic(err) } @@ -155,7 +140,7 @@ func NewABIFromSlice(abi []compiler.AbiField) (*ABI, error) { a.addEvent(event) case "error": - input, err := NewTupleTypeFromArgs(toArgStr(field.Inputs)) + input, err := NewTupleTypeFromFields(field.Inputs) if err != nil { panic(err) } @@ -203,8 +188,8 @@ func (a *ABI) UnmarshalJSON(data []byte) error { Constant bool Anonymous bool StateMutability string - Inputs []*ArgumentStr - Outputs []*ArgumentStr + Inputs []*compiler.IOField + Outputs []*compiler.IOField } if err := json.Unmarshal(data, &fields); err != nil { @@ -217,7 +202,7 @@ func (a *ABI) UnmarshalJSON(data []byte) error { if a.Constructor != nil { return fmt.Errorf("multiple constructor declaration") } - input, err := NewTupleTypeFromArgs(field.Inputs) + input, err := NewTupleTypeFromFields(field.Inputs) if err != nil { panic(err) } @@ -231,11 +216,11 @@ func (a *ABI) UnmarshalJSON(data []byte) error { c = true } - inputs, err := NewTupleTypeFromArgs(field.Inputs) + inputs, err := NewTupleTypeFromFields(field.Inputs) if err != nil { panic(err) } - outputs, err := NewTupleTypeFromArgs(field.Outputs) + outputs, err := NewTupleTypeFromFields(field.Outputs) if err != nil { panic(err) } @@ -248,7 +233,7 @@ func (a *ABI) UnmarshalJSON(data []byte) error { a.addMethod(method) case "event": - input, err := NewTupleTypeFromArgs(field.Inputs) + input, err := NewTupleTypeFromFields(field.Inputs) if err != nil { panic(err) } @@ -260,7 +245,7 @@ func (a *ABI) UnmarshalJSON(data []byte) error { a.addEvent(event) case "error": - input, err := NewTupleTypeFromArgs(field.Inputs) + input, err := NewTupleTypeFromFields(field.Inputs) if err != nil { panic(err) } @@ -497,15 +482,6 @@ func buildSignature(name string, typ *Type) string { return fmt.Sprintf("%v(%v)", name, strings.Join(types, ",")) } -// ArgumentStr encodes a type object -type ArgumentStr struct { - Name string - Type string - Indexed bool - Components []*ArgumentStr - InternalType string -} - var keccakPool = sync.Pool{ New: func() interface{} { return sha3.NewLegacyKeccak256() diff --git a/abi/encoding_test.go b/abi/encoding_test.go index cfa7e7c1..d7a181eb 100644 --- a/abi/encoding_test.go +++ b/abi/encoding_test.go @@ -504,13 +504,13 @@ func TestEncodingBestEffort(t *testing.T) { func TestEncodingArguments(t *testing.T) { cases := []struct { - Arg *ArgumentStr + Arg *compiler.IOField Input interface{} }{ { - &ArgumentStr{ + &compiler.IOField{ Type: "tuple", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Name: "", Type: "int32", @@ -527,9 +527,9 @@ func TestEncodingArguments(t *testing.T) { }, }, { - &ArgumentStr{ + &compiler.IOField{ Type: "tuple", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Name: "a", Type: "int32", @@ -551,7 +551,7 @@ func TestEncodingArguments(t *testing.T) { for _, c := range cases { t.Run("", func(t *testing.T) { - tt, err := NewTypeFromArgument(c.Arg) + tt, err := NewTypeFromField(c.Arg) if err != nil { t.Fatal(err) } diff --git a/abi/type.go b/abi/type.go index 221278a5..b7e458ad 100644 --- a/abi/type.go +++ b/abi/type.go @@ -9,6 +9,7 @@ import ( "strings" "github.com/Ethernal-Tech/ethgo" + "github.com/Ethernal-Tech/ethgo/compiler" ) // batch of predefined reflect types @@ -115,10 +116,10 @@ func NewTupleType(inputs []*TupleElem) *Type { } } -func NewTupleTypeFromArgs(inputs []*ArgumentStr) (*Type, error) { +func NewTupleTypeFromFields(inputs []*compiler.IOField) (*Type, error) { elems := []*TupleElem{} for _, i := range inputs { - typ, err := NewTypeFromArgument(i) + typ, err := NewTypeFromField(i) if err != nil { return nil, err } @@ -255,7 +256,7 @@ func (t *Type) isDynamicType() bool { return t.kind == KindString || t.kind == KindBytes || t.kind == KindSlice || (t.kind == KindArray && t.elem.isDynamicType()) } -func parseType(arg *ArgumentStr) (string, error) { +func parseType(arg *compiler.IOField) (string, error) { if !strings.HasPrefix(arg.Type, "tuple") { return arg.Type, nil } @@ -280,8 +281,8 @@ func parseType(arg *ArgumentStr) (string, error) { return fmt.Sprintf("tuple(%s)%s", strings.Join(str, ","), strings.TrimPrefix(arg.Type, "tuple")), nil } -// NewTypeFromArgument parses an abi type from an argument -func NewTypeFromArgument(arg *ArgumentStr) (*Type, error) { +// NewTypeFromField parses an abi type from an argument +func NewTypeFromField(arg *compiler.IOField) (*Type, error) { str, err := parseType(arg) if err != nil { return nil, err @@ -299,7 +300,7 @@ func NewTypeFromArgument(arg *ArgumentStr) (*Type, error) { return typ, nil } -func fillIn(typ *Type, arg *ArgumentStr) error { +func fillIn(typ *Type, arg *compiler.IOField) error { typ.itype = arg.InternalType if len(arg.Components) == 0 { diff --git a/abi/type_test.go b/abi/type_test.go index d9865c4c..d3c92a48 100644 --- a/abi/type_test.go +++ b/abi/type_test.go @@ -4,6 +4,7 @@ import ( "reflect" "testing" + "github.com/Ethernal-Tech/ethgo/compiler" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -11,7 +12,7 @@ import ( func TestType(t *testing.T) { cases := []struct { s string - a *ArgumentStr + a *compiler.IOField t *Type r string err bool @@ -111,9 +112,9 @@ func TestType(t *testing.T) { }, { s: "tuple(int64 indexed arg0)", - a: &ArgumentStr{ + a: &compiler.IOField{ Type: "tuple", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Name: "arg0", Type: "int64", @@ -139,9 +140,9 @@ func TestType(t *testing.T) { }, { s: "tuple(int64 arg_0)[2]", - a: &ArgumentStr{ + a: &compiler.IOField{ Type: "tuple[2]", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Name: "arg_0", Type: "int64", @@ -170,9 +171,9 @@ func TestType(t *testing.T) { }, { s: "tuple(int64 a)[]", - a: &ArgumentStr{ + a: &compiler.IOField{ Type: "tuple[]", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Name: "a", Type: "int64", @@ -200,9 +201,9 @@ func TestType(t *testing.T) { }, { s: "tuple(int32 indexed arg0,tuple(int32 c) b_2)", - a: &ArgumentStr{ + a: &compiler.IOField{ Type: "tuple", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Name: "arg0", Type: "int32", @@ -211,7 +212,7 @@ func TestType(t *testing.T) { { Name: "b_2", Type: "tuple", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Name: "c", Type: "int32", @@ -255,9 +256,9 @@ func TestType(t *testing.T) { }, { s: "tuple()", - a: &ArgumentStr{ + a: &compiler.IOField{ Type: "tuple", - Components: []*ArgumentStr{}, + Components: []*compiler.IOField{}, }, t: &Type{ kind: KindTuple, @@ -268,12 +269,12 @@ func TestType(t *testing.T) { { // hidden tuple token s: "tuple((int32))", - a: &ArgumentStr{ + a: &compiler.IOField{ Type: "tuple", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Type: "tuple", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Type: "int32", }, @@ -344,7 +345,7 @@ func TestType(t *testing.T) { } assert.Equal(t, expected, e0.Format(true)) - e1, err := NewTypeFromArgument(c.a) + e1, err := NewTypeFromField(c.a) if err != nil { t.Fatal(err) } @@ -365,12 +366,12 @@ func TestType(t *testing.T) { } func TestTypeArgument_InternalFields(t *testing.T) { - arg := &ArgumentStr{ + arg := &compiler.IOField{ Type: "tuple", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Type: "tuple[]", - Components: []*ArgumentStr{ + Components: []*compiler.IOField{ { Type: "int32", InternalType: "c", @@ -381,7 +382,7 @@ func TestTypeArgument_InternalFields(t *testing.T) { }, } - res, err := NewTypeFromArgument(arg) + res, err := NewTypeFromField(arg) require.NoError(t, err) require.Equal(t, res.tuple[0].Elem.itype, "b") @@ -432,8 +433,8 @@ func TestSize(t *testing.T) { } } -func simpleType(s string) *ArgumentStr { - return &ArgumentStr{ +func simpleType(s string) *compiler.IOField { + return &compiler.IOField{ Type: s, } } diff --git a/compiler/solidity.go b/compiler/solidity.go index 38b0ce68..d0c65f08 100644 --- a/compiler/solidity.go +++ b/compiler/solidity.go @@ -24,21 +24,21 @@ type Source struct { } type IOField struct { - Name string `json:"name"` - Type string `json:"type"` - Indexed bool `json:"indexed"` - Components []IOField `json:"components"` - InternalType string `json:"internalType"` + Name string `json:"name"` + Type string `json:"type"` + Indexed bool `json:"indexed"` + Components []*IOField `json:"components"` + InternalType string `json:"internalType"` } type AbiField struct { - Type string `json:"type"` - Name string `json:"name"` - Inputs []IOField `json:"inputs"` - Outputs []IOField `json:"outputs"` - StateMutability string `json:"stateMutability"` - Anonymous bool `json:"anonymous"` - Constant bool `json:"constant"` + Type string `json:"type"` + Name string `json:"name"` + Inputs []*IOField `json:"inputs"` + Outputs []*IOField `json:"outputs"` + StateMutability string `json:"stateMutability"` + Anonymous bool `json:"anonymous"` + Constant bool `json:"constant"` } type Artifact struct { diff --git a/compiler/solidity_test.go b/compiler/solidity_test.go index ab6756f1..1e5f5209 100644 --- a/compiler/solidity_test.go +++ b/compiler/solidity_test.go @@ -19,7 +19,7 @@ var ( ) func init() { - _, err := os.Stat(solcDir) + _, err := os.Stat(solcPath) if err == nil { // already exists return