Skip to content

Commit

Permalink
Refactor ABI parsing to use compiler.IOField instead of custom Argume…
Browse files Browse the repository at this point in the history
…ntStr struct
  • Loading branch information
luka-ciric-ethernal committed Oct 18, 2024
1 parent b14808b commit 22695b1
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 83 deletions.
48 changes: 12 additions & 36 deletions abi/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{}

Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand All @@ -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)
}
Expand Down Expand Up @@ -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()
Expand Down
12 changes: 6 additions & 6 deletions abi/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -527,9 +527,9 @@ func TestEncodingArguments(t *testing.T) {
},
},
{
&ArgumentStr{
&compiler.IOField{
Type: "tuple",
Components: []*ArgumentStr{
Components: []*compiler.IOField{
{
Name: "a",
Type: "int32",
Expand All @@ -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)
}
Expand Down
13 changes: 7 additions & 6 deletions abi/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"

"github.com/Ethernal-Tech/ethgo"
"github.com/Ethernal-Tech/ethgo/compiler"
)

// batch of predefined reflect types
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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
}
Expand All @@ -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
Expand All @@ -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 {
Expand Down
45 changes: 23 additions & 22 deletions abi/type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import (
"reflect"
"testing"

"github.com/Ethernal-Tech/ethgo/compiler"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestType(t *testing.T) {
cases := []struct {
s string
a *ArgumentStr
a *compiler.IOField
t *Type
r string
err bool
Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand All @@ -211,7 +212,7 @@ func TestType(t *testing.T) {
{
Name: "b_2",
Type: "tuple",
Components: []*ArgumentStr{
Components: []*compiler.IOField{
{
Name: "c",
Type: "int32",
Expand Down Expand Up @@ -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,
Expand All @@ -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",
},
Expand Down Expand Up @@ -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)
}
Expand All @@ -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",
Expand All @@ -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")
Expand Down Expand Up @@ -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,
}
}
24 changes: 12 additions & 12 deletions compiler/solidity.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading

0 comments on commit 22695b1

Please sign in to comment.