1

I want to retrieve the following information from a transaction hash:

  • If that transaction is an ERC-20 transfer: if yes what erc20 was transferred, what amount and to who
  • If that transaction is an ERC-721 transfer: if yes what erc721 nft was transferred and to who

Example: https://blockscout.com/xdai/mainnet/tx/0x5f1ac5db6c0c31025ac19f6de22eef665e57262f9953567438827b339828e1a8/token-transfers

I have transferred some weth on this transaction. Now i would like to retrieve the information above from my tx hash.

This is what I am doing (using ethers.js):

        let blockchain = await Blockchain.findBy('network', 'xdai')
        let defaultProvider = await Ethers.getDefaultProvider(blockchain)

        let tx = await defaultProvider.getTransaction("0x5f1ac5db6c0c31025ac19f6de22eef665e57262f9953567438827b339828e1a8")
        let txReceipt = await defaultProvider.getTransactionReceipt("0x5f1ac5db6c0c31025ac19f6de22eef665e57262f9953567438827b339828e1a8")

Results:

{
    "tx": {
        "hash": "0x5f1ac5db6c0c31025ac19f6de22eef665e57262f9953567438827b339828e1a8",
        "blockHash": "0x4023d17a5469c9dfb13bf50a63ce40d90b07a4b8e811fdba25b063ad535ba3f2",
        "blockNumber": 21105871,
        "transactionIndex": 4,
        "confirmations": 151,
        "from": "0x52eB606f94091A2BA4f985D98C62880a9BA591B6",
        "gasPrice": {
            "type": "BigNumber",
            "hex": "0x59682f07"
        },
        "gasLimit": {
            "type": "BigNumber",
            "hex": "0x01630f"
        },
        "to": "0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1",
        "value": {
            "type": "BigNumber",
            "hex": "0x00"
        },
        "nonce": 937,
        "data": "0xa9059cbb000000000000000000000000fce3c3d51c7f3cc8c0f380be844e7cbad14c1c1d00000000000000000000000000000000000000000000000000027ca57357c000",
        "r": "0xa3ff01c0dcc17cfccf595fefe23468b80727e58003f364f793f6c8ed38da63b4",
        "s": "0x4a709844959b5858607b555a8ec66f90c76c00f10de44386ff80990737d126dd",
        "v": 1,
        "creates": null,
        "chainId": 100
    },
    "txReceipt": {
        "to": "0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1",
        "from": "0x52eB606f94091A2BA4f985D98C62880a9BA591B6",
        "contractAddress": null,
        "transactionIndex": 4,
        "gasUsed": {
            "type": "BigNumber",
            "hex": "0xead8"
        },
        "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000800000000000000000008000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000008000000000000000000000000000000000008000000000000000000010000000000000000000000000000000000000000000000044000002000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "blockHash": "0x4023d17a5469c9dfb13bf50a63ce40d90b07a4b8e811fdba25b063ad535ba3f2",
        "transactionHash": "0x5f1ac5db6c0c31025ac19f6de22eef665e57262f9953567438827b339828e1a8",
        "logs": [
            {
                "transactionIndex": 4,
                "blockNumber": 21105871,
                "transactionHash": "0x5f1ac5db6c0c31025ac19f6de22eef665e57262f9953567438827b339828e1a8",
                "address": "0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1",
                "topics": [
                    "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
                    "0x00000000000000000000000052eb606f94091a2ba4f985d98c62880a9ba591b6",
                    "0x000000000000000000000000fce3c3d51c7f3cc8c0f380be844e7cbad14c1c1d"
                ],
                "data": "0x00000000000000000000000000000000000000000000000000027ca57357c000",
                "logIndex": 21,
                "blockHash": "0x4023d17a5469c9dfb13bf50a63ce40d90b07a4b8e811fdba25b063ad535ba3f2"
            }
        ],
        "blockNumber": 21105871,
        "confirmations": 151,
        "cumulativeGasUsed": {
            "type": "BigNumber",
            "hex": "0x168b7f"
        },
        "status": 1,
        "byzantium": true
    }
}

From the transaction receipt I can see this data here:

 "logs": [
            {
                "transactionIndex": 4,
                "blockNumber": 21105871,
                "transactionHash": "0x5f1ac5db6c0c31025ac19f6de22eef665e57262f9953567438827b339828e1a8",
                "address": "0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1",
                "topics": [
                    "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
                    "0x00000000000000000000000052eb606f94091a2ba4f985d98c62880a9ba591b6",
                    "0x000000000000000000000000fce3c3d51c7f3cc8c0f380be844e7cbad14c1c1d"
                ],
                "data": "0x00000000000000000000000000000000000000000000000000027ca57357c000",
                "logIndex": 21,
                "blockHash": "0x4023d17a5469c9dfb13bf50a63ce40d90b07a4b8e811fdba25b063ad535ba3f2"
            }
        ],

But how do I find the information that I need (that are also shown on the explorer).

I would like to know what currency was transferred and the amount.

2 Answers 2

1

You can read from the log.

A good article explaining how to use events can be found here https://betterprogramming.pub/learn-solidity-events-2801d6a99a92.

To know the 'currency', or the token, you can read the smart contract that was called. The 'to', 'from' and 'amount' of the transaction are in the log. To and From are topics of the event (please refer to the article above), and the amount is in the data.

To check the function that has been called you can read from the data of the transaction. Its first 4 bytes (a9059cbb) is the signature of the function. You can check if the signature is the one for 'transfer', for example.

1
  • Thank you, I didn't notice that the address in the logs was referring to the Wrapped Ethereum smart contract.
    – Agilulfo
    Commented Mar 14, 2022 at 15:08
2

You can filter the logs in the tx receipt by topics. Something like

const erc20TransferEventHash = keccak256("Transfer(address,uint256");

const erc20Transfers = [];

const logs = txReceipt.logs.filter((log) => {
  if (log.topics[0] === erc20TranferEventHash) {
    const trasferredFrom = log.topics[1];
    const transferredTo = log.topics[2];
    const amountTrasferred = log.data;
    const token = log.address;
    erc20Transfers.push({token, amount: amountTransferred, to: transferredTo, from: transferredFrom});
  }
})

However, all of this requires you to know exactly what the event signature is, what is indexed, what is not, etc. and that way you'll know how to decode them and which topics to use for what.

You can also not do all these filterings like in the previous example on your own and rather use etc_subscribe with relevant filters so you only get the transfer events directly. Look up more info on logs and events in Ethereum.

3
  • You codded what I said in words, much better =) Commented Mar 14, 2022 at 15:15
  • 1
    @JoãoPauloMorais haha, there were no answers on this question when I started typing this answer, race conditions triggered!
    – Meet
    Commented Mar 14, 2022 at 15:16
  • Yeah, Your answer was better anyway. He can use the code. Commented Mar 14, 2022 at 23:06

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.