diff --git a/ethcoder/events_parser.go b/ethcoder/events_parser.go index 7bb9c04..f99b97e 100644 --- a/ethcoder/events_parser.go +++ b/ethcoder/events_parser.go @@ -10,14 +10,15 @@ type EventDef struct { Name string `json:"name"` // the event name, ie. Transfer Sig string `json:"sig"` // the event sig, ie. Transfer(address,address,uint256) ArgTypes []string `json:"argTypes"` // the event arg types, ie. [address, address, uint256] - ArgNames []string `json:"argNames"` // the event arg names, ie. [from, to, value] or ["","",""] ArgIndexed []bool `json:"argIndexed"` // the event arg indexed flag, ie. [true, false, true] + ArgNames []string `json:"argNames"` // the event arg names, ie. [from, to, value] or ["","",""] } func ParseEventDef(event string) (EventDef, error) { eventDef := EventDef{ - ArgTypes: []string{}, - ArgNames: []string{}, + ArgTypes: []string{}, + ArgIndexed: []bool{}, + ArgNames: []string{}, } var errInvalid = fmt.Errorf("event format is invalid, expecting Method(arg1,arg2,..)") @@ -50,15 +51,18 @@ func ParseEventDef(event string) (EventDef, error) { return eventDef, err } - // TODO ... - argsSig, typs, indexed, _, err := groupEventSelectorTree(tree, true) + sig, typs, indexed, names, err := groupEventSelectorTree(tree, true) if err != nil { return eventDef, err } - eventDef.Sig = fmt.Sprintf("%s(%s)", method, argsSig) + eventDef.Sig = fmt.Sprintf("%s(%s)", method, sig) eventDef.ArgTypes = typs - for i := 0; i < len(typs); i++ { - eventDef.ArgNames = append(eventDef.ArgNames, "") + for i, name := range names { + if name != "" { + eventDef.ArgNames = append(eventDef.ArgNames, name) + } else { + eventDef.ArgNames = append(eventDef.ArgNames, fmt.Sprintf("arg%d", i+1)) + } } eventDef.ArgIndexed = indexed } @@ -69,14 +73,14 @@ func ParseEventDef(event string) (EventDef, error) { } type eventSelectorTree struct { - left string - indexed []bool - names []string - tuple []eventSelectorTree - tupleArray string - // tupleIndexed bool ? - // tupleName string ? .. - right []eventSelectorTree + left string + indexed []bool + names []string + tuple []eventSelectorTree + tupleArray string + tupleIndexed bool + tupleName string + right []eventSelectorTree } // parseEventArgs parses the event arguments and returns a tree structure @@ -84,7 +88,7 @@ type eventSelectorTree struct { func parseEventArgs(eventArgs string, iteration int) (eventSelectorTree, error) { args := strings.TrimSpace(eventArgs) if iteration == 0 { - args = strings.ReplaceAll(eventArgs, " ", "") // ..???? + args = strings.ReplaceAll(eventArgs, " ", "") } out := eventSelectorTree{} @@ -129,28 +133,24 @@ func parseEventArgs(eventArgs string, iteration int) (eventSelectorTree, error) x1 := strings.LastIndex(p2, "]") x2 := strings.LastIndex(p2, ")") xx := max(x1, x2) - // if strings.LastIndex(p2, "indexed") > x1 || strings.LastIndex(p2, "indexed") > x2 { - // p2indexed = true - // } - // fmt.Println("!!!WEEE!", p2) // get indexed/var name from end n := strings.Split(strings.TrimSpace(p2[xx+1:]), " ") - if len(n) == 1 { - p2name = strings.TrimRight(n[0], ",") - } else if len(n) == 2 && n[0] == "indexed" { + n0 := "" + if len(n) > 0 { + n0 = strings.TrimRight(n[0], ",") + } + if len(n) == 1 && n0 != "indexed" { + p2name = n0 + } else if len(n) == 1 && n0 == "indexed" { + p2indexed = true + } else if len(n) == 2 && n0 == "indexed" { p2indexed = true p2name = strings.TrimRight(n[1], ",") } - // spew.Dump(n) // split indexed/var name from end p2 = p2[:xx+1] - // if x1 > x2 { - // p2 = p2[:x1+1] - // } else { - // p2 = p2[:x2+1] - // } // split array from tuple x1 = strings.LastIndex(p2, "]") @@ -183,6 +183,9 @@ func parseEventArgs(eventArgs string, iteration int) (eventSelectorTree, error) p1names = append(p1names, arg[2]) } else if len(arg) == 3 && arg[1] != "indexed" { return out, fmt.Errorf("invalid event indexed argument format") + } else if len(arg) == 2 && arg[1] == "indexed" { + p1indexed = append(p1indexed, true) + p1names = append(p1names, "") } else if len(arg) > 0 && arg[0] != "" { p1indexed = append(p1indexed, false) if len(arg) > 1 { @@ -213,8 +216,8 @@ func parseEventArgs(eventArgs string, iteration int) (eventSelectorTree, error) } out.tuple = append(out.tuple, out2) out.tupleArray = p2ar - out.indexed = append(out.indexed, p2indexed) - out.names = append(out.names, p2name) + out.tupleIndexed = p2indexed + out.tupleName = p2name } // p3 @@ -266,6 +269,8 @@ func groupEventSelectorTree(t eventSelectorTree, include bool) (string, []string b += t.tupleArray if include && b != "" { typs = append(typs, b) + indexed = append(indexed, t.tupleIndexed) + names = append(names, t.tupleName) } for _, child := range t.right { diff --git a/ethcoder/events_parser_test.go b/ethcoder/events_parser_test.go index 45a45ca..2f71e13 100644 --- a/ethcoder/events_parser_test.go +++ b/ethcoder/events_parser_test.go @@ -3,7 +3,6 @@ package ethcoder import ( "testing" - "github.com/davecgh/go-spew/spew" "github.com/stretchr/testify/require" ) @@ -68,19 +67,77 @@ func TestParseEventArgs(t *testing.T) { []bool{false, false, false, false, false, false}, []string{"", "", "", "", "", ""}, }, + + // + // repeat, with no arg names + // + { + "bytes32, address[] indexed, uint256, ( address op, (uint256 val, bytes32 data)), address, (int128 a, int64 b), uint256", + "bytes32,address[],uint256,(address,(uint256,bytes32)),address,(int128,int64),uint256", + []bool{false, true, false, false, false, false, false}, + []string{"", "", "", "", "", "", ""}, + }, + { // its not actually valid selector, but use it for parser testing + "bytes, uint256[2][], ( address yo, uint256[2] no )[2][] indexed, address", + "bytes,uint256[2][],(address,uint256[2])[2][],address", + []bool{false, false, true, false}, + []string{"", "", "", ""}, + }, + { // its not actually valid selector, but use it for parser testing + "address, ( uint256 num, address cool, ( address op, uint256 val )[2] hmm)[][], uint256", + "address,(uint256,address,(address,uint256)[2])[][],uint256", + []bool{false, false, false}, + []string{"", "", ""}, + }, + { + "address,address,uint256", + "address,address,uint256", + []bool{false, false, false}, + []string{"", "", ""}, + }, + { + "bytes32,address,address,((uint32,uint32,uint32,address,address,bool,bytes,uint256,address,uint256,uint256,uint256,bytes32),address[],bytes[],address,bytes),address,uint256,address", + "bytes32,address,address,((uint32,uint32,uint32,address,address,bool,bytes,uint256,address,uint256,uint256,uint256,bytes32),address[],bytes[],address,bytes),address,uint256,address", + []bool{false, false, false, false, false, false, false}, + []string{"", "", "", "", "", "", ""}, + }, + { + "(address,uint256,string,string)", + "(address,uint256,string,string)", + []bool{false}, + []string{""}, + }, + { + "bytes32,address,address,address,(uint8,address,uint256,uint256)[] indexed,(uint8,address,uint256,uint256,address)[]", + "bytes32,address,address,address,(uint8,address,uint256,uint256)[],(uint8,address,uint256,uint256,address)[]", + []bool{false, false, false, false, true, false}, + []string{"", "", "", "", "", ""}, + }, + { + "address,(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address,uint40,uint40)", + "address,(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,address,uint40,uint40)", + []bool{false, false}, + []string{"", ""}, + }, + { + "bytes32,address,address,address,(uint8,address,uint256,uint256)[],(uint8,address,uint256,uint256,address)[]", + "bytes32,address,address,address,(uint8,address,uint256,uint256)[],(uint8,address,uint256,uint256,address)[]", + []bool{false, false, false, false, false, false}, + []string{"", "", "", "", "", ""}, + }, } for _, c := range cases { tree, err := parseEventArgs(c.in, 0) require.NoError(t, err) - spew.Dump(tree) + // spew.Dump(tree) out, typs, indexed, names, err := groupEventSelectorTree(tree, true) require.NoError(t, err) require.Equal(t, c.sig, out) - spew.Dump(typs) - spew.Dump(indexed) - spew.Dump(names) + // spew.Dump(typs) + // spew.Dump(indexed) + // spew.Dump(names) require.Equal(t, len(c.argNames), len(typs)) require.Equal(t, len(c.argNames), len(indexed))