abicalldata

package
v0.64.3 Latest Latest
Warning

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

Go to latest
Published: May 19, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

README

ABI calldata

Helpers for Ethereum ABI-encoded calldata: head layout, static argument words, and dynamic bytes/string tails. Also defines ByteRange, Selector, and a fluent Path for locating byte spans inside a v3 CallsPayload.

Calldata layout

Offsets are from the start of calldata (bytes 0..3 are the 4-byte function selector).

  • AbiHeadWords(t) — number of 32-byte words an ABI type occupies in the head (dynamic types count as one offset word).
  • CalldataStaticWord(method, argIndex)start and length (multiple of 32) for a static argument’s encoded words in calldata.
  • CalldataBytesContent(calldata, method, argIndex)start/length of the raw bytes/string payload (no length word, no tail padding).
  • CalldataBytesEncoded(calldata, method, argIndex)start/length of the full tail slice: 32-byte length word + content + padding to 32-byte boundary.
method := contractABI.Methods["transfer"]
start, length, err := abicalldata.CalldataStaticWord(method, 1) // e.g. uint256 amount
if err != nil {
    return err
}
argBytes := calldata[start : start+length]

For nested calldata (e.g. a bytes argument whose body is another contract call), slice to the inner calldata and call these helpers again with the inner method’s abi.Method.

Calls payload selectors

  • ByteRange{CallIndex, Offset, Size} into payload.Calls[CallIndex].Data (that field is the call’s calldata, typically including the inner 4-byte selector).
  • SelectorResolve(*v3.CallsPayload) ([]ByteRange, error) plus String() for errors.
  • NewRangeSelector(callIndex, offset, size) — fixed range, validated on resolve.
sel := abicalldata.NewRangeSelector(0, 0x24, 32)
ranges, err := sel.Resolve(payload)

Path builder (NewPath)

*Path is a Selector: chain steps to walk from a top-level call into nested packed calls and ABI argument slots, then call .AsSelector() for APIs that take a Selector.

Typical steps:

  • .CallData(i) — start from payload.Calls[i].Data.
  • .ABI(contractABI, method) — bind the current range to that method (checks the 4-byte selector).
  • .ArgSlot(name) / .ArgSlotIndex(i) — static argument word(s) in the current frame.
  • .ArgBytesData(name) / .ArgBytesDataIndex(i) — inner payload of a bytes/string argument (clears ABI context; rebind with .ABI before further arg steps).
  • .ArgBytesEncoded(name) — full ABI-encoded tail for that dynamic argument.
  • .EncodedCallsPayload() — treat the active range as v3 packed calls; clear ABI context.
  • .EncodedCallData(j) — select packed call j’s calldata within that layout.
  • .Slice(offset, size) — byte slice within the active range.
sel := abicalldata.NewPath().
    CallData(0).
    ABI(&outerABI, "hydrateExecute").
    ArgBytesData("payload").
    EncodedCallsPayload().
    EncodedCallData(0).
    ABI(&tokenABI, "permit").
    ArgSlot("value").
    AsSelector()

After any step that narrows the range or switches to a new byte frame (including .Slice, .ArgBytesData, .ArgBytesDataIndex, .ArgBytesEncoded, .EncodedCallsPayload, .EncodedCallData), ABI context is cleared. Call .ABI(...) again before .ArgSlot, .ArgSlotIndex, .ArgBytesData, .ArgBytesDataIndex, or .ArgBytesEncoded on the new frame.

Packed calls layout

ParsePackedCalls(packed []byte) returns a PackedCallsLayout describing where each call’s calldata sits inside the encoded packed-calls blob (as produced by CallsPayload.Encode). CallData entries use Span (Start, Len; Start == -1 when that call has no calldata). The path step .EncodedCallData(i) uses this parser internally.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AbiHeadWords

func AbiHeadWords(t abi.Type) int

AbiHeadWords returns the number of 32-byte words this type occupies in the ABI calldata head. Dynamic types (bytes, string, slice, and tuples/arrays that contain them) occupy 1 word (offset); static types use their encoded size.

func CalldataBytesContent

func CalldataBytesContent(calldata []byte, method abi.Method, argIndex int) (start, length int, err error)

CalldataBytesContent returns the raw bytes/string content (excludes length word and padding).

func CalldataBytesEncoded

func CalldataBytesEncoded(calldata []byte, method abi.Method, argIndex int) (start, length int, err error)

CalldataBytesEncoded returns the full ABI-encoded tail: length word + data + padding.

func CalldataStaticWord

func CalldataStaticWord(method abi.Method, argIndex int) (start, length int, err error)

Types

type ByteRange

type ByteRange struct {
	CallIndex int
	Offset    int
	Size      int
}

ByteRange identifies a contiguous slice of one call's calldata (data field) in a CallsPayload.

func (ByteRange) Slice

func (r ByteRange) Slice(payload *v3.CallsPayload) ([]byte, error)

Slice returns the referenced bytes from payload.Calls[CallIndex].Data.

type PackedCallsLayout

type PackedCallsLayout struct {
	GlobalFlag byte
	NumCalls   int
	CallData   []Span
}

func ParsePackedCalls

func ParsePackedCalls(packed []byte) (*PackedCallsLayout, error)

ParsePackedCalls parses the packed calls layout from the packed payload.calls data.

type Path

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

func NewPath

func NewPath() *Path

func (*Path) ABI

func (p *Path) ABI(contractABI *abi.ABI, method string) *Path

func (*Path) ArgBytesData

func (p *Path) ArgBytesData(argName string) *Path

func (*Path) ArgBytesDataIndex

func (p *Path) ArgBytesDataIndex(argIndex int) *Path

func (*Path) ArgBytesEncoded

func (p *Path) ArgBytesEncoded(argName string) *Path

func (*Path) ArgSlot

func (p *Path) ArgSlot(argName string) *Path

func (*Path) ArgSlotIndex

func (p *Path) ArgSlotIndex(argIndex int) *Path

func (*Path) AsSelector

func (p *Path) AsSelector() Selector

func (*Path) CallData

func (p *Path) CallData(i int) *Path

func (*Path) EncodedCallData

func (p *Path) EncodedCallData(i int) *Path

func (*Path) EncodedCallsPayload

func (p *Path) EncodedCallsPayload() *Path

func (*Path) Resolve

func (p *Path) Resolve(payload *v3.CallsPayload) ([]ByteRange, error)

func (*Path) Slice

func (p *Path) Slice(offset uint32, size uint32) *Path

func (*Path) String

func (p *Path) String() string

type RangeSelector

type RangeSelector struct {
	Range ByteRange
}

RangeSelector is a Selector backed by a fixed ByteRange (validated on Resolve).

func NewRangeSelector

func NewRangeSelector(callIndex, offset, size int) RangeSelector

NewRangeSelector returns a Selector for an explicit call index, offset, and size within that call's data.

func (RangeSelector) Resolve

func (r RangeSelector) Resolve(payload *v3.CallsPayload) ([]ByteRange, error)

func (RangeSelector) String

func (r RangeSelector) String() string

type Selector

type Selector interface {
	Resolve(payload *v3.CallsPayload) ([]ByteRange, error)
	String() string
}

Selector resolves one or more byte ranges in a calls payload (e.g. ABI paths or fixed ranges).

type Span

type Span struct {
	Start int
	Len   int
}

Jump to

Keyboard shortcuts

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