Skip to content

Commit cf9e836

Browse files
committed
Support signatures with parameter names
1 parent 1816cdc commit cf9e836

File tree

1 file changed

+28
-32
lines changed

1 file changed

+28
-32
lines changed

accounts/abi/selector_parser.go

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,9 @@
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-
171
package abi
182

193
import (
204
"errors"
215
"fmt"
6+
"strings"
227
)
238

249
type SelectorMarshaling struct {
@@ -32,7 +17,7 @@ func isDigit(c byte) bool {
3217
}
3318

3419
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 == ' ')
3621
}
3722

3823
func 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

Comments
 (0)