0

I have an application which should work as an exchange. Customers have their own Ethereum addresses on my Geth server, and they might receive ERC20 Tokens on them. I need to fetch the incoming transaction data for multiple accounts.
I've used eth_getLogs() like this:

eth_getLogs(
   '0x9589a2',
   'latest',
   '0xdac17f958d2ee523a2206206994597c13d831ec7',
   [null, null, '0x000000000000000000000000825F80D4c229f56bf1275C9592223a9d921329E2']
);

Now, I have some questions:

  1. What are the 1st and 2nd parameters in array for? I found this sample code and used it, but unfortunately I couldn't find the appropriate document for it.
  2. I added some 0000... before address regarding to the example I found. It works now, but what is the exact value here and what is its correct format?
  3. And the main question: How can I do searches at once on multiple accounts for each ERC20 Token?
3
  • 1. fromBlock and toBlock Apr 20, 2020 at 7:42
  • 2. Apparently, a 64-character long hexadecimal string prefixed with 0x Apr 20, 2020 at 7:45
  • @goodvibration, I meant 2 null value before hex strnig in question #1. [null, null, '0x000000000000000000000000825F80D4c229f56bf1275C9592223a9d921329E2'] Apr 20, 2020 at 8:16

2 Answers 2

0

You can listen for Transfer events for all tokens. Then build your own database of all transfers you are interested in. Then match those transfers to your exchange user balances.

Poll for the events scan them again a few blocks back.

Here is some Python code: https://github.com/TokenMarketNet/sto/blob/master/sto/ethereum/scanner.py#L153

0

dev advocate at Chainstack here.

Here you can find a good explanation and examples of how to use eth_getLogs.

Those are the parameters accepted by eth_getLogs

object — the filter parameters:
fromBlock — (optional, default: latest) integer that specifies the starting block number from which the logs should be fetched.
toBlock — (optional, default: latest) integer that specifies the ending block number until which the logs should be fetched.
address — (optional) the contract address from which the logs should be fetched. It can be a single address or an array of addresses.
topics — (optional) an array of DATA topics. The event topics for which the logs should be fetched. It can be a single topic or an array of topics.
blockhash — (optional) the hash of the specific block. Limits logs to a specific block with a 32-byte hash value. It takes precedence over fromBlock and toBlock.

To answer your question, the first 2 elements you have in the code snippet are the fromBlock and toBlock fields.

So you can use eth_getLogs to find Transfer events on the USDT contract to specific addresses; here is how you can do it using ethers.js

const { ethers } = require("ethers");

const providerUrl =
  "NODE_URL";

// Connect to the Ethereum network
const provider = new ethers.providers.JsonRpcProvider(providerUrl);

// ERC20 Contract Address (e.g., Tether USDT)
const contractAddress = "0xdAC17F958D2ee523a2206206994597C13D831ec7";

// ERC20 ABI (Simplified for Transfer event)
const erc20Abi = [
  "event Transfer(address indexed from, address indexed to, uint amount)",
];

// Create a new contract instance
const contract = new ethers.Contract(contractAddress, erc20Abi, provider);

// Define the addresses to monitor for incoming transfers
const addresses = [
  "0x27567cf7319c5eE35cf1E4D32F02E235359005c4",
  "0xabBBA3AB9F09eA8713FD5bf60A0D580A7503FA2F",
  "0x68a5E773A11DEC57645a7567943f3644e4B7979c",
];

// Optionally, specify the block range (startBlock and endBlock)
const startBlock = 18636486; // Start block number
const endBlock = 18636487; // Use 'latest' for the most recent block

// Function to fetch and log transfer events for a given address
async function fetchTransferEvents(toAddress) {
  const filter = {
    fromBlock: startBlock,
    toBlock: endBlock,
    address: contractAddress,
    topics: [
      ethers.utils.id("Transfer(address,address,uint256)"),
      null,
      ethers.utils.hexZeroPad(toAddress, 32), // Pad the address to 32 bytes
    ],
  };

  try {
    const logs = await provider.getLogs(filter);
    logs.forEach((log) => {
      const parsedLog = contract.interface.parseLog(log);
      console.log(
        `Transfer to ${toAddress}: From ${
          parsedLog.args.from
        } Amount: ${parsedLog.args.amount.toString()}`
      );
    });
  } catch (err) {
    console.error(`Error fetching logs for address ${toAddress}:`, err);
  }
}

// Fetch transfer events for each address
addresses.forEach(fetchTransferEvents);

This will get the transfers of USDT going to the addresses in the array during the specified block range.

// Define the addresses to monitor for incoming transfers
const addresses = [
  "0x27567cf7319c5eE35cf1E4D32F02E235359005c4",
  "0xabBBA3AB9F09eA8713FD5bf60A0D580A7503FA2F",
  "0x68a5E773A11DEC57645a7567943f3644e4B7979c",
];

// Optionally, specify the block range (startBlock and endBlock)
const startBlock = 18636486; // Start block number
const endBlock = 18636487; // Use 'latest' for the most recent block

In this case, giving you this result:

Transfer to 0x27567cf7319c5eE35cf1E4D32F02E235359005c4: From 0x56Eddb7aa87536c09CCc2793473599fD21A8b17F Amount: 751200000
Transfer to 0x68a5E773A11DEC57645a7567943f3644e4B7979c: From 0x15e308914f9B7d3b072fE881FdB0d0B6cB5cb6da Amount: 1897000000
Transfer to 0xabBBA3AB9F09eA8713FD5bf60A0D580A7503FA2F: From 0xf89d7b9c864f589bbF53a82105107622B35EaA40 Amount: 21250000000

If you want to listen to live events instead, you should use subscriptions. You can find examples here: subscribe("logs").

Feel free to reach out if you have any questions!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.