sigparser

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2023 License: MIT Imports: 4 Imported by: 1

README

go-sigparser

The go-sigparser is a Go package that helps parse Ethereum function signatures. This parser uses the Solidity grammar rules.

However, it doesn't need argument names or the returns and function keywords to parse signatures. So, you can use it for both complete Solidity signatures and shorter versions like bar(uint256,bytes32).

Tuples are represented as a list of parameters, e.g. (uint256,bytes32). The list can be optionally prefixed with tuple keyword, e.g. tuple(uint256,bytes32).

The go-sigparser supports many different signature formats. Here are a few examples:

  • getPrice(string)
  • getPrice(string)((uint256,unit256))
  • function getPrice(string calldata symbol) external view returns (tuple(uint256 price, uint256 timestamp) result)
  • constructor(string symbol, string name)
  • receive() external payable
  • fallback (bytes calldata input) external payable returns (bytes memory output)
  • event PriceUpdated(string indexed symbol, uint256 price)
  • error PriceExpired(string symbol, uint256 timestamp)

Installation

You can install the go-sigparser package with this command:

go get github.com/ethereum/go-sigparser

Usage

Parsing Signature
package main

import (
	"fmt"

	"github.com/defiweb/go-sigparser"
)

func main() {
	sig, err := sigparser.ParseSignature("function getPrices(string[] calldata symbols) external view returns ((uint256 price, uint256 timestamp)[] result)")
	if err != nil {
		panic(err)
	}

	fmt.Println(sig.Kind)                     // function
	fmt.Println(sig.Name)                     // getPrice
	fmt.Println(sig.Inputs[0].Name)           // symbol
	fmt.Println(sig.Inputs[0].Type)           // string
	fmt.Println(sig.Inputs[0].Arrays)         // [-1] (-1 means that the array is unbounded)
	fmt.Println(sig.Inputs[0].DataLocation)   // calldata
	fmt.Println(sig.Modifiers)                // [external, view]
	fmt.Println(sig.Outputs[0].Name)          // result
	fmt.Println(sig.Outputs[0].Arrays)        // [-1] 
	fmt.Println(sig.Outputs[0].Tuple[0].Name) // price
	fmt.Println(sig.Outputs[0].Tuple[0].Type) // uint256
	fmt.Println(sig.Outputs[0].Tuple[1].Name) // timestamp
	fmt.Println(sig.Outputs[0].Tuple[1].Type) // uint256
}
Parsing Parameter
package main

import (
	"fmt"

	"github.com/defiweb/go-sigparser"
)

func main() {
	param, err := sigparser.ParseParameter("(uint256 price, uint256 timestamp)")
	if err != nil {
		panic(err)
	}

	fmt.Println(param.Tuple[0].Name) // price
	fmt.Println(param.Tuple[0].Type) // uint256
	fmt.Println(param.Tuple[1].Name) // timestamp
	fmt.Println(param.Tuple[1].Type) // uint256
}
Parsing Struct

You can also parse structs with go-sigparser. When you parse a struct, you get a tuple where the struct name is the parameter name, and the struct fields are the tuple elements. Here's an example:

package main

import (
	"fmt"

	"github.com/defiweb/go-sigparser"
)

func main() {
	param, err := sigparser.ParseStruct("struct name { uint256 price; uint256 timestamp; }")
	if err != nil {
		panic(err)
	}

	fmt.Println(param.Name)          // name
	fmt.Println(param.Tuple[0].Name) // price
	fmt.Println(param.Tuple[0].Type) // uint256
	fmt.Println(param.Tuple[1].Name) // timestamp
	fmt.Println(param.Tuple[1].Type) // uint256
}

Documentation

For more information about the go-sigparser package, visit https://pkg.go.dev/github.com/defiweb/go-sigparser.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type DataLocation

type DataLocation int8

DataLocation is the data location of the parameter, like storage, memory or calldata.

const (
	UnspecifiedLocation DataLocation = iota
	Storage
	CallData
	Memory
)

func (DataLocation) String

func (d DataLocation) String() string

type InputKind added in v0.5.0

type InputKind int8

InputKind is the kind of the input string returned by the Kind function.

const (
	InvalidInput InputKind = iota
	TypeInput
	ArrayInput
	TupleInput
	StructDefinitionInput
	FunctionSignatureInput
	ConstructorSignatureInput
	FallbackSignatureInput
	ReceiveSignatureInput
	EventSignatureInput
	ErrorSignatureInput
)

func Kind added in v0.5.0

func Kind(input string) (k InputKind)

Kind returns the kind of the input string.

This function helps determine which parser should be used to parse the input.

Note that some inputs are ambiguous. They could be interpreted either as a type or a function signature. For example, "foo" could be a type or a function name. Similarly, "function foo" could be interpreted as a function signature or a parameter "foo" with the type "function".

To avoid ambiguity, always add an empty parameter list to function signatures.

func (InputKind) IsParameter added in v0.5.0

func (k InputKind) IsParameter() bool

IsParameter returns true if the input is a parameter.

It can be parsed using ParseParameter function.

func (InputKind) IsSignature added in v0.5.0

func (k InputKind) IsSignature() bool

IsSignature returns true if the input is a signature for any type of function.

It can be parsed using ParseSignature function.

func (InputKind) IsStruct added in v0.5.0

func (k InputKind) IsStruct() bool

IsStruct returns true if the input is a struct definition.

It can be parsed using ParseStruct function.

func (InputKind) String added in v0.5.0

func (k InputKind) String() string

type Parameter

type Parameter struct {
	// Name is an optional name of the argument or return value.
	Name string

	// Type is the parameter type, like uint256, bytes32, etc. It must
	// be empty for tuples.
	Type string

	// Tuple is a list tuple elements. It must be empty for non-tuple types.
	Tuple []Parameter

	// Arrays is the list of array dimensions, where each dimension is the
	// maximum length of the array. If the length is -1, the array is
	// unbounded. If the Arrays is empty, the argument is not an array.
	Arrays []int

	// Indexed indicates whether the argument is indexed. It must be false
	// for types other than event.
	Indexed bool

	// DataLocation indicates the data location of the argument. It should be
	// UnspecifiedLocation for types other than function and constructor.
	DataLocation DataLocation
}

Parameter represents an argument or return value.

func ParseParameter

func ParseParameter(signature string) (Parameter, error)

ParseParameter parses the single parameter. The syntax is same as for parameters in the ParseSignature function.

func ParseStruct

func ParseStruct(definition string) (Parameter, error)

ParseStruct parses the struct definition.

It returns a structure as a tuple type where the tuple name is the struct name and the tuple elements are the struct fields.

func (Parameter) String

func (p Parameter) String() string

String returns the string representation of the type.

type Signature

type Signature struct {
	// Kind is the kind of the signature.
	Kind SignatureKind

	// Name is the name of the function, event or error. It should be empty for
	// fallback, receive and constructor kinds.
	Name string

	// Inputs is the list of input parameters.
	Inputs []Parameter

	// Outputs is the list of output parameters.
	Outputs []Parameter

	// Modifiers is the list of function modifiers.
	Modifiers []string
}

Signature represents a signature of a function, constructor, fallback, receive, event or error.

func ParseSignature

func ParseSignature(signature string) (Signature, error)

ParseSignature parses the function, constructor, fallback, receive, event or error signature. The syntax is similar to that of Solidity, but it is less strict. The argument names are always optional, and the return keyword can be omitted.

Tuples are represented as a list of types enclosed in parentheses, optionally prefixed with the "tuple" keyword.

Signature may be prepended with the keyword describing the signature kind. The following kinds are supported:

  • function
  • constructor
  • fallback
  • receive
  • event
  • error

The following examples are valid signatures:

  • function foo(uint256 memory a, tuple(uint256 b1, uint256 b2) memory b) internal returns (uint256)
  • function foo(uint256 a, (uint256 b1, uint256 b2) b) (uint256)
  • foo(uint256,(uint256,uint256))(uint256)
  • constructor(uint256 a, uint256 b)
  • fallback(bytes memory a) returns (bytes memory)
  • receive()
  • event Foo(uint256 a, uint256 b)
  • error Foo(uint256 a, uint256 b)

Signatures that are syntactically correct, but semantically invalid are rejected by the parser.

func ParseSignatureAs

func ParseSignatureAs(kind SignatureKind, signature string) (Signature, error)

ParseSignatureAs works like ParseSignature, but it allows to specify the signature kind.

The kind can be UnknownKind, in which case the kind is inferred from the signature.

func (Signature) String

func (s Signature) String() string

String returns the string representation of the signature.

type SignatureKind

type SignatureKind int8

SignatureKind is the kind of the signature, like function, constructor, fallback, etc.

const (
	UnknownKind SignatureKind = iota
	FunctionKind
	ConstructorKind
	FallbackKind
	ReceiveKind
	EventKind
	ErrorKind
)

func (SignatureKind) String

func (s SignatureKind) String() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL