1

Given a transaction of type types.Transaction (golang go-ethereum), how can I analyze the data field and check if it has a swap or a sync event? I know that 0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1 is Uniswap v2's Sync(uint112,uint112) but how can I extract the topics out of the transaction's data to check if it is present?

Context: I am looking at Arbitrum's WS sequencer feed, so the tx has not yet been published on chain and I cannot query the logs.

2 Answers 2

1

types.Transaction does not hold any events, or any post-block-inclusion information. But types.Receipt does. You can get the receipt of a transaction pretty easily from its hash (only if the transaction has already been included in a block):

package main

import (
    "context"

    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/ethclient"
)

func getTransactionReceipt(ethClient *ethclient.Client, tx *types.Transaction) (*types.Receipt, error) {
    return ethClient.TransactionReceipt(context.Background(), tx.Hash())
}

The Logs property on types.Receipt holds all the events for that transaction, represented by the types.Log types, which itself has a Topics member, holding the topics:

package main

import (
    "context"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/ethclient"
)

var uniV2SyncTopic = common.HexToHash("0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1")

func handleUniV2SyncEvents(ethClient *ethclient.Client, tx *types.Transaction) {
    txReceipt, err := ethClient.TransactionReceipt(context.Background(), tx.Hash())
    if err != nil {
        // handle the error
    }

    for _, log := range txReceipt.Logs {
        if log.Topics[0] == uniV2SyncTopic {
            // do something with the log
        }
    }
}
1
  • In my case the tx has not already been included in the block, I am looking at the WS feed from Arbitrum Sequencer. Aug 10, 2023 at 7:02
1

Take under note that I'm the author of this package and that it's still not fully completed (not in main, missing tests, etc...)

You can see the code of how to unpack logs here: https://github.com/unpackdev/solgo/tree/liquidity/bytecode

Specifically take a look here: https://github.com/unpackdev/solgo/blob/liquidity/bytecode/log.go

What you need to do is following:

Everything you need starts with types.Receipt. Once you have transaction, you need to fetch receipt. Within receipt, you'll have status if transaction executed successfully including types.Log.

  • Within logs, there are topics. 0th topic is signature.
  • Remaining of the topics will be related to arguments that are passed within the event/signature.
  • log.Data basically the event data payload.

Now you need to be aware of one crucial thing. Logs within transaction can be and usually are related to different contracts. Each log has Address entry and you'll need to have ABI for that contract in order to properly and safely decode the log.

Example code:

func (p *TransactionsProcessor) decodeLogs(entry *TransactionEntry) error {
    if len(entry.Receipt.Logs) == 0 {
        return nil
    }

    for _, log := range entry.Receipt.Logs {
        if logContract, ok := entry.LogContracts[log.Address]; ok {
            logEntry, err := logContract.DecodeLog(p.ctx, log)
            if err != nil {
                zap.L().Error(
                    "failed to decode log",
                    zap.Error(err),
                    zap.Any("network_id", entry.NetworkID),
                    zap.String("network", entry.Network.String()),
                    zap.Any("strategy", entry.Strategy),
                    zap.Uint64("block_number", entry.BlockHeader.Number.Uint64()),
                    zap.String("tx_hash", entry.Transaction.Hash().String()),
                    zap.Uint("log_index", log.Index),
                    zap.String("log_address", log.Address.String()),
                )
                continue
            }

            entry.Logs = append(entry.Logs, logEntry)
        }
    }

    return nil
}

https://github.com/unpackdev/solgo/blob/a118d2fec19b1a1d9f2331095e948bca94595b27/observers/transactions.go#L365

Hope this helps!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.