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
-
17
1
package abi
18
2
19
3
import (
20
4
"errors"
21
5
"fmt"
6
+ "strings"
22
7
)
23
8
24
9
type SelectorMarshaling struct {
@@ -32,7 +17,7 @@ func isDigit(c byte) bool {
32
17
}
33
18
34
19
func 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 == ' ' )
36
21
}
37
22
38
23
func isIdentifierSymbol (c byte ) bool {
@@ -62,8 +47,8 @@ func parseIdentifier(unescapedSelector string) (string, string, error) {
62
47
return parseToken (unescapedSelector , true )
63
48
}
64
49
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 )
67
52
if err != nil {
68
53
return "" , "" , fmt .Errorf ("failed to parse elementary type: %v" , err )
69
54
}
@@ -84,15 +69,16 @@ func parseElementaryType(unescapedSelector string) (string, string, error) {
84
69
return parsedType , rest , nil
85
70
}
86
71
87
- func parseCompositeType (unescapedSelector string ) ([]interface {}, string , error ) {
72
+ func parseCompositeType (unescapedSelector string ) (result []interface {}, rest string , err error ) {
88
73
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 )
90
75
}
91
- parsedType , rest , err := parseType (unescapedSelector [1 :])
76
+ var parsedType interface {}
77
+ parsedType , rest , err = parseType (unescapedSelector [1 :])
92
78
if err != nil {
93
79
return nil , "" , fmt .Errorf ("failed to parse type: %v" , err )
94
80
}
95
- result : = []interface {}{parsedType }
81
+ result = []interface {}{parsedType }
96
82
for len (rest ) > 0 && rest [0 ] != ')' {
97
83
parsedType , rest , err = parseType (rest [1 :])
98
84
if err != nil {
@@ -120,15 +106,23 @@ func parseType(unescapedSelector string) (interface{}, string, error) {
120
106
}
121
107
}
122
108
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 )
125
111
for i , arg := range args {
126
112
// generate dummy name to avoid unmarshal issues
127
113
name := fmt .Sprintf ("name%d" , i )
128
114
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 })
130
123
} else if components , ok := arg .([]interface {}); ok {
131
- subArgs , err := assembleArgs (components )
124
+ var subArgs []ArgumentMarshaling
125
+ subArgs , err = assembleArgs (components )
132
126
if err != nil {
133
127
return nil , fmt .Errorf ("failed to assemble components: %v" , err )
134
128
}
@@ -137,7 +131,7 @@ func assembleArgs(args []interface{}) ([]ArgumentMarshaling, error) {
137
131
subArgs = subArgs [:len (subArgs )- 1 ]
138
132
tupleType = "tuple[]"
139
133
}
140
- arguments = append (arguments , ArgumentMarshaling {name , tupleType , tupleType , subArgs , false })
134
+ arguments = append (arguments , ArgumentMarshaling {Name : name , Type : tupleType , InternalType : tupleType , Components : subArgs })
141
135
} else {
142
136
return nil , fmt .Errorf ("failed to assemble args: unexpected type %T" , arg )
143
137
}
@@ -149,12 +143,13 @@ func assembleArgs(args []interface{}) ([]ArgumentMarshaling, error) {
149
143
// and consumed by other functions in this package.
150
144
// Note, although uppercase letters are not part of the ABI spec, this function
151
145
// 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 )
154
149
if err != nil {
155
150
return SelectorMarshaling {}, fmt .Errorf ("failed to parse selector '%s': %v" , unescapedSelector , err )
156
151
}
157
- args := []interface {}{}
152
+ args := make ( []interface {}, 0 )
158
153
if len (rest ) >= 2 && rest [0 ] == '(' && rest [1 ] == ')' {
159
154
rest = rest [2 :]
160
155
} else {
@@ -168,7 +163,8 @@ func ParseSelector(unescapedSelector string) (SelectorMarshaling, error) {
168
163
}
169
164
170
165
// Reassemble the fake ABI and construct the JSON
171
- fakeArgs , err := assembleArgs (args )
166
+ var fakeArgs []ArgumentMarshaling
167
+ fakeArgs , err = assembleArgs (args )
172
168
if err != nil {
173
169
return SelectorMarshaling {}, fmt .Errorf ("failed to parse selector: %v" , err )
174
170
}
0 commit comments