Skip to main content
Function decoding transforms raw transaction calldata into structured, typed rows. When configured, the pipeline matches each transaction’s input data against ABI function signatures and produces decoded rows in {chain_name}_fn_{function_name} tables.

How It Works

  1. The normalizer produces rows for the transactions table, each containing an input_data field (hex-encoded calldata)
  2. The decoder matches the first 4 bytes of input_data (the function selector) against ABI function entries
  3. Parameters are decoded from input_data[4:] using ABI type definitions
  4. Each decoded call is emitted to a {chain_name}_fn_{function_name_snake_case} table
Only function ABI entries with stateMutability of nonpayable or payable are used. View and pure functions are excluded since they do not appear in transaction calldata.

Output Schema

Each decoded function table includes envelope columns from the source transaction plus the ABI-defined parameters:
ColumnTypeSource
block_heightUINT64From transactions envelope
block_signed_atTIMESTAMPFrom transactions envelope
tx_hashSTRINGFrom transactions envelope
tx_offsetUINT32From transactions envelope
from_addressSTRINGFrom transactions envelope
to_addressSTRINGFrom transactions envelope
valueSTRINGFrom transactions envelope
gas_limitUINT64From transactions envelope
receipt_statusSTRINGFrom transactions envelope
(ABI parameters)(mapped type)Decoded from calldata

Example

For an ERC-20 transfer function call on Base:
function transfer(address to, uint256 amount) external returns (bool);
The output table base_fn_transfer would contain:
ColumnType
block_heightUINT64
block_signed_atTIMESTAMP
tx_hashSTRING
tx_offsetUINT32
from_addressSTRING
to_addressSTRING
valueSTRING
gas_limitUINT64
receipt_statusSTRING
toSTRING
amountSTRING

Configuration

Function decoding is activated by setting the abi section in your pipeline config and using a transactions topic entity:
topic: "base.mainnet.ref.block.transactions"

abi:
  path: "/etc/pipeline-api/erc20.json"
  contract_addresses:
    - "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
  unmatched: "skip"
Contract address filtering matches against the to_address field (the contract being called).

When to Use Function Decoding vs Event Decoding

Event DecodingFunction Decoding
Sourcelogs topic entitytransactions topic entity
DecodesEmitted event logsTransaction calldata
Output tables{chain_name}_evt_{name}{chain_name}_fn_{name}
Best forTracking state changes, transfers, approvalsAnalyzing what functions were called and with what parameters
Includes failed txsNo (failed txs don’t emit events)Yes (calldata exists even if tx reverted)
Most use cases are better served by event decoding. Use function decoding when you specifically need to analyze calldata - for example, tracking MEV bot calls, analyzing governance proposals, or monitoring specific function invocations regardless of success.