Skip to main content
Understanding how parameters are encoded into calldata is essential for working with smart contracts at a low level.

ABI Encoding Overview

The Contract ABI (Application Binary Interface) defines how to encode function calls and data. Every parameter is encoded to exactly 32 bytes (256 bits), with specific rules for different types.

Encoding Structure

Static parameters: Fixed-size types encoded in-place Dynamic parameters: Variable-size types with pointer + data

Basic Type Encoding

Integers (uint/int)

Integers are left-padded with zeros to 32 bytes:
Smaller integer types follow the same padding:

Addresses

Addresses are 20 bytes, left-padded to 32 bytes:

Booleans

Booleans encoded as uint256:
  • false0x0000...0000
  • true0x0000...0001

Fixed-Size Bytes (bytes1-bytes32)

Fixed bytes are right-padded with zeros:

Dynamic Type Encoding

Dynamic types (strings, bytes, arrays) use offset-based encoding:
  1. Static section contains offset pointer (32 bytes)
  2. Offset points to start of dynamic data
  3. Dynamic data starts with length, followed by content

Dynamic Bytes

Offset: Points to where length starts (byte 32 after selector) Length: Number of bytes in the data Data: Right-padded to 32-byte boundary

Strings

Strings encoded identically to bytes:

Arrays

Fixed-Size Arrays

Fixed arrays encoded like multiple static parameters:

Dynamic Arrays

Dynamic arrays use offset + length + elements:

Complex Encoding

Multiple Parameters

With multiple parameters, dynamic types use offsets relative to start of parameters section:
Offset calculation: Skip static params (2 * 32 = 64) + 32 for offset itself = 96 bytes (0x60)

Structs (Tuples)

Structs encoded as if all fields were separate parameters:

Nested Arrays

Arrays of dynamic types require nested offsets:

Manual Encoding (Zig)

Encoding Rules Summary

Decoding Process

Decoding reverses the encoding:

Validation

Always validate encoded calldata:

Gas Optimization Tips

  1. Use smaller types: uint96 instead of uint256 when possible
  2. Minimize dynamic data: Fixed arrays cheaper than dynamic
  3. Pack structs: Group small values to reduce padding
  4. Order parameters: Put dynamic types last to simplify offsets

See Also