accounts/abi: fix test

This commit is contained in:
mmsqe 2026-01-15 19:58:05 +08:00
parent 7fddaecfd9
commit 47d937b3f1
No known key found for this signature in database
GPG key ID: 1D6409A9D4025709
2 changed files with 30 additions and 15 deletions

View file

@ -22,6 +22,7 @@ import (
"strings" "strings"
) )
// SelectorMarshaling represents a parsed function signature with its components.
type SelectorMarshaling struct { type SelectorMarshaling struct {
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
@ -31,6 +32,7 @@ type SelectorMarshaling struct {
Anonymous bool `json:"anonymous,omitempty"` Anonymous bool `json:"anonymous,omitempty"`
} }
// EventMarshaling represents a parsed event signature.
type EventMarshaling struct { type EventMarshaling struct {
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
@ -38,16 +40,27 @@ type EventMarshaling struct {
Anonymous bool `json:"anonymous"` Anonymous bool `json:"anonymous"`
} }
// ErrorMarshaling represents a parsed error signature.
type ErrorMarshaling struct { type ErrorMarshaling struct {
Name string `json:"name"` Name string `json:"name"`
Type string `json:"type"` Type string `json:"type"`
Inputs []ArgumentMarshaling `json:"inputs"` Inputs []ArgumentMarshaling `json:"inputs"`
} }
// ABIMarshaling is a union type that can represent any ABI element // ABIMarshaling is a union type that can represent any ABI element.
type ABIMarshaling map[string]interface{} // It stores the parsed ABI fields such as "name", "type", "inputs", "outputs",
// "stateMutability", and "anonymous" as key-value pairs.
type ABIMarshaling map[string]any
// ParseHumanReadableABI parses a human-readable ABI signature into a JSON-compatible map // ParseHumanReadableABI parses a human-readable ABI signature into a JSON-compatible map.
// It supports functions, events, errors, constructors, fallback, and receive functions.
//
// Examples:
//
// "function transfer(address to, uint256 amount)"
// "function balanceOf(address) view returns (uint256)"
// "event Transfer(address indexed from, address indexed to, uint256 value)"
// "constructor(address owner) payable"
func ParseHumanReadableABI(signature string) (ABIMarshaling, error) { func ParseHumanReadableABI(signature string) (ABIMarshaling, error) {
signature = skipWhitespace(signature) signature = skipWhitespace(signature)
@ -284,7 +297,8 @@ func parseTupleType(params string) ([]ArgumentMarshaling, string, string, error)
components = append(components, component) components = append(components, component)
rest = skipWhitespace(rest) rest = skipWhitespace(rest)
if rest[0] == ')' { switch rest[0] {
case ')':
rest = rest[1:] rest = rest[1:]
arraySuffix := "" arraySuffix := ""
for len(rest) > 0 && rest[0] == '[' { for len(rest) > 0 && rest[0] == '[' {
@ -299,10 +313,10 @@ func parseTupleType(params string) ([]ArgumentMarshaling, string, string, error)
rest = rest[endBracket+1:] rest = rest[endBracket+1:]
} }
return components, arraySuffix, rest, nil return components, arraySuffix, rest, nil
} else if rest[0] == ',' { case ',':
rest = rest[1:] rest = rest[1:]
paramIndex++ paramIndex++
} else { default:
return nil, "", rest, fmt.Errorf("expected ',' or ')' in tuple, got '%c'", rest[0]) return nil, "", rest, fmt.Errorf("expected ',' or ')' in tuple, got '%c'", rest[0])
} }
} }
@ -318,6 +332,7 @@ func parseParameterList(params string, allowIndexed bool) ([]ArgumentMarshaling,
var arguments []ArgumentMarshaling var arguments []ArgumentMarshaling
paramIndex := 0 paramIndex := 0
loop:
for params != "" { for params != "" {
params = skipWhitespace(params) params = skipWhitespace(params)
@ -389,12 +404,13 @@ func parseParameterList(params string, allowIndexed bool) ([]ArgumentMarshaling,
if rest == "" { if rest == "" {
break break
} }
if rest[0] == ',' { switch rest[0] {
case ',':
rest = rest[1:] rest = rest[1:]
params = rest params = rest
paramIndex++ paramIndex++
} else { default:
break break loop
} }
} }
@ -554,8 +570,7 @@ func ParseConstructor(signature string) (ABIMarshaling, error) {
return result, nil return result, nil
} }
// ParseFallback parses a fallback function signature // ParseFallback parses a fallback function signature (no parameters allowed).
// ParseFallback parses a fallback function signature (no parameters allowed)
func ParseFallback(signature string) (ABIMarshaling, error) { func ParseFallback(signature string) (ABIMarshaling, error) {
signature = skipWhitespace(signature) signature = skipWhitespace(signature)

View file

@ -28,13 +28,13 @@ func TestParseSelector(t *testing.T) {
mkType := func(types ...interface{}) []ArgumentMarshaling { mkType := func(types ...interface{}) []ArgumentMarshaling {
var result []ArgumentMarshaling var result []ArgumentMarshaling
for i, typeOrComponents := range types { for i, typeOrComponents := range types {
name := fmt.Sprintf("name%d", i) name := fmt.Sprintf("param%d", i)
if typeName, ok := typeOrComponents.(string); ok { if typeName, ok := typeOrComponents.(string); ok {
result = append(result, ArgumentMarshaling{name, typeName, typeName, nil, false}) result = append(result, ArgumentMarshaling{name, typeName, "", nil, false})
} else if components, ok := typeOrComponents.([]ArgumentMarshaling); ok { } else if components, ok := typeOrComponents.([]ArgumentMarshaling); ok {
result = append(result, ArgumentMarshaling{name, "tuple", "tuple", components, false}) result = append(result, ArgumentMarshaling{name, "tuple", "", components, false})
} else if components, ok := typeOrComponents.([][]ArgumentMarshaling); ok { } else if components, ok := typeOrComponents.([][]ArgumentMarshaling); ok {
result = append(result, ArgumentMarshaling{name, "tuple[]", "tuple[]", components[0], false}) result = append(result, ArgumentMarshaling{name, "tuple[]", "", components[0], false})
} else { } else {
log.Fatalf("unexpected type %T", typeOrComponents) log.Fatalf("unexpected type %T", typeOrComponents)
} }