【问题标题】:Get total amount of tokens received from a specific address using Web3.js使用 Web3.js 获取从特定地址收到的令牌总量
【发布时间】:2021-12-04 16:34:18
【问题描述】:

在一个场景中,WalletA 定期从 AddressC 接收 TokenB。 AddressC 只发送 TokenB,没有别的。

在 etherscan 或 bscscan 中,很容易查看 WalletA 中收到了多少 TokenB,并且存在“from”字段,因此您可以做一些数学运算来获得总数。

如何使用 web3 做到这一点?我在 web3 文档中找不到任何相关的 api 调用。 我可以通过 web3.js 获得 WalletA 中 TokenB 的总余额,但我需要从 AddressC 发送的令牌计数。

谢谢。

【问题讨论】:

    标签: web3js


    【解决方案1】:

    根据ERC-20 标准,每次令牌传输都会发出一个Transfer() 事件日志,其中包含发送方地址、接收方地址和令牌数量。

    您可以使用web3js通用方法web3.eth.getPastLogs()获取过去的事件日志,对输入进行编码和对输出进行解码。

    或者您可以提供合约的 ABI JSON(在这种情况下,只使用 Transfer() 事件定义就足够了)并使用 web3js 方法 web3.eth.Contract.getPastEvents(),它根据您对输入进行编码并解码输出在提供的 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();
    

    【讨论】:

    • 我认为第二个“fromblock”应该是“toblock”,并且我可以使用此代码获得输出,但由于我收到此错误,我不知道结果是否正确。 ///// Uncaught (in promise) 错误:返回错误:超出最大块范围:5000 ///// 我的 fromblock 是创建令牌的块,toblock 是当前块,它肯定高于 5000 个块。有什么解决方法可以覆盖它吗?
    • @mhmd 谢谢,我在我的回答中修复了它......“超过最大块范围”错误消​​息来自您的 RPC 提供商(Infura 或类似的)。您始终可以使用不施加这些限制的自托管节点,否则您需要寻找提供符合您需要的限制的提供商。
    • 我在 bsc 上使用 web3 和这个提供商 web3 = new Web3('bsc-dataseed.binance.org/'); ///// 你知道其他没有块范围限制的 bsc 提供者吗?
    • 或者我可以为每 5000 个块运行一个循环吗?还是它也有一些限制?
    • @mhmd 除了devs page 中列出的“官方”供应商之外,我不知道有任何第三方 BSC 供应商。在同步循环中运行,等待每个批次处理,可能会有所帮助,但随后您可能会遇到其他速率限制,例如每分钟的请求总数。对于这个规模,我真的建议运行你的own fullnode,它不会施加任何限制。
    猜你喜欢
    • 2021-12-22
    • 2018-08-02
    • 2018-08-01
    • 2021-12-24
    • 2022-07-16
    • 2021-12-05
    • 2022-05-31
    • 2021-07-31
    • 2018-06-17
    相关资源
    最近更新 更多