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:
-
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? -
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
-
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/0x7ea52aad9bd16dd39353be31ffb532d7311c474d682ea2a7f378aa8afef5ad8cSmart 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:
As far as I know, the ERC20 standard dictates the prototype of the
transfer
function, but it doesn't dictate the prototype of theTransfer
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:
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:
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:
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 aTransfer
event with the source address being zero, and thatburn
functions (also not part of the standard) emit aTransfer
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.