Have you ever tried programmatically figuring out exactly what happened in an Ethereum transaction using just a transaction hash? While it might seem simple at first, the reality can be much more complicated depending on your use case.
Simplest Scenario | Normal Scenario | |
---|---|---|
Number of contracts | 1 well‑known contract | Many unknown contracts & third‑party libraries |
Needed ABIs | 1–2 static ABIs | Dozens of ABIs, fetched dynamically, unknown in advance |
Interactions | Minimal | Includes token transfers, calls to other contracts, multicalls etc |
Typical examples | Transfers of a single token | DEX swaps, NFT marketplace trade, bridge, deposits etc |
This quick comparison highlights how decoding complexity grows when you move from a single‑contract world to the wild, multi‑contract reality of most on‑chain activity.
Let’s take a closer look at why getting context about EVM transactions is hard in the first place.
When you query an RPC endpoint, you only receive raw blockchain data. Without extra context—such as which smart contracts were involved or which tokens and NFTs moved—you can’t really understand what happened. In short, RPC data alone isn’t enough to interpret a transaction.
Smart contracts—including tokens and NFTs—can be surprisingly tricky. They may use proxies (contracts that delegate calls to other contracts), custom logic, or non‑standard patterns. Some are unverified, so their ABI—the interface you need to decode them—isn’t publicly available. Without these details, decoding becomes more challenging.
Even popular standards like ERC‑20 or ERC‑721 are not always strictly followed. Developers can tweak contracts, changing event names or function signatures, or create completely new standards. As a result, you’ll encounter unusual patterns in blockchain data that don’t follow the textbook rules, yet you still need to handle them.
Existing decoding tools come with serious limitations:
Most people rely on third‑party APIs, which are closed‑source, so you can’t host, modify, or extend them yourself.
API‑based services often support only a some set of chains they choose.
With all these challenges in mind, what if you don’t want to rely on a third‑party API and instead want to programmatically understand what happened in a transaction yourself? Here’s what that process looks like:
Retrieve raw transaction data from Ethereum RPC nodes—logs, receipts, and execution traces.
Handle differences between RPC nodes, which may return data in varying formats.
Locate the ABIs or function signatures for every contract involved in the transaction. Handle such things like various types of proxies, multicalls, and unverified contracts.
Using those ABIs, decode logs, calldata, and traces. Handle nested, tree‑like calldata and traces structures; you may need to fetch additional ABIs as you traverse the tree.
Detect and correctly decode token or NFT transfers, even when non‑standard methods are used.
Extract native ETH transfers, which appear only in execution traces.
If the transaction was reverted, decode the error message.
Add caching, retries, and other optimizations to stay within rate limits, lower RPC costs, and speed up ABI lookups.
Continuously update your decoder to support new standards (e.g., Account Abstraction) and common protocol quirks.
Finally, interpret all this decoded context and present it in a meaningful way.
I ran into all of these problems myself and wanted something better than to use a closed‑source, limited third‑party API. So we built Loop Decoder—a TypeScript library that simplifies transaction decoding and turns any EVM transaction hash into a clear, human‑readable format.
In the next posts, I’ll dive into how Loop Decoder works under the hood and explain why we built it on top of Effect TS library.
Links:
Have you ever tried programmatically figuring out exactly what happened in an Ethereum transaction using just a transaction hash? While it might seem simple at first, the reality can be much more complicated depending on your use case.
Simplest Scenario | Normal Scenario | |
---|---|---|
Number of contracts | 1 well‑known contract | Many unknown contracts & third‑party libraries |
Needed ABIs | 1–2 static ABIs | Dozens of ABIs, fetched dynamically, unknown in advance |
Interactions | Minimal | Includes token transfers, calls to other contracts, multicalls etc |
Typical examples | Transfers of a single token | DEX swaps, NFT marketplace trade, bridge, deposits etc |
This quick comparison highlights how decoding complexity grows when you move from a single‑contract world to the wild, multi‑contract reality of most on‑chain activity.
Let’s take a closer look at why getting context about EVM transactions is hard in the first place.
When you query an RPC endpoint, you only receive raw blockchain data. Without extra context—such as which smart contracts were involved or which tokens and NFTs moved—you can’t really understand what happened. In short, RPC data alone isn’t enough to interpret a transaction.
Smart contracts—including tokens and NFTs—can be surprisingly tricky. They may use proxies (contracts that delegate calls to other contracts), custom logic, or non‑standard patterns. Some are unverified, so their ABI—the interface you need to decode them—isn’t publicly available. Without these details, decoding becomes more challenging.
Even popular standards like ERC‑20 or ERC‑721 are not always strictly followed. Developers can tweak contracts, changing event names or function signatures, or create completely new standards. As a result, you’ll encounter unusual patterns in blockchain data that don’t follow the textbook rules, yet you still need to handle them.
Existing decoding tools come with serious limitations:
Most people rely on third‑party APIs, which are closed‑source, so you can’t host, modify, or extend them yourself.
API‑based services often support only a some set of chains they choose.
With all these challenges in mind, what if you don’t want to rely on a third‑party API and instead want to programmatically understand what happened in a transaction yourself? Here’s what that process looks like:
Retrieve raw transaction data from Ethereum RPC nodes—logs, receipts, and execution traces.
Handle differences between RPC nodes, which may return data in varying formats.
Locate the ABIs or function signatures for every contract involved in the transaction. Handle such things like various types of proxies, multicalls, and unverified contracts.
Using those ABIs, decode logs, calldata, and traces. Handle nested, tree‑like calldata and traces structures; you may need to fetch additional ABIs as you traverse the tree.
Detect and correctly decode token or NFT transfers, even when non‑standard methods are used.
Extract native ETH transfers, which appear only in execution traces.
If the transaction was reverted, decode the error message.
Add caching, retries, and other optimizations to stay within rate limits, lower RPC costs, and speed up ABI lookups.
Continuously update your decoder to support new standards (e.g., Account Abstraction) and common protocol quirks.
Finally, interpret all this decoded context and present it in a meaningful way.
I ran into all of these problems myself and wanted something better than to use a closed‑source, limited third‑party API. So we built Loop Decoder—a TypeScript library that simplifies transaction decoding and turns any EVM transaction hash into a clear, human‑readable format.
In the next posts, I’ll dive into how Loop Decoder works under the hood and explain why we built it on top of Effect TS library.
Links:
I’m stoked to share that Loop Decoder - the dev library I’m building - just made it onto the @optimism Retro Funding list! What does that mean? Loop Decoder is one of 72 open‑source tools recognized for boosting developer experience and protocol security - and it’s now eligible for a retroactive grant 🎉 I’m also kicking off a post series on why and how I’m building it - here’s Post #1 explaining the problem it solves. https://paragraph.com/@nastyacodes/why-decoding-ethereum-transactions-is-hard?referrer=0x6C994eEF6fdbeE8BCFF9016B7CE3A53b489Ad155 https://x.com/Optimism/status/1918378918442402289
Congrats @nastya that’s amazing news!
gg congrats. Just remembered the onchain alerts bot repo you created helped me build a nft mint alert bot. Thanks for building cool stuff!
I’m stoked to share that Loop Decoder - the dev library I’m building - just made it onto the @optimism Retro Funding list! What does that mean? Loop Decoder is one of 72 open‑source tools recognized for boosting developer experience and protocol security - and it’s now eligible for a retroactive grant 🎉 I’m also kicking off a post series on why and how I’m building it - here’s Post #1 explaining the problem it solves. https://paragraph.com/@nastyacodes/why-decoding-ethereum-transactions-is-hard?referrer=0x6C994eEF6fdbeE8BCFF9016B7CE3A53b489Ad155 https://x.com/Optimism/status/1918378918442402289
Congrats @nastya that’s amazing news!
thank you!
Let’s goooooo!! Congrats!!!!
thank you!
Awesome, congrats!!! 🎉🎉🎉
yayay congrats!
FIRE SHIT LOVE IT 🔥🔥🔥🔥
thanks 😃
awesome news, well deserved!
gg congrats. Just remembered the onchain alerts bot repo you created helped me build a nft mint alert bot. Thanks for building cool stuff!
OMG glad to hear!
wow incredible!
Congrats!
thanks Nikolaii!
1000 $degen