获取USDT交易的哈希值和金额

问题描述 投票:0回答:1

我是编码新手。尝试在 TRC20 和 ERC20 系统上获取 USDT 交易的哈希值和金额,而不绑定到单个钱包。

一直在尝试使用TRX和ETH原生API以及第三方API,例如QuickNode - 这给了我更好的体验,但仍然无法得到正确的结果:(

使用 QuickNode API 设法获取一些区块和 TRX 交易,但不知道如何获取它们的金额并通过合约正确过滤它们 - 换句话说,通过代币,例如 USDT。

期望能够在 TRC20 或 ERC20 生态系统上获取最新 USDT 交易的哈希值和金额,而无需将获取仅绑定到单个钱包

javascript web3js tron etherscan
1个回答
0
投票

👋🏼 这里是 QuickNode 的 DevRel 负责人

前进基础(又称前向填充)

您无需重复查询区块链或索引(轮询),而是可以使用服务来为您提供所需的数据。我们的QuickAlerts产品就是这样一种服务。

在我们的表达式库中,我们有ERC-20/TRC-20 传输的示例表达式。表达式库准确地解释了表达式的工作原理。您需要做的就是:

  1. 选择您想要监视新 USDT 转账的网络。
  2. 单击部署按钮。
  3. 设置您想要收到通知的 Webhook URL。

为了方便起见,我们提供了 有关如何使用 QuickAlerts 界面的视频指南

获取历史数据(又名回填)

在这里找到一家提供索引 API 的公司总是最容易的,尽管提供通过 ERC-20 代币或大量链进行查询的能力的公司并不多。如果您决定这样做,请找到一家支持您正在寻找的连锁店的公司,并询问他们是否可以公开这种新方法。

手动方式可能是您登陆这里的地方,因为使用像 QuickNode 这样的人,您可以访问您需要的所有链。请记住,这将需要相当多的 RPC 调用和处理,因为您将迭代许多块。

我在下面为您编写了一些代码,展示了如何在以太坊主网上完成它。您需要确保:

  1. 插入您的 RPC URL。
  2. 从小块范围开始进行实验,然后通过调整
    startingBlock
    中的
    fetchAllTransfers
    定义扩展到整个块范围。根据您正在使用的每条链上部署的 USDT 合约的区块来调整此值。
  3. 调整脚本以写入文件或数据库。正如我在脚本中所使用的那样,登录到控制台可能会很快耗尽内存。

const { Web3 } = require('web3');

// QuickNode API URL (replace with your own)
const quickNodeApiUrl = 'YOUR_QUICKNODE_API_URL';

// Initialize Web3
const web3 = new Web3(quickNodeApiUrl);

// Ethereum MainNet USDT Token Contract Address, adjust for other chains
const usdtContractAddress = '0xdAC17F958D2ee523a2206206994597C13D831ec7';

// Define the ABI for the USDT token transfer event
const usdtAbi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_upgradedAddress","type":"address"}],"name":"deprecate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"deprecated","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_evilUser","type":"address"}],"name":"addBlackList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"upgradedAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balances","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maximumFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_maker","type":"address"}],"name":"getBlackListStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowed","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getOwner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newBasisPoints","type":"uint256"},{"name":"newMaxFee","type":"uint256"}],"name":"setParams","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"issue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"redeem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"basisPointsRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isBlackListed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_clearedUser","type":"address"}],"name":"removeBlackList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_UINT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_blackListedUser","type":"address"}],"name":"destroyBlackFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_initialSupply","type":"uint256"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Issue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAddress","type":"address"}],"name":"Deprecate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"feeBasisPoints","type":"uint256"},{"indexed":false,"name":"maxFee","type":"uint256"}],"name":"Params","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_blackListedUser","type":"address"},{"indexed":false,"name":"_balance","type":"uint256"}],"name":"DestroyedBlackFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_user","type":"address"}],"name":"AddedBlackList","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_user","type":"address"}],"name":"RemovedBlackList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"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"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"}];

// Initialize the USDT Token Contract
const usdtToken = new web3.eth.Contract(usdtAbi, usdtContractAddress);

// Function to fetch transfers with pagination
const fetchTransfersPaginated = async (fromBlock, toBlock, accumulatedEvents = []) => {
    try {
        // Maximum block range to fetch in a single call, QuickNode limit for getlogs is 10,000
        const MAX_BLOCK_RANGE = 10000;

        const remainingBlocks = toBlock - fromBlock;
        const batchSize = Math.min(remainingBlocks, MAX_BLOCK_RANGE);
        const batchToBlock = fromBlock + batchSize - 1; // Inclusive range

        console.log(`Fetching transfers batch (block ${fromBlock} to ${batchToBlock})`);

        const pageEvents = await usdtToken.getPastEvents('Transfer', {
            fromBlock,
            toBlock: batchToBlock,
        });

        accumulatedEvents = accumulatedEvents.concat(pageEvents);

        if (remainingBlocks > batchSize) {
            // Fetch next batch
            return await fetchTransfersPaginated(fromBlock + batchSize, toBlock, accumulatedEvents);
        }

        return accumulatedEvents;
    } catch (error) {
        console.error('Error fetching transfers:', error);
        return accumulatedEvents; // Return accumulated events so far
    }
};

const fetchAllTransfers = async () => {
    try {
        const latestBlock = await web3.eth.getBlockNumber();

        // Switch to first definition for full run, second for testing with smaller ranges
        //const startingBlock = BigInt(4634748); // block where USDT contract was deployed on Ethereum Mainnet
        const startingBlock = latestBlock - BigInt(100); 

        console.log(`Fetching transfers form block ${startingBlock} to ${latestBlock}`);

        // Fetch transfers in batches of 10,000
        const events = await fetchTransfersPaginated(Number(startingBlock), Number(latestBlock));

        for (const event of events) {
            // Extract transaction hash and transferred amount
            const transactionHash = event.transactionHash;
            let amount = event.returnValues.value;

            if (typeof amount === 'bigint') {
              // Convert to number for division
              amount = Number(amount);
            }
            
            // Convert based on decimals (USDT has 6 decimals)
            amount = amount / 10 ** 6;

            // Log information, write this to a database or file if needed
            console.log(`Transaction Hash: ${transactionHash}`);
            console.log(`Amount Transferred: ${amount}`);
            console.log('---');
        }

        console.log('Fetched', events.length, 'transfers');

    } catch (error) {
        console.error('Error fetching transfers:', error);
    }
};


fetchAllTransfers().then(() => {
    console.log('All transfers fetched');
}).catch((error) => {
    console.error('Error:', error);
});

© www.soinside.com 2019 - 2024. All rights reserved.