1- // Copyright 2022 The go-ethereum Authors
2- // This file is part of the go-ethereum library.
3- //
4- // The go-ethereum library is free software: you can redistribute it and/or modify
5- // it under the terms of the GNU Lesser General Public License as published by
6- // the Free Software Foundation, either version 3 of the License, or
7- // (at your option) any later version.
8- //
9- // The go-ethereum library is distributed in the hope that it will be useful,
10- // but WITHOUT ANY WARRANTY; without even the implied warranty of
11- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12- // GNU Lesser General Public License for more details.
13- //
14- // You should have received a copy of the GNU Lesser General Public License
15- // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
16-
171package abi
182
193import (
204 "errors"
215 "fmt"
6+ "strings"
227)
238
249type SelectorMarshaling struct {
@@ -32,7 +17,7 @@ func isDigit(c byte) bool {
3217}
3318
3419func isAlpha (c byte ) bool {
35- return (c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' )
20+ return (c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' ) || ( c == ' ' )
3621}
3722
3823func isIdentifierSymbol (c byte ) bool {
@@ -62,8 +47,8 @@ func parseIdentifier(unescapedSelector string) (string, string, error) {
6247 return parseToken (unescapedSelector , true )
6348}
6449
65- func parseElementaryType (unescapedSelector string ) (string , string , error ) {
66- parsedType , rest , err : = parseToken (unescapedSelector , false )
50+ func parseElementaryType (unescapedSelector string ) (parsedType string , rest string , err error ) {
51+ parsedType , rest , err = parseToken (unescapedSelector , false )
6752 if err != nil {
6853 return "" , "" , fmt .Errorf ("failed to parse elementary type: %v" , err )
6954 }
@@ -84,15 +69,16 @@ func parseElementaryType(unescapedSelector string) (string, string, error) {
8469 return parsedType , rest , nil
8570}
8671
87- func parseCompositeType (unescapedSelector string ) ([]interface {}, string , error ) {
72+ func parseCompositeType (unescapedSelector string ) (result []interface {}, rest string , err error ) {
8873 if len (unescapedSelector ) == 0 || unescapedSelector [0 ] != '(' {
89- return nil , "" , fmt .Errorf ("expected '(', got %c " , unescapedSelector [ 0 ] )
74+ return nil , "" , fmt .Errorf ("expected '(... ', got %s " , unescapedSelector )
9075 }
91- parsedType , rest , err := parseType (unescapedSelector [1 :])
76+ var parsedType interface {}
77+ parsedType , rest , err = parseType (unescapedSelector [1 :])
9278 if err != nil {
9379 return nil , "" , fmt .Errorf ("failed to parse type: %v" , err )
9480 }
95- result : = []interface {}{parsedType }
81+ result = []interface {}{parsedType }
9682 for len (rest ) > 0 && rest [0 ] != ')' {
9783 parsedType , rest , err = parseType (rest [1 :])
9884 if err != nil {
@@ -120,15 +106,23 @@ func parseType(unescapedSelector string) (interface{}, string, error) {
120106 }
121107}
122108
123- func assembleArgs (args []interface {}) ([]ArgumentMarshaling , error ) {
124- arguments : = make ([]ArgumentMarshaling , 0 )
109+ func assembleArgs (args []interface {}) (arguments []ArgumentMarshaling , err error ) {
110+ arguments = make ([]ArgumentMarshaling , 0 )
125111 for i , arg := range args {
126112 // generate dummy name to avoid unmarshal issues
127113 name := fmt .Sprintf ("name%d" , i )
128114 if s , ok := arg .(string ); ok {
129- arguments = append (arguments , ArgumentMarshaling {name , s , s , nil , false })
115+ parts := strings .Split (s , " " )
116+ if len (parts ) > 2 {
117+ return nil , fmt .Errorf ("more than 2 spaces in type declaration in selector %s" , s )
118+ } else if len (parts ) == 2 {
119+ name = parts [0 ]
120+ s = parts [1 ]
121+ }
122+ arguments = append (arguments , ArgumentMarshaling {Name : name , Type : s , InternalType : s })
130123 } else if components , ok := arg .([]interface {}); ok {
131- subArgs , err := assembleArgs (components )
124+ var subArgs []ArgumentMarshaling
125+ subArgs , err = assembleArgs (components )
132126 if err != nil {
133127 return nil , fmt .Errorf ("failed to assemble components: %v" , err )
134128 }
@@ -137,7 +131,7 @@ func assembleArgs(args []interface{}) ([]ArgumentMarshaling, error) {
137131 subArgs = subArgs [:len (subArgs )- 1 ]
138132 tupleType = "tuple[]"
139133 }
140- arguments = append (arguments , ArgumentMarshaling {name , tupleType , tupleType , subArgs , false })
134+ arguments = append (arguments , ArgumentMarshaling {Name : name , Type : tupleType , InternalType : tupleType , Components : subArgs })
141135 } else {
142136 return nil , fmt .Errorf ("failed to assemble args: unexpected type %T" , arg )
143137 }
@@ -149,12 +143,13 @@ func assembleArgs(args []interface{}) ([]ArgumentMarshaling, error) {
149143// and consumed by other functions in this package.
150144// Note, although uppercase letters are not part of the ABI spec, this function
151145// still accepts it as the general format is valid.
152- func ParseSelector (unescapedSelector string ) (SelectorMarshaling , error ) {
153- name , rest , err := parseIdentifier (unescapedSelector )
146+ func ParseSelector (unescapedSelector string ) (m SelectorMarshaling , err error ) {
147+ var name , rest string
148+ name , rest , err = parseIdentifier (unescapedSelector )
154149 if err != nil {
155150 return SelectorMarshaling {}, fmt .Errorf ("failed to parse selector '%s': %v" , unescapedSelector , err )
156151 }
157- args := []interface {}{}
152+ args := make ( []interface {}, 0 )
158153 if len (rest ) >= 2 && rest [0 ] == '(' && rest [1 ] == ')' {
159154 rest = rest [2 :]
160155 } else {
@@ -168,7 +163,8 @@ func ParseSelector(unescapedSelector string) (SelectorMarshaling, error) {
168163 }
169164
170165 // Reassemble the fake ABI and construct the JSON
171- fakeArgs , err := assembleArgs (args )
166+ var fakeArgs []ArgumentMarshaling
167+ fakeArgs , err = assembleArgs (args )
172168 if err != nil {
173169 return SelectorMarshaling {}, fmt .Errorf ("failed to parse selector: %v" , err )
174170 }
0 commit comments