[Ethereum] Web3js – Internal Transaction Data (Event Logs): Token Transfers, Contract Creations, & Internal ETH Transfers

erc-20etherscaneventsinternal-transactionsweb3js

I'm currently recording transaction data via Web3js, while directly connected to a local Geth full archive node via IPC, and I was wondering if there was a more elegant way to record internal transaction data (aka 'Event Logs' according to Etherscan.io).

More specifically I'm looking to record ALL ERC-20 token transfers, internal contract creations, and internal transactions (for ex: ETH returned to addresses from Smart Contracts such as CEX / DEX wallets, Primablock, etc).

As of now I'm able to retrieve both ERC-20 token transfers & some internally created contracts using the code snippet posted towards the bottom of this post.


I wasn't entirely sure of three things:

  1. Are all ERC-20 token transfers are listed with the "0xddf252…"
    sha3 hash, and would the below code suffice for accurately capturing those transfers? Is there a separate function for new tokens minted, or is it safe to assume all newly minted tokens come from the '0x000000…' address?

  2. Is there a specific sha3 hash associated with contract created internally?
    The 'contractInternalHash = 0xef4c86' value below is associated with
    new smart contract (new wallet) creations from the Bittrex exchange, however, I'm more
    specifically looking to log everything with a 'create_0' Type Trace
    Address as shown in the below Etherscan link:

    https://etherscan.io/tx/0x1164ea62dc6ac087d9d4802a1a0fae6b366b292cd896ed69ec42f290418a7d2d#internal

  3. Lastly, how do I record ETH transfers sent as Internal Transactions?
    Two examples below: a DEX ETH transfer & a smart contract ETH
    transfer, both have different 'Event Logs' according to Etherscan
    yet have a similar 'call_0' format under the 'Internal Transactions'
    tab.

    DEX ETH transfer:
    https://etherscan.io/tx/0x7ea52aad9bd16dd39353be31ffb532d7311c474d682ea2a7f378aa8afef5ad8c

    Smart Contract ETH transfer:
    https://etherscan.io/tx/0xf24b9c6de3f184bc729cf68193122b5d23f4517023824c049439d5e25d69fea6

Thanks


web3.eth.getTransactionFromBlock(i,j).then(function(v){
   web3.eth.getTransactionReceipt(v.hash).then(function(r){

      tokenTransferHash = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef'
      contractInternalHash = '0xef4c8685c12779a52dae7549eb7defa8523f67a054ad425b877a6b2da469a331'

         for (var k = 0; k < r.logs.length; k++) {
            if((r.logs[k].topics[0] == tokenTransferHash) && (r.logs[k].topics.length == 3)) {

               //Code to Process ERC-20 Token Transfer Data
            }

            if(r.logs[k].topics[0] == contractInternalHash) {

               //Code to Process Internal Contract Creations
            }
         }
   }).catch(function(e) {
        console.log(e);
   });
}).catch(function(e) {
     console.log(e);
});

Best Answer

To answer the first part of your first question:

Are all ERC-20 token transfers are listed with the "0xddf252..." sha3 hash, and would the below code suffice for accurately capturing those transfers?

As far as I know, the ERC20 standard dictates the prototype of the transfer function, but it doesn't dictate the prototype of the Transfer event (or even the fact that this function should emit an event to begin with).

I might be wrong here, as evidently, OpenZeppelin have declared this event in their IERC20 interface:

event Transfer(address indexed from, address indexed to, uint256 value);

In either case, even if this event is not part of the ERC20 standard, it is widely acceptable to rely on it being emitted as a result of ERC20-token transfer operations.

A technical suggestion:

If you're using web3.js v1.x, then I recommend that you use this instead of that hard-coded value:

const tokenTransferHash = Web3.utils.keccak256("Transfer(address,address,uint256)");

Of course, you can initialize it once (i.e., in global scope, outside of any function).


To answer the second part of your first question:

Is there a separate function for new tokens minted, or is it safe to assume all newly minted tokens come from the '0x000000...' address?

The ERC20 standard does not state that a mint function should be implemented to begin with.

So any ERC20-token contract which implements this function, is in fact extending the standard.

That said, it is widely acceptable that mint functions emit a Transfer event with the source address being zero, and that burn functions (also not part of the standard) emit a Transfer event with the target address being zero.

Of course, you should not rely on this fact without verifying it in the implementation of the contract that you're targeting.

Related Topic