使用 Web3.js 获取从特定地址收到的令牌总量
Posted
技术标签:
【中文标题】使用 Web3.js 获取从特定地址收到的令牌总量【英文标题】:Get total amount of tokens received from a specific address using 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 发送的令牌计数。
谢谢。
【问题讨论】:
【参考方案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,它不会施加任何限制。以上是关于使用 Web3.js 获取从特定地址收到的令牌总量的主要内容,如果未能解决你的问题,请参考以下文章
如何在 SOLANA 上使用 web3 js 从令牌地址获取元数据
如何获取在与@solana/web3.js 的交易中转移的自定义令牌数量?