|
|
|
@ -85,7 +85,7 @@ var selectorRegexp = regexp.MustCompile(`^([^\)]+)\(([A-Za-z0-9,\[\]]*)\)`) |
|
|
|
|
|
|
|
|
|
// parseSelector converts a method selector into an ABI JSON spec. The returned
|
|
|
|
|
// data is a valid JSON string which can be consumed by the standard abi package.
|
|
|
|
|
func parseSelector(selector string) ([]byte, error) { |
|
|
|
|
func parseSelector(unescapedSelector string) ([]byte, error) { |
|
|
|
|
// Define a tiny fake ABI struct for JSON marshalling
|
|
|
|
|
type fakeArg struct { |
|
|
|
|
Type string `json:"type"` |
|
|
|
@ -95,10 +95,10 @@ func parseSelector(selector string) ([]byte, error) { |
|
|
|
|
Type string `json:"type"` |
|
|
|
|
Inputs []fakeArg `json:"inputs"` |
|
|
|
|
} |
|
|
|
|
// Validate the selector and extract it's components
|
|
|
|
|
groups := selectorRegexp.FindStringSubmatch(selector) |
|
|
|
|
// Validate the unescapedSelector and extract it's components
|
|
|
|
|
groups := selectorRegexp.FindStringSubmatch(unescapedSelector) |
|
|
|
|
if len(groups) != 3 { |
|
|
|
|
return nil, fmt.Errorf("invalid selector %s (%v matches)", selector, len(groups)) |
|
|
|
|
return nil, fmt.Errorf("invalid selector %q (%v matches)", unescapedSelector, len(groups)) |
|
|
|
|
} |
|
|
|
|
name := groups[1] |
|
|
|
|
args := groups[2] |
|
|
|
@ -115,7 +115,7 @@ func parseSelector(selector string) ([]byte, error) { |
|
|
|
|
|
|
|
|
|
// parseCallData matches the provided call data against the ABI definition and
|
|
|
|
|
// returns a struct containing the actual go-typed values.
|
|
|
|
|
func parseCallData(calldata []byte, abidata string) (*decodedCallData, error) { |
|
|
|
|
func parseCallData(calldata []byte, unescapedAbidata string) (*decodedCallData, error) { |
|
|
|
|
// Validate the call data that it has the 4byte prefix and the rest divisible by 32 bytes
|
|
|
|
|
if len(calldata) < 4 { |
|
|
|
|
return nil, fmt.Errorf("invalid call data, incomplete method signature (%d bytes < 4)", len(calldata)) |
|
|
|
@ -127,9 +127,9 @@ func parseCallData(calldata []byte, abidata string) (*decodedCallData, error) { |
|
|
|
|
return nil, fmt.Errorf("invalid call data; length should be a multiple of 32 bytes (was %d)", len(argdata)) |
|
|
|
|
} |
|
|
|
|
// Validate the called method and upack the call data accordingly
|
|
|
|
|
abispec, err := abi.JSON(strings.NewReader(abidata)) |
|
|
|
|
abispec, err := abi.JSON(strings.NewReader(unescapedAbidata)) |
|
|
|
|
if err != nil { |
|
|
|
|
return nil, fmt.Errorf("invalid method signature (%s): %v", abidata, err) |
|
|
|
|
return nil, fmt.Errorf("invalid method signature (%q): %v", unescapedAbidata, err) |
|
|
|
|
} |
|
|
|
|
method, err := abispec.MethodById(sigdata) |
|
|
|
|
if err != nil { |
|
|
|
|