Decode traces
Sync traces to a database with the contract ABI using Mirror.
This guide explains how to decode traces on-the-fly using Mirror Decoding Functions within transforms in Mirror pipelines.
What you’ll need
- A Goldky account and the CLI installed
- A basic understanding of the Mirror product
- A destination sink to write your data to. In this example, we will use PostgresSQL Sink
Preface
In this guide we are going to show how to decode traces of a contract with Goldsky Mirror. We will use as example the Friendtech contract deployed in Base but the same logic applies to any other contract and chain for which there’s an availabe Raw Traces Direct Indexing dataset as per this list.
Pipeline definition
name: decoding-traces
apiVersion: 3
sources:
my_base_raw_traces:
type: dataset
dataset_name: base.raw_traces
version: 1.0.0
transforms:
friendtech_decoded:
primary_key: id
# Fetch the ABI from basescan, then use it to decode from the friendtech address.
sql: >
SELECT
`id`,
_gs_tx_decode(
_gs_fetch_abi('https://api.basescan.org/api?module=contract&action=getabi&address=0xcf205808ed36593aa40a44f10c7f7c2f67d4a4d4', 'etherscan'),
`input`,
`output`
) AS `decoded`,
block_number,
transaction_hash
FROM my_base_raw_traces
WHERE address='0xcf205808ed36593aa40a44f10c7f7c2f67d4a4d4'
friendtech_clean:
primary_key: id
# Clean up the previous transform, unnest the values from the `decoded` object.
sql: >
SELECT
`id`,
decoded.function AS `function_name`,
decoded.decoded_inputs AS `decoded_inputs`,
decoded.decoded_outputs AS `decoded_outputs`,
block_number,
transaction_hash
FROM friendtech_decoded
WHERE decoded IS NOT NULL
sinks:
friendtech_logs:
secret_name: EXAMPLE_SECRET
type: postgres
from: friendtech_clean
schema: decoded_logs
table: friendtech
There are two important transforms in this pipeline definition which are responsible for decoding the contract; we’ll explain how they work in detail. If you copy and use this configuration file, make sure to update:
- Your
secret_name
(v2:secretName
). If you already created a secret, you can find it via the CLI commandgoldsky secret list
. - The schema and table you want the data written to, by default it writes to
decoded_logs.friendtech
.
Decoding transforms
Let’s start analyzing the first transform:
SELECT
`id`,
_gs_tx_decode(
_gs_fetch_abi('https://api.basescan.org/api?module=contract&action=getabi&address=0xcf205808ed36593aa40a44f10c7f7c2f67d4a4d4', 'etherscan'),
`input`,
`output`
) AS `decoded`,
block_number,
transaction_hash
FROM base.raw_traces
WHERE address='0xcf205808ed36593aa40a44f10c7f7c2f67d4a4d4'
Looking at the Raw Traces schema we see there are standard traces columns such as id
, block_number
and transaction_hash
. Since the columns
input
and output
are encoded we need to make use of the _gs_tx_decode to decode the data. This function takes the following parameters:
- The contract ABI: rather than specifying ABI directly into the SQL query, which would made the code considerably less legible, we have decided to make use of the _gs_fetch_abi function to fetch the ABI from the BaseScan API but you could also fetch it from an external public repository like Github Gist if you preferred.
input
: as a second argument which refer to the data sent along with the message call.output
: as a third argument which refer to the data returned by the message call.Some columns are surrounded by backticks, this is because they are reserved words in Flink SQL. Common columns that need backticks are: data, output, value, and a full list can be found here.
We are storing the decoding result in a new column called decoded
which is a nested ROW with the properties event_param::TEXT[]
and event_signature::TEXT
. We create a second transform that reads from the resulting dataset of this first SELECT query to access the decoded data:
SELECT
`id`,
decoded.function AS `function_name`,
decoded.decoded_inputs AS `decoded_inputs`,
decoded.decoded_outputs AS `decoded_outputs`,
block_number,
transaction_hash
FROM friendtech_decoded
WHERE decoded IS NOT NULL
Notice how we add a filter for decoded IS NOT NULL
as a safety measure to discard processing potential issues in the decoding phase.
Deploying the pipeline
As a last step, to deploy this pipeline and start sinking decoded data into your database simply execute:
goldsky pipeline create <pipeline_name> --definition-path <yaml_file>
Conclusion
In this guide we have explored an example implementation of how we can use Mirror Decoding Functions to decode raw logs and stream them into our PostgreSQL database.
This same methodology can be applied to any contract of interest for any chain with raw_log
and raw_traces
Direct Indexing datasets available (see list).
Goldsky also provides alternative decoding methods:
- Decoded datasets:
decoded_logs
anddecoded_traces
- Subgraphs entity sources to your pipelines.
Decoding contracts on the flight is a very powerful way of understanding onchain data and making it usable for your users.
Can't find what you're looking for? Reach out to us at support@goldsky.com for help.
Was this page helpful?