> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dune.com/llms.txt
> Use this file to discover all available pages before exploring further.

# EIP-8021 calldata table function

> Parse EIP-8021 builder codes from calldata with the `functions.base_l2.call_data_8021` table function.

# EIP-8021 calldata table function

[EIP-8021](https://eips.ethereum.org/EIPS/eip-8021) defines a standard for embedding builder identification codes at the end of transaction calldata.

Dune exposes this as the table function `functions.base_l2.call_data_8021`. It reads calldata from an input table, keeps the input columns, and adds parsed EIP-8021 fields for rows that contain a valid EIP-8021 suffix.

Rows without the EIP-8021 suffix are omitted from the result.

## Syntax

```sql theme={null}
SELECT *
FROM TABLE(functions.base_l2.call_data_8021(
  input => TABLE(<query>),
  calldata => DESCRIPTOR(<calldata_column>)
))
```

## Arguments

* `input`: The input table or subquery that contains a calldata column.
* `calldata`: Optional descriptor pointing to the calldata column in `input`.
  If omitted, the function looks for a column named `calldata`.

The referenced calldata column must be `varchar`.

## Output columns

The table function passes through the original input columns and adds:

| Column                    | Type             | Description                                                                                                             |
| ------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `original_tx_data`        | `varchar`        | Original calldata without the EIP-8021 suffix                                                                           |
| `schema_type`             | `varchar`        | Parsed schema label: `Schema 0: Canonical Registry`, `Schema 1: Custom Registry`, `Schema 2: CBOR`, or `Unknown Schema` |
| `codes_hex`               | `varchar`        | Builder codes as hex                                                                                                    |
| `custom_registry_address` | `varchar`        | Custom registry address for schema 1, otherwise `NULL`                                                                  |
| `codes_readable`          | `varchar`        | UTF-8 decoded builder codes                                                                                             |
| `codes_array`             | `array(varchar)` | Builder codes split into an array                                                                                       |
| `cbor_data`               | `varchar`        | JSON representation of schema 2 CBOR payloads                                                                           |
| `erc_8021_suffix`         | `varchar`        | The EIP-8021 magic bytes suffix                                                                                         |

## Examples

### Parse transaction calldata from `base.transactions`

```sql theme={null}
SELECT
  tx_hash,
  block_time,
  schema_type,
  codes_readable,
  codes_array
FROM TABLE(functions.base_l2.call_data_8021(
  input => TABLE(
    SELECT
      hash AS tx_hash,
      block_time,
      cast(data as varchar) AS calldata
    FROM base.transactions
    WHERE block_time >= now() - interval '7' day
  )
))
LIMIT 100
```

### Use the default `calldata` column name

```sql theme={null}
SELECT
  tx_hash,
  schema_type,
  codes_readable
FROM TABLE(functions.base_l2.call_data_8021(
  input => TABLE(
    VALUES
      (
        '0xdeadbeef',
        '0x722c6182000000000000000000000000000000000000000000000000000000000000000163625f77616c6c6574090080218021802180218021802180218021'
      )
  ) AS t(tx_hash, calldata)
))
```

### Override the calldata column name

```sql theme={null}
SELECT
  tx_hash,
  schema_type,
  codes_readable
FROM TABLE(functions.base_l2.call_data_8021(
  input => TABLE(
    VALUES
      (
        '0xdeadbeef',
        '0x722c6182000000000000000000000000000000000000000000000000000000000000000163625f77616c6c6574090080218021802180218021802180218021'
      )
  ) AS t(tx_hash, call_data),
  calldata => DESCRIPTOR(call_data)
))
```

### Parse schema 2 CBOR calldata

```sql theme={null}
SELECT
  schema_type,
  codes_readable,
  codes_array,
  cbor_data
FROM TABLE(functions.base_l2.call_data_8021(
  input => TABLE(
    VALUES
      (
        '0xabcda26161656d796170706177686d7977616c6c657400140280218021802180218021802180218021'
      )
  ) AS t(calldata)
))
```

### Filter for a specific builder code

```sql theme={null}
SELECT
  tx_hash,
  block_time,
  codes_readable
FROM TABLE(functions.base_l2.call_data_8021(
  input => TABLE(
    SELECT
      hash AS tx_hash,
      block_time,
      cast(data as varchar) AS calldata
    FROM base.transactions
    WHERE block_time >= now() - interval '7' day
  )
))
WHERE contains(codes_array, 'cb_wallet')
LIMIT 100
```

## Supported schema types

* **Schema 0: Canonical Registry**: Builder codes plus the EIP-8021 suffix
* **Schema 1: Custom Registry**: Builder codes plus a custom registry address
* **Schema 2: CBOR**: CBOR-encoded builder metadata exposed through both `codes_*` fields and `cbor_data`

## EIP-8021 suffix structure

Schema 0 and schema 1 are parsed from the end of calldata in this order:

| Component        | Size     | Description                                |
| ---------------- | -------- | ------------------------------------------ |
| Builder codes    | Variable | UTF-8 encoded builder identification codes |
| Registry address | 20 bytes | Only present for schema 1                  |
| Codes length     | 1 byte   | Length of the builder code payload         |
| Schema ID        | 1 byte   | `0x00` or `0x01`                           |
| Magic bytes      | 16 bytes | `0x80218021802180218021802180218021`       |

Schema 2 uses:

| Component    | Size     | Description                          |
| ------------ | -------- | ------------------------------------ |
| CBOR payload | Variable | CBOR map containing builder metadata |
| CBOR length  | 2 bytes  | Length of the CBOR payload           |
| Schema ID    | 1 byte   | `0x02`                               |
| Magic bytes  | 16 bytes | `0x80218021802180218021802180218021` |

## Use Cases

* **Builder attribution**: Track which wallet or tool produced a transaction
* **Wallet analytics**: Measure adoption of builder codes across applications
* **ERC-4337 analysis**: Parse builder metadata from UserOperation calldata
* **Schema research**: Compare canonical registry, custom registry, and CBOR-based usage

## Notes

* The function currently expects calldata as `varchar`, not `varbinary`
* If your source column is `varbinary` (for example `base.transactions.data`), cast it to `varchar` before passing it into the table function
* Input rows without the EIP-8021 magic bytes are filtered out of the result
* Builder codes are typically comma-separated identifiers such as `cb_wallet`
