Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get total amount of tokens received from a specific address using Web3.js

Tags:

in a scenario, WalletA is receiving TokenB in a regular basis from AddressC. AddressC only sends TokenB, nothing else.

in etherscan or bscscan it is simple to see how much of TokenB is received in WalletA and "from" field is there so you can do some math to get total.

How can this be done using web3? I couldn't find any relevant api call in web3 documents. I can get total balance of TokenB in WalletA by web3.js but I need the count of tokens only sent from AddressC.

Thanks.

like image 356
mhmd Avatar asked Oct 17 '21 07:10

mhmd


1 Answers

As per the ERC-20 standard, each token transfer emits a Transfer() event log, containing the sender address, receiver address and token amount.

You can get the past event logs using the web3js general method web3.eth.getPastLogs(), encode the inputs and decode the outputs.

Or you can supply ABI JSON of the contract (it's enough to use just the Transfer() event definition in this case) and use the web3js method web3.eth.Contract.getPastEvents(), which encodes the inputs and decodes the outputs for you based on the provided ABI JSON.

const Web3 = require('web3');
const web3 = new Web3('<provider_url>');

const walletA = '0x3cd751e6b0078be393132286c442345e5dc49699'; // sender
const tokenB = '0xdAC17F958D2ee523a2206206994597C13D831ec7'; // token contract address
const addressC = '0xd5895011F887A842289E47F3b5491954aC7ce0DF'; // receiver

// just the Transfer() event definition is sufficient in this case
const abiJson = [{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}];
const contract = new web3.eth.Contract(abiJson, tokenB);

const fromBlock = 10000000;
const toBlock = 13453500;
const blockCountIteration = 5000;

const run = async () => {
    let totalTokensTranferred = 0;

    for (let i = fromBlock; i <= (toBlock - blockCountIteration); i += blockCountIteration) {
        //console.log("Requesting from block", i, "to block ", i + blockCountIteration - 1);
        const pastEvents = await contract.getPastEvents('Transfer', {
            'filter': {
                'from': walletA,
                'to': addressC,
            },
            'fromBlock': i,
            'toBlock': i + blockCountIteration - 1,
        });
    }

    for (let pastEvent of pastEvents) {
        totalTokensTranferred += parseInt(pastEvent.returnValues.value);
    }

    console.log(totalTokensTranferred);
}

run();
like image 178
Petr Hejda Avatar answered Sep 30 '22 19:09

Petr Hejda