abi

package
v1.2.1 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Tl;dr

sampleABI, _ := ParseABI([]byte(`[
	{
		"name": "transfer",
		"inputs": [
			{"name": "recipient", "internalType": "address", "type": "address" },
			{"name": "amount", "internalType": "uint256", "type": "uint256"}
		],
		"outputs": [{"internalType": "bool", "type": "bool"}],
		"stateMutability": "nonpayable",
		"type": "function"
	}
]`))
transferABIFn := sampleABI.Functions()["transfer"]
sampleABICallBytes, _ := transferABIFn.EncodeCallDataJSON([]byte(
	`{"recipient":"0x4a0d852ebb58fc88cb260bb270ae240f72edc45b","amount":"100000000000000000"}`,
))
fmt.Printf("ABI Call Bytes: %s\n", hex.EncodeToString(sampleABICallBytes))
values, _ := transferABIFn.DecodeCallData(sampleABICallBytes)
outputJSON, _ := NewSerializer().
	SetFormattingMode(FormatAsObjects).
	SetByteSerializer(HexByteSerializer0xPrefix).
	SerializeJSON(values)
fmt.Printf("Back to JSON:  %s\n", outputJSON)

The abi package allows encoding and decoding of ABI encoded bytes, for the inputs/outputs to EVM functions, and the parsing of EVM logs/events.

A high level summary of the API is as follows:

                     [ ABI ]        - parse your ABI definition, using the Go model of the JSON format
                        ↓
                    (validate)      - all types in functions (methods), events and errors are validated
                        ↓
            [ ComponentType tree ]  - to build a "type tree" of all the arrays/tuples/elementary
                        ↓
[ JSON ] →  [ ComponentValue tree ] - which you combine with data (JSON or Go types) to get a "value tree"
                        ↓
                     (encode)       - the value tree can then be serialized into ABI encoded bytes
                        ↓
              [ ABI encoded bytes ] - so you can use these bytes to invoke EVM functions (signatures supported)
                        ↓
                     (decode)       - then you can decode ABI bytes from function outputs, or logs (event data)
                        ↓
[ JSON ] ← [ ComponentValue tree ]  - the value tree can be serialized back to JSON

Example:

transferABI := `[
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "recipient",
				"type": "address"
			},
			{
				"internalType": "uint256",
				"name": "amount",
				"type": "uint256"
			}
		],
		"name": "transfer",
		"outputs": [
			{
				"internalType": "bool",
				"name": "",
				"type": "bool"
			}
		],
		"stateMutability": "nonpayable",
		"type": "function"
	}
]`

// Parse the ABI definition
var abi ABI
_ = json.Unmarshal([]byte(transferABI), &abi)
f := abi.Functions()["transfer"]

// Parse some JSON input data conforming to the ABI
encodedValueTree, _ := f.Inputs.ParseJSON([]byte(`{
	"recipient": "0x03706Ff580119B130E7D26C5e816913123C24d89",
	"amount": "1000000000000000000"
}`))

// We can serialize this directly to abi bytes
abiData, _ := encodedValueTree.EncodeABIData()
fmt.Println(hex.EncodeToString(abiData))
// 00000000000000000000000003706ff580119b130e7d26c5e816913123c24d890000000000000000000000000000000000000000000000000de0b6b3a7640000

// We can also serialize that to function call data, with the function selector prefix
abiCallData, _ := f.EncodeCallData(encodedValueTree)

// Decode those ABI bytes back again, verifying the function selector
decodedValueTree, _ := f.DecodeCallData(abiCallData)

// Serialize back to JSON with default formatting - note the keys are alphabetically ordered
jsonData, _ := decodedValueTree.JSON()
fmt.Println(string(jsonData))
// {"amount":"1000000000000000000","recipient":"03706ff580119b130e7d26c5e816913123c24d89"}

// Use a custom serializer to get ordered array output, hex integers, and 0x prefixes
// - Check out FormatAsSelfDescribingArrays for a format with embedded type information
jsonData2, _ := NewSerializer().
	SetFormattingMode(FormatAsFlatArrays).
	SetIntSerializer(HexIntSerializer0xPrefix).
	SetByteSerializer(HexByteSerializer0xPrefix).
	SerializeJSON(decodedValueTree)
fmt.Println(string(jsonData2))
// ["0x03706ff580119b130e7d26c5e816913123c24d89","0xde0b6b3a7640000"]

The package deliberately gives you access to perform all of the transitions individually.

For example, if you want to traverse the type tree itself to generate metadata for the ABI, you can do that by calling TypeComponentTree() on the inputs/outputs of a function/event.

External data parsing tries to be flexible when coercing JSON data into a value tree:

- Bytes and Addresses can be any of:

  • Hex string without any prefix
  • Hex string with an "0x" prefix
  • A byte array

- Numbers can be any of:

  • A base10 formatted string without any prefix
  • A hex formatted string with an "0x" prefix
  • A number
  • Negative numbers are supported
  • Floating point numbers are supported (for ABI fixed/ufixed types)

- Boolean values can be any of:

  • A boolean
  • A string "true"/"false"

- Strings must be a string

When passing in an interface{} (instead of JSON directly) efforts are made to follow pointers, and resolve types down to the basic types. For example detecting whether a struct conforms to the fmt.Stringer interface.

For serialization back out from the value tree, to JSON, there is a pluggable formatting interface with a number of built-in options as follows:

- Parameter serialization for function outputs / event log data (and nested tuples) can be:

  • Object based {"key1":"val1"}
  • Flat ordered array based ["val1"]
  • Self describing array based [{"name":"key1","type":"string","value":"val1"}]

- Number serialization can be:

  • Base 10 formatted string
  • Hex with "0x" prefix
  • Numeric up to the maximum safe Javascript values, then automatically switching to string

- Byte serialization can be:

  • Hex with "0x" prefix
  • Hex without any prefix

Index

Constants

This section is empty.

Variables

View Source
var (
	ElementaryTypeInt = registerElementaryType(elementaryTypeInfo{
		name:             BaseTypeInt,
		suffixType:       suffixTypeMRequired,
		defaultSuffix:    "256",
		mMin:             8,
		mMax:             256,
		mMod:             8,
		fixed32:          true,
		dynamic:          alwaysFixed,
		jsonEncodingType: JSONEncodingTypeInteger,
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getIntegerFromInterface(ctx, desc, input)
		},
		encodeABIData: encodeABISignedInteger,
		decodeABIData: decodeABISignedInt,
	})
	ElementaryTypeUint = registerElementaryType(elementaryTypeInfo{
		name:             BaseTypeUInt,
		suffixType:       suffixTypeMRequired,
		defaultSuffix:    "256",
		mMin:             8,
		mMax:             256,
		mMod:             8,
		fixed32:          true,
		dynamic:          alwaysFixed,
		jsonEncodingType: JSONEncodingTypeInteger,
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getIntegerFromInterface(ctx, desc, input)
		},
		encodeABIData: encodeABIUnsignedInteger,
		decodeABIData: decodeABIUnsignedInt,
	})
	ElementaryTypeAddress = registerElementaryType(elementaryTypeInfo{
		name:       BaseTypeAddress,
		suffixType: suffixTypeNone,
		defaultM:   160,
		fixed32:    true,
		dynamic:    alwaysFixed,
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getUintBytesFromInterface(ctx, desc, input)
		},
		jsonEncodingType: JSONEncodingTypeBytes,
		encodeABIData:    encodeABIUnsignedInteger,
		decodeABIData:    decodeABIUnsignedInt,
	})
	ElementaryTypeBool = registerElementaryType(elementaryTypeInfo{
		name:       BaseTypeBool,
		suffixType: suffixTypeNone,
		defaultM:   8,
		fixed32:    true,
		dynamic:    alwaysFixed,
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getBoolAsUnsignedIntegerFromInterface(ctx, desc, input)
		},
		jsonEncodingType: JSONEncodingTypeBool,
		encodeABIData:    encodeABIUnsignedInteger,
		decodeABIData:    decodeABIUnsignedInt,
	})
	ElementaryTypeFixed = registerElementaryType(elementaryTypeInfo{
		name:             BaseTypeFixed,
		suffixType:       suffixTypeMxNRequired,
		defaultSuffix:    "128x18",
		mMin:             8,
		mMax:             256,
		mMod:             8,
		nMin:             1,
		nMax:             80,
		fixed32:          true,
		dynamic:          alwaysFixed,
		jsonEncodingType: JSONEncodingTypeFloat,
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getFloatFromInterface(ctx, desc, input)
		},
		encodeABIData: encodeABISignedFloat,
		decodeABIData: decodeABISignedFloat,
	})
	ElementaryTypeUfixed = registerElementaryType(elementaryTypeInfo{
		name:             BaseTypeUFixed,
		suffixType:       suffixTypeMxNRequired,
		defaultSuffix:    "128x18",
		mMin:             8,
		mMax:             256,
		mMod:             8,
		nMin:             1,
		nMax:             80,
		fixed32:          true,
		dynamic:          alwaysFixed,
		jsonEncodingType: JSONEncodingTypeFloat,
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getFloatFromInterface(ctx, desc, input)
		},
		encodeABIData: encodeABIUnsignedFloat,
		decodeABIData: decodeABIUnsignedFloat,
	})
	ElementaryTypeBytes = registerElementaryType(elementaryTypeInfo{
		name:       BaseTypeBytes,
		suffixType: suffixTypeMOptional,
		mMin:       1,
		mMax:       32,
		fixed32:    false,
		dynamic:    func(tc *typeComponent) bool { return tc.elementarySuffix == "" },
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getBytesFromInterface(ctx, desc, input)
		},
		jsonEncodingType: JSONEncodingTypeBytes,
		encodeABIData:    encodeABIBytes,
		decodeABIData:    decodeABIBytes,
	})
	ElementaryTypeFunction = registerElementaryType(elementaryTypeInfo{
		name:       BaseTypeFunction,
		suffixType: suffixTypeNone,
		defaultM:   24,
		fixed32:    true,
		dynamic:    alwaysFixed,
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getBytesFromInterface(ctx, desc, input)
		},
		jsonEncodingType: JSONEncodingTypeBytes,
		encodeABIData:    encodeABIBytes,
		decodeABIData:    decodeABIBytes,
	})
	ElementaryTypeString = registerElementaryType(elementaryTypeInfo{
		name:       BaseTypeString,
		suffixType: suffixTypeNone,
		fixed32:    false,
		dynamic:    func(tc *typeComponent) bool { return true },
		readExternalData: func(ctx context.Context, desc string, input interface{}) (interface{}, error) {
			return getStringFromInterface(ctx, desc, input)
		},
		jsonEncodingType: JSONEncodingTypeString,
		encodeABIData:    encodeABIString,
		decodeABIData:    decodeABIString,
	})
)

Functions

func Base10StringFloatSerializer

func Base10StringFloatSerializer(f *big.Float) interface{}

func Base10StringIntSerializer

func Base10StringIntSerializer(i *big.Int) interface{}

func Base64ByteSerializer

func Base64ByteSerializer(b []byte) interface{}

func ChecksumAddrSerializer

func ChecksumAddrSerializer(addr [20]byte) interface{}

func FormatErrorStringCtx

func FormatErrorStringCtx(ctx context.Context, e *Entry, cv *ComponentValue) string

func HexAddrSerializer0xPrefix

func HexAddrSerializer0xPrefix(addr [20]byte) interface{}

func HexAddrSerializerPlain

func HexAddrSerializerPlain(addr [20]byte) interface{}

func HexByteSerializer

func HexByteSerializer(b []byte) interface{}

func HexByteSerializer0xPrefix

func HexByteSerializer0xPrefix(b []byte) interface{}

func HexIntSerializer0xPrefix

func HexIntSerializer0xPrefix(i *big.Int) interface{}

func JSONNumberIntSerializer

func JSONNumberIntSerializer(i *big.Int) interface{}

func NumberIfFitsOrBase10StringFloatSerializer

func NumberIfFitsOrBase10StringFloatSerializer(f *big.Float) interface{}

func NumberIfFitsOrBase10StringIntSerializer

func NumberIfFitsOrBase10StringIntSerializer(i *big.Int) interface{}

func NumericDefaultNameGenerator

func NumericDefaultNameGenerator(idx int) string

func ParseInt256TwosComplementBytes

func ParseInt256TwosComplementBytes(b []byte) *big.Int

func SanitizeBinaryString

func SanitizeBinaryString(raw []byte) string

SanitizeBinaryString returns the input as a text string if it is entirely printable ASCII, or hex-encodes the entire input otherwise. This ensures the output is always safe for database TEXT columns and human-readable logging.

func SerializeInt256TwosComplementBytes

func SerializeInt256TwosComplementBytes(i *big.Int) []byte

Types

type ABI

type ABI []*Entry

ABI "Application Binary Interface" is a list of the methods and events on the external interface of an EVM based smart contract - written in Solidity / Vyper.

It is structured as a JSON array of ABI entries, each of which can be a function, event or error definition.

func ParseABI

func ParseABI(data []byte) (ABI, error)

func (ABI) Constructor

func (a ABI) Constructor() *Entry

func (ABI) DecodeRevertError

func (a ABI) DecodeRevertError(revertData []byte, options ...ErrorFormatOption) *RevertError

DecodeRevertError decodes raw EVM revert data into a RevertError. Pass ErrorFormatOption{SearchForWrappedBinaryErrors: true} to scan for inner errors binary-encoded within an Error(string) value. Returns nil if the data does not match any known error selector.

func (ABI) DecodeRevertErrorCtx

func (a ABI) DecodeRevertErrorCtx(ctx context.Context, revertData []byte, options ...ErrorFormatOption) *RevertError

DecodeRevertErrorCtx decodes raw EVM revert data into a RevertError. The ABI's error entries are tried first, followed by the built-in Error(string) and Panic(uint256). Returns nil if no selector matches. Pass ErrorFormatOption{SearchForWrappedBinaryErrors: true} to scan for inner errors binary-encoded within an Error(string) value.

func (ABI) ErrorString

func (a ABI) ErrorString(revertData []byte, options ...ErrorFormatOption) (string, bool)

ErrorString formats raw EVM revert data as a human-readable string. Pass ErrorFormatOption{SearchForWrappedBinaryErrors: true} to decode inner errors that are binary-encoded within an Error(string) value.

func (ABI) ErrorStringCtx

func (a ABI) ErrorStringCtx(ctx context.Context, revertData []byte, options ...ErrorFormatOption) (string, bool)

ErrorStringCtx formats raw EVM revert data as a human-readable string. The ABI's own error entries are tried first, followed by the built-in Error(string) and Panic(uint256). Pass ErrorFormatOption{SearchForWrappedBinaryErrors: true} to decode inner errors that are binary-encoded within an Error(string) value.

func (ABI) Errors

func (a ABI) Errors() map[string]*Entry

func (ABI) Events

func (a ABI) Events() map[string]*Entry

func (ABI) FilterType

func (a ABI) FilterType(t EntryType) ABI

FilterType returns a new ABI containing only the entries whose Type matches t, preserving their original order. Returns nil if no entries match. Use this to narrow an ABI before passing it to SelectorMap or other helpers, e.g. a.FilterType(Error) to obtain only error definitions.

func (ABI) Functions

func (a ABI) Functions() map[string]*Entry

func (ABI) ParseError

func (a ABI) ParseError(revertData []byte) (*Entry, *ComponentValue, bool)

Returns the components value from the parsed error

func (ABI) ParseErrorCtx

func (a ABI) ParseErrorCtx(ctx context.Context, revertData []byte) (*Entry, *ComponentValue, bool)

ParseErrorCtx returns the matched Entry and decoded ComponentValue from the given revert data. The ABI's error entries are tried first, followed by the built-in Error(string) and Panic(uint256).

func (ABI) SelectorMap

func (a ABI) SelectorMap() map[[4]byte]*Entry

SelectorMap builds a map from 4-byte ABI selectors to their corresponding entries. When two entries in the ABI produce the same 4-byte selector, the first one wins. Entries for which selector generation fails are silently skipped.

SelectorMap operates on all entry types — combine with FilterType to restrict to a specific type, e.g. a.FilterType(Error).SelectorMap().

func (ABI) Validate

func (a ABI) Validate() (err error)

Validate processes all the components of all the entries in this ABI, to build a parsing tree

func (ABI) ValidateCtx

func (a ABI) ValidateCtx(ctx context.Context) (err error)

type AddressSerializer

type AddressSerializer func(addr [20]byte) interface{}

type BaseTypeName

type BaseTypeName string
const (
	BaseTypeInt      BaseTypeName = "int"
	BaseTypeUInt     BaseTypeName = "uint"
	BaseTypeAddress  BaseTypeName = "address"
	BaseTypeBool     BaseTypeName = "bool"
	BaseTypeFixed    BaseTypeName = "fixed"
	BaseTypeUFixed   BaseTypeName = "ufixed"
	BaseTypeBytes    BaseTypeName = "bytes"
	BaseTypeFunction BaseTypeName = "function"
	BaseTypeString   BaseTypeName = "string"
)

type ByteSerializer

type ByteSerializer func(b []byte) interface{}

type ComponentType

type ComponentType int
const (
	ElementaryComponent ComponentType = iota
	FixedArrayComponent
	DynamicArrayComponent
	TupleComponent
)

type ComponentValue

type ComponentValue struct {
	Component TypeComponent
	Children  []*ComponentValue
	Value     interface{}
}

ComponentValue is a the ABI matched data associated with the TypeComponent tree of the ABI.

func (*ComponentValue) ElementaryABIData

func (cv *ComponentValue) ElementaryABIData() ([]byte, bool, error)

func (*ComponentValue) ElementaryABIDataCtx

func (cv *ComponentValue) ElementaryABIDataCtx(ctx context.Context) (data []byte, dynamic bool, err error)

func (*ComponentValue) EncodeABIData

func (cv *ComponentValue) EncodeABIData() ([]byte, error)

func (*ComponentValue) EncodeABIDataCtx

func (cv *ComponentValue) EncodeABIDataCtx(ctx context.Context) ([]byte, error)

func (*ComponentValue) JSON

func (cv *ComponentValue) JSON() ([]byte, error)

JSON is a convenience helper for NewSerializer().Serialize(cv), to perform default serialization See Serializer builder for configuration options. See Serializer.SerializeInterface() to obtain the interface to serialize to other binary formats (YAML, TOML etc.).

type DataReader

type DataReader func(ctx context.Context, desc string, input interface{}) (interface{}, error)

type DefaultNameGenerator

type DefaultNameGenerator func(idx int) string

type ElementaryTypeInfo

type ElementaryTypeInfo interface {
	BaseType() BaseTypeName             // const for each of the elementary types
	String() string                     // gives a summary of the rules the elemental type (used in error reporting)
	JSONEncodingType() JSONEncodingType // categorizes JSON input/output type to one of a small number of options
	DataReader() DataReader             // allows a side-door into the ABI code read data - caller has to know what to expect
}

ElementaryTypeInfo represents the rules for each elementary type understood by this ABI type parser. You can do an equality check against the appropriate constant, to check if this is the type you are expecting. e.g.

type Entry

type Entry struct {
	Type            EntryType       `ffstruct:"EthABIEntry" json:"type,omitempty"`            // Type of the entry - there are multiple function sub-types, events and errors
	Name            string          `ffstruct:"EthABIEntry" json:"name,omitempty"`            // Name of the function/event/error
	Payable         bool            `ffstruct:"EthABIEntry" json:"payable,omitempty"`         // Functions only: Superseded by stateMutability payable/nonpayable
	Constant        bool            `ffstruct:"EthABIEntry" json:"constant,omitempty"`        // Functions only: Superseded by stateMutability pure/view
	Anonymous       bool            `ffstruct:"EthABIEntry" json:"anonymous,omitempty"`       // Events only: The event is emitted without a signature (topic[0] is not generated)
	StateMutability StateMutability `ffstruct:"EthABIEntry" json:"stateMutability,omitempty"` // How the function interacts with the blockchain state
	Inputs          ParameterArray  `ffstruct:"EthABIEntry" json:"inputs"`                    // The list of input parameters to a function, or fields of an event / error
	Outputs         ParameterArray  `ffstruct:"EthABIEntry" json:"outputs"`                   // Functions only: The list of return values from a function
}

Entry is an individual entry in an ABI - a function, event or error.

Defines the name / inputs / outputs which can be used to generate the signature of the function/event, and used to encode input data, or decode output data.

func (*Entry) DecodeCallData

func (e *Entry) DecodeCallData(b []byte) (*ComponentValue, error)

func (*Entry) DecodeCallDataCtx

func (e *Entry) DecodeCallDataCtx(ctx context.Context, b []byte) (*ComponentValue, error)

func (*Entry) DecodeEventData

func (e *Entry) DecodeEventData(topics []ethtypes.HexBytes0xPrefix, data ethtypes.HexBytes0xPrefix) (*ComponentValue, error)

DecodeEventData takes the array of topics, and the event data, and builds a component value tree that parses the values against the ABI definition in the entry. Values are extracted from either the topic or data per the rules defined here: https://docs.soliditylang.org/en/v0.8.15/abi-spec.html

If the event is non-anonymous, the signature hash of the event must match the first topic (or an error is thrown).

func (*Entry) DecodeEventDataCtx

func (e *Entry) DecodeEventDataCtx(ctx context.Context, topics []ethtypes.HexBytes0xPrefix, data ethtypes.HexBytes0xPrefix) (*ComponentValue, error)

func (*Entry) EncodeCallData

func (e *Entry) EncodeCallData(cv *ComponentValue) ([]byte, error)

EncodeCallData serializes the inputs of the entry, prefixed with the function selector

func (*Entry) EncodeCallDataCtx

func (e *Entry) EncodeCallDataCtx(ctx context.Context, cv *ComponentValue) ([]byte, error)

func (*Entry) EncodeCallDataJSON

func (e *Entry) EncodeCallDataJSON(jsonData []byte) ([]byte, error)

EncodeCallDataValues is a helper to go straight from an JSON input, to binary encoded call data

func (*Entry) EncodeCallDataJSONCtx

func (e *Entry) EncodeCallDataJSONCtx(ctx context.Context, jsonData []byte) ([]byte, error)

func (*Entry) EncodeCallDataValues

func (e *Entry) EncodeCallDataValues(values interface{}) ([]byte, error)

EncodeCallDataValues is a helper to go straight from an interface input, such as a map or array, to call data

func (*Entry) EncodeCallDataValuesCtx

func (e *Entry) EncodeCallDataValuesCtx(ctx context.Context, values interface{}) ([]byte, error)

func (*Entry) FunctionSelectorBytes

func (e *Entry) FunctionSelectorBytes() ethtypes.HexBytes0xPrefix

FunctionSelectorBytes is a convenience function to get the ID as bytes. Will return all zeros on error (ensures non-nil)

func (*Entry) GenerateFunctionSelector

func (e *Entry) GenerateFunctionSelector() ([]byte, error)

func (*Entry) GenerateFunctionSelectorCtx

func (e *Entry) GenerateFunctionSelectorCtx(ctx context.Context) ([]byte, error)

func (*Entry) IsFunction

func (e *Entry) IsFunction() bool

func (*Entry) Signature

func (e *Entry) Signature() (string, error)

func (*Entry) SignatureCtx

func (e *Entry) SignatureCtx(ctx context.Context) (string, error)

func (*Entry) SignatureHash

func (e *Entry) SignatureHash() (ethtypes.HexBytes0xPrefix, error)

SignatureHash returns the keccak hash of the signature as bytes

func (*Entry) SignatureHashBytes

func (e *Entry) SignatureHashBytes() ethtypes.HexBytes0xPrefix

SignatureHashBytes is a convenience function to get the signature hash as bytes. Will return all zeros on error (ensures non-nil)

func (*Entry) SignatureHashCtx

func (e *Entry) SignatureHashCtx(context.Context) (ethtypes.HexBytes0xPrefix, error)

func (*Entry) SolString

func (e *Entry) SolString() string

SolString returns a Solidity - like string, with an empty function definition, and any struct definitions separated afterwards with a ; (semicolon)

func (*Entry) SolidityDef

func (e *Entry) SolidityDef() (string, []string, error)

func (*Entry) SolidityDefCtx

func (e *Entry) SolidityDefCtx(ctx context.Context) (string, []string, error)

SolidityDefCtx returns a Solidity-like descriptor of the entry, including its type

func (*Entry) SolidityStringCtx

func (e *Entry) SolidityStringCtx(ctx context.Context) (string, error)

func (*Entry) String

func (e *Entry) String() string

String returns the signature string. If a Validate needs to be initiated, and that parse fails, then the error is logged, but is not returned

func (*Entry) Validate

func (e *Entry) Validate() (err error)

Validate processes all the components of all the parameters in this ABI entry

func (*Entry) ValidateCtx

func (e *Entry) ValidateCtx(ctx context.Context) (err error)

type EntryType

type EntryType string

EntryType is an enum of the possible ABI entry types

const (
	Function    EntryType = "function"    // A function/method of the smart contract
	Constructor EntryType = "constructor" // The constructor
	Receive     EntryType = "receive"     // The "receive ether" function
	Fallback    EntryType = "fallback"    // The default function to invoke
	Event       EntryType = "event"       // An event the smart contract can emit
	Error       EntryType = "error"       // An error definition
)

type ErrorFormatOption

type ErrorFormatOption struct {
	// There is a pattern used in some smart contracts, where a string error is used
	// to embed the raw bytes of an ABI encoded sub-error.
	// While uncommon, this pattern is supported by the library if you set this switch.
	// When set, every standard revert `Error(string)` error will be traversed to look for
	// eyecatcher (4 byte signatures) of other errors binary encoded within the string.
	SearchForWrappedBinaryErrors bool
}

ErrorFormatOption configures the behaviour of ErrorString and ErrorStringCtx.

type FloatSerializer

type FloatSerializer func(f *big.Float) interface{}

type FormattingMode

type FormattingMode int

FormattingMode affects how function parameters, and child tuples, are serialized.

const (
	// FormatAsObjects uses the names of the function / event / tuple parameters as keys in an object
	FormatAsObjects FormattingMode = iota
	// FormatAsFlatArrays uses flat arrays of flat values
	FormatAsFlatArrays
	// FormatAsSelfDescribingArrays uses arrays of structures with {"name":"arg1","type":"uint256","value":...}
	FormatAsSelfDescribingArrays
)

type IntSerializer

type IntSerializer func(i *big.Int) interface{}

type JSONEncodingType

type JSONEncodingType int
const (
	JSONEncodingTypeBool    JSONEncodingType = iota // JSON string or bool
	JSONEncodingTypeInteger                         // JSON string containing integer with/without 0x prefix, or JSON number
	JSONEncodingTypeBytes                           // JSON string containing hex with/without 0x prefix
	JSONEncodingTypeFloat                           // JSON string containing a float with/without 0x prefix or exponent, or JSON number
	JSONEncodingTypeString                          // JSON string containing any unicode characters
)

type Parameter

type Parameter struct {
	Name         string         `ffstruct:"EthABIParameter" json:"name"`                   // The name of the argument - does not affect the signature
	Type         string         `ffstruct:"EthABIParameter" json:"type"`                   // The canonical type of the parameter
	InternalType string         `ffstruct:"EthABIParameter" json:"internalType,omitempty"` // Additional internal type information that might be generated by the compiler
	Components   ParameterArray `ffstruct:"EthABIParameter" json:"components,omitempty"`   // An ordered list (tuple) of nested elements for array/object types
	Indexed      bool           `ffstruct:"EthABIParameter" json:"indexed,omitempty"`      // Events only: Whether the parameter is indexed into one of the topics of the log, or in the log's data segment
	// contains filtered or unexported fields
}

Parameter is an individual typed parameter input/output

func (*Parameter) SignatureString

func (p *Parameter) SignatureString() (s string, err error)

SignatureString generates and returns the signature string of the ABI parameter. If Validate has not yet been called, it will be called on your behalf.

Note if you have modified the structure since Validate was last called, you should call Validate again.

func (*Parameter) SignatureStringCtx

func (p *Parameter) SignatureStringCtx(ctx context.Context) (string, error)

func (*Parameter) SolidityDefCtx

func (p *Parameter) SolidityDefCtx(ctx context.Context, fieldType SolFieldType) (string, []string, error)

func (*Parameter) String

func (p *Parameter) String() string

String returns the signature string. If a Validate needs to be initiated, and that parse fails, then the error is logged, but is not returned

func (*Parameter) TypeComponentTree

func (p *Parameter) TypeComponentTree() (TypeComponent, error)

ComponentTypeTree returns the root of the component tree for the parameter. If Validate has not yet been called, it will be called on your behalf.

Note if you have modified the structure since Validate was last called, you should call Validate again.

func (*Parameter) TypeComponentTreeCtx

func (p *Parameter) TypeComponentTreeCtx(ctx context.Context) (TypeComponent, error)

func (*Parameter) Validate

func (p *Parameter) Validate() (err error)

Validate processes all the components of the type of this ABI parameter. - The elementary type - The fixed/variable length array dimensions - The tuple component types (recursively)

func (*Parameter) ValidateCtx

func (p *Parameter) ValidateCtx(ctx context.Context) (err error)

type ParameterArray

type ParameterArray []*Parameter

func (ParameterArray) DecodeABIData

func (pa ParameterArray) DecodeABIData(b []byte, offset int) (cv *ComponentValue, err error)

DecodeABIData takes ABI encoded bytes that conform to the parameter array, and decodes them into a value tree. We take the offset (rather than requiring you to generate a slice at the given offset) so that errors in parsing can be reported at an absolute offset.

func (ParameterArray) DecodeABIDataCtx

func (pa ParameterArray) DecodeABIDataCtx(ctx context.Context, b []byte, offset int) (cv *ComponentValue, err error)

func (ParameterArray) EncodeABIDataJSON

func (pa ParameterArray) EncodeABIDataJSON(jsonData []byte) ([]byte, error)

EncodeABIData is a helper to go all the way from JSON data to encoded ABI bytes

func (ParameterArray) EncodeABIDataJSONCtx

func (pa ParameterArray) EncodeABIDataJSONCtx(ctx context.Context, jsonData []byte) ([]byte, error)

EncodeABIData is a helper to go all the way from JSON data to encoded ABI bytes

func (ParameterArray) EncodeABIDataValues

func (pa ParameterArray) EncodeABIDataValues(v interface{}) ([]byte, error)

EncodeABIData goes all the way from interface inputs, to encoded ABI bytes The TypeComponentTree is created and discarded within the function

func (ParameterArray) EncodeABIDataValuesCtx

func (pa ParameterArray) EncodeABIDataValuesCtx(ctx context.Context, v interface{}) ([]byte, error)

func (ParameterArray) ParseExternalData

func (pa ParameterArray) ParseExternalData(input interface{}) (cv *ComponentValue, err error)

ParseExternalData takes (non-ABI encoded) data input, such as an unmarshalled JSON structure, and traverses it against the ABI component type tree, to form a component value tree.

The component value tree can then be serialized to binary ABI data.

func (ParameterArray) ParseExternalDataCtx

func (pa ParameterArray) ParseExternalDataCtx(ctx context.Context, input interface{}) (cv *ComponentValue, err error)

func (ParameterArray) ParseJSON

func (pa ParameterArray) ParseJSON(data []byte) (*ComponentValue, error)

ParseJSON takes external JSON data, and parses against the ABI to generate a component value tree.

The component value tree can then be serialized to binary ABI data.

func (ParameterArray) ParseJSONCtx

func (pa ParameterArray) ParseJSONCtx(ctx context.Context, data []byte) (*ComponentValue, error)

func (ParameterArray) TypeComponentTree

func (pa ParameterArray) TypeComponentTree() (component TypeComponent, err error)

TypeComponentTree returns the type component tree for the array (tuple) of individually typed parameters

func (ParameterArray) TypeComponentTreeCtx

func (pa ParameterArray) TypeComponentTreeCtx(ctx context.Context) (tc TypeComponent, err error)

type RevertError

type RevertError struct {
	ErrorEntry *Entry `ffstruct:"RevertError" json:"errorEntry,omitempty"` // the matched ABI error entry at this level

	Prefix     string       `ffstruct:"RevertError" json:"prefix,omitempty"`     // readable text before the inner error
	InnerError *RevertError `ffstruct:"RevertError" json:"innerError,omitempty"` // recursively decoded inner error, nil if none
	// contains filtered or unexported fields
}

RevertError represents a decoded Solidity revert error. For nested errors (where a contract catches a revert and re-throws with the original error embedded in the string), the InnerError field links to the inner decoded error, forming a recursive chain.

func (*RevertError) ErrorString

func (r *RevertError) ErrorString() string

ErrorString returns the formatted error at this level only, e.g. Error("not enough funds") or MyCustomError("0x1234","-100"). Unlike String(), it does not walk the chain — use it when you need the single-level description.

func (*RevertError) Errors

func (r *RevertError) Errors() []*RevertError

Errors returns a flattened slice of all RevertError entries in the chain, from outermost to innermost.

func (*RevertError) GetInnerError

func (r *RevertError) GetInnerError() *RevertError

GetInnerError returns the next error in the chain (one level deeper), or nil at the leaf.

func (*RevertError) Innermost

func (r *RevertError) Innermost() *RevertError

Innermost walks the chain to return the deepest RevertError — the innermost binary-wrapped error.

func (*RevertError) SerializeJSON

func (r *RevertError) SerializeJSON(ctx context.Context, s *Serializer) ([]byte, error)

SerializeJSON serializes the decoded error data at this level using the provided Serializer.

func (*RevertError) Signature

func (r *RevertError) Signature() (string, error)

Signature returns the ABI signature of the error at this level, e.g. "Error(string)" or "AnError(string,uint256)".

func (*RevertError) String

func (r *RevertError) String() string

String returns a human-readable representation of the full error chain. It concatenates the Prefix at each level, with the leaf error formatted as ErrorName(arg1,arg2,...).

type Serializer

type Serializer struct {
	// contains filtered or unexported fields
}

Serializer contains a set of options for how to serialize an parsed ABI value tree, into JSON.

func NewSerializer

func NewSerializer() *Serializer

NewSerializer creates a new ABI value tree serializer, with the default configuration. - FormattingMode: FormatAsObjects - IntSerializer: DecimalStringIntSerializer - FloatSerializer: DecimalStringFloatSerializer - ByteSerializer: HexByteSerializer

func (*Serializer) SerializeInterface

func (s *Serializer) SerializeInterface(cv *ComponentValue) (interface{}, error)

func (*Serializer) SerializeInterfaceCtx

func (s *Serializer) SerializeInterfaceCtx(ctx context.Context, cv *ComponentValue) (interface{}, error)

func (*Serializer) SerializeJSON

func (s *Serializer) SerializeJSON(cv *ComponentValue) ([]byte, error)

func (*Serializer) SerializeJSONCtx

func (s *Serializer) SerializeJSONCtx(ctx context.Context, cv *ComponentValue) ([]byte, error)

func (*Serializer) SetAddressSerializer

func (s *Serializer) SetAddressSerializer(ad AddressSerializer) *Serializer

func (*Serializer) SetByteSerializer

func (s *Serializer) SetByteSerializer(bs ByteSerializer) *Serializer

func (*Serializer) SetDefaultNameGenerator

func (s *Serializer) SetDefaultNameGenerator(dn DefaultNameGenerator) *Serializer

func (*Serializer) SetFloatSerializer

func (s *Serializer) SetFloatSerializer(fs FloatSerializer) *Serializer

func (*Serializer) SetFormattingMode

func (s *Serializer) SetFormattingMode(ts FormattingMode) *Serializer

func (*Serializer) SetIntSerializer

func (s *Serializer) SetIntSerializer(is IntSerializer) *Serializer

func (*Serializer) SetPretty

func (s *Serializer) SetPretty(pretty bool) *Serializer

type SolFieldType

type SolFieldType int
const (
	FunctionInput     SolFieldType = iota // input to a function, or a constructor
	EventOrErrorField                     // a field of an event or an error
	StructField                           // a field of a struct
)

type StateMutability

type StateMutability string
const (
	Pure       StateMutability = "pure"       // Specified not to read blockchain state
	View       StateMutability = "view"       // Specified not to modify the blockchain state (read-only)
	Payable    StateMutability = "payable"    // The function accepts ether
	NonPayable StateMutability = "nonpayable" // The function does not accept ether
)

type TypeComponent

type TypeComponent interface {
	String() string                     // gives the signature for this type level of the type component hierarchy
	ComponentType() ComponentType       // classification of the component type (tuple, array or elemental)
	ElementaryType() ElementaryTypeInfo // only non-nil for elementary components
	ElementaryM() uint16                // only for N dimensioned elementary types
	ElementaryN() uint16                // only for M dimensioned elementary types
	ElementarySuffix() string           // only on elementary types with a suffix - expands "aliases" (so "uint" would have "256")
	ElementaryFixed() bool              // whether the elementary type if fixed
	ArrayChild() TypeComponent          // only non-nil for array components
	FixedArrayLen() int                 // only for fixed-array components
	TupleChildren() []TypeComponent     // only non-nil for tuple components
	KeyName() string                    // the name of the ABI property/component, only set for top-level parameters and tuple entries
	Parameter() *Parameter              // the ABI property/component, only set for top-level parameters and tuple entries
	ParseExternal(v interface{}) (*ComponentValue, error)
	ParseExternalCtx(ctx context.Context, v interface{}) (*ComponentValue, error)
	ParseExternalDesc(ctx context.Context, v interface{}, desc string) (*ComponentValue, error)
	DecodeABIData(d []byte, offset int) (*ComponentValue, error)
	DecodeABIDataCtx(ctx context.Context, d []byte, offest int) (*ComponentValue, error)

	SolidityParamDef(fieldType SolFieldType) (solDef string, structDefs []string) // gives a string that can be used to define this param in solidity
	SolidityTypeDef() (isRef bool, typeDef string, childStructs []string)
	SolidityStructDef() (structName string, structs []string)
}

TypeComponent is a modelled representation of a component of an ABI type. We don't just go to the tuple level, we go down all the way through the arrays too. This breaks things down into the way in which they are serialized/parsed. Example "((uint256,string[2],string[])[][3][],string)" becomes: - tuple1

  • variable size array
  • fixed size [3] array
  • variable size array
  • tuple2
  • uint256
  • fixed size [2] array
  • string
  • variable size array
  • string
  • string

This thus matches the way a JSON structure would exist to supply values in

Jump to

Keyboard shortcuts

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