Skip to main content
This guide streams ERC-1155 transfers into your own database, including batch transfers expanded to one row per token, so single and batch movements land in the same table. This guide is part of a series of tutorials on how you can stream transfer data into your data warehouse with Turbo pipelines. Here we focus on ERC-1155 transfers; see the other guides for other transfer types:

What you’ll need

  1. A Goldsky account and the CLI installed
  1. Install the Goldsky CLI: For macOS/Linux:
    For Windows:
    Windows users need to have Node.js and npm installed first. Download from nodejs.org if not already installed.
  2. Log into your Project by running:
    This opens your browser to sign in (Google, GitHub, SSO, or email). Once you authenticate, the CLI is logged in automatically — there’s no API key to copy or paste.
    On a headless or remote machine (or in CI), create an API key on your Project Settings page and pass it directly with goldsky login --token <API_KEY>. Use goldsky login --no-browser to print the login URL instead of opening a browser.
  3. Now that you are logged in, run goldsky to get started:
  1. A basic understanding of Turbo pipelines
  2. A destination sink to write your data to. In this example, we will use the PostgreSQL sink

Introduction

There are two ways to get ERC-1155 transfers flowing:
  1. Use the readily available ERC-1155 dataset for the chain you are interested in: this is the easiest and quickest method to get you streaming token transfers into your sink of choice with minimum code.
  2. Build the ERC-1155 transfers pipeline from scratch using raw logs: this method takes more code and time to implement, but it’s a great way to learn how the decoding functions work in case you want to build more customized pipelines.
Let’s explore both methods in more detail.

Using the ERC-1155 transfers source dataset

Every EVM chain has its own ERC-1155 dataset available for you to use as a source in your pipelines. You can check this by running the goldsky dataset list command and finding the EVM chain of your choice. For this example, let’s use the apex chain and create a simple pipeline definition that writes its ERC-1155 dataset into a PostgreSQL instance:
apex-erc1155-transfers.yaml
If you copy and use this configuration file, make sure to update:
  1. Your secret_name. If you already created a secret, you can find it via the CLI command goldsky secret list.
  2. The schema and table you want the data written to; by default it writes to public.apex_erc1155_transfers.
If you use ClickHouse as the sink for this dataset, add a schema_override to avoid data precision errors for big numbers:
Deploy the pipeline by running:
That’s it! You should soon start seeing ERC-1155 token transfers in your database.

Building ERC-1155 transfers from scratch using logs

The ERC-1155 dataset we used as a source in the previous method encapsulates all the decoding logic explained in this section. Read on if you are interested in learning how it’s implemented, in case you want to extend or modify this logic yourself. To build the token transfers pipeline from scratch, use the raw_logs dataset for the chain in combination with the decoding functions and the ABI of a specific ERC-1155 contract. In this example, we will stream all the transfer events of all the ERC-1155 tokens on the Scroll chain. We dynamically fetch the ABI of the Rubyscore_Scroll token from the Scrollscan API and use it to decode the same events for every ERC-1155 token on the chain. Any other ERC-1155-compliant token’s ABI would also work. ERC-1155 combines the features of ERC-20 and ERC-721 contracts and adds a few of its own. Each transfer has both a token ID and a value representing the quantity being transferred. For tokens intended to represent NFTs the value is 1, but this depends on how the contract is implemented. ERC-1155 also introduces new event signatures for transfers: TransferSingle(address,address,address,uint256,uint256) and TransferBatch(address,address,address,uint256[],uint256[]), which lets a contract transfer multiple tokens at once to a single recipient. That batching causes us some trouble, because we want one row per transfer in the database. To keep the SQL simple, we handle single and batch transfers in separate transforms: a SQL transform for TransferSingle, and a TypeScript transform that expands each TransferBatch event into one row per token. A final SQL transform then combines both streams.

Pipeline definition

scroll-erc1155-transfers.yaml
If you copy and use this configuration file, make sure to update:
  1. Your secret_name. If you already created a secret, you can find it via the CLI command goldsky secret list.
  2. The schema and table you want the data written to; by default it writes to public.erc1155_transfers.
  3. token_id and amount are kept as strings because ERC-1155 values can be as large as an unsigned 256-bit integer. Cast them in a downstream transform, or use your sink’s schema_override, if your database has a suitable numeric type; see 256-bit integers in the Postgres sink.
Let’s walk through the transforms.

Decoding transforms

Transform: scroll_decoded
As explained in the decoding contract events guide, we use _gs_fetch_abi to get the ABI from Scrollscan and pass it as the first argument to _gs_log_decode, which decodes each log’s topics and data into a decoded struct. Filtering on the two transfer topics up front keeps the decoder from doing wasted work on unrelated logs: the first topic hash is TransferSingle(address,address,address,uint256,uint256), the second is TransferBatch(address,address,address,uint256[],uint256[]).
Transform: scroll_clean
In this second transform, we pull event_params and event_signature out of the decode result, and filter on decoded IS NOT NULL to leave out logs the decoder couldn’t match against the ABI.

Single transfers

Transform: erc1155_transfer_single
TransferSingle has the parameters (operator, from, to, id, value), and event_params is 1-indexed in SQL, so the sender is event_params[2], the recipient event_params[3], the token ID event_params[4], and the amount event_params[5]. Note that the indexes differ from the ERC-721 guide because the event signature is different.

Batch transfers

For TransferBatch, parameters 4 and 5 are arrays of token IDs and amounts, decoded into strings like [1 2 3]. We want one database row per token, so the erc1155_transfer_batch transform is a TypeScript transform that parses both arrays and returns an array of row objects; returning an array from invoke expands one input row into many output rows. It also:
  • suffixes the row index onto the event id (one batch event produces many rows, and the sink’s primary_key must stay unique), and
  • skips zero-amount entries, matching the behavior of the curated datasets.

Combining single and batch transfers

Transform: scroll_1155_transfers
The final transform unions both streams into a single table for the sink.

Deploying the pipeline

Deploy the pipeline and start sinking ERC-1155 transfer data into your database:
After some time, you should see transfer data streaming into your sink. Here’s an example transfer record:
You can speed up a backfill by increasing the pipeline’s resource_size in the YAML and re-applying it with goldsky turbo apply; see operating pipelines.

Conclusion

In this guide, we learned how Turbo simplifies streaming ERC-1155 transfer events into your database. We first looked at the easy path: using the chain’s readily available ERC-1155 dataset as the pipeline source. We then went deep on building the same stream from raw logs: decoding with _gs_fetch_abi and _gs_log_decode, handling TransferSingle in SQL, and expanding TransferBatch events into per-token rows with a TypeScript transform. Can’t find what you’re looking for? Reach out to us at support@goldsky.com for help.