1

web3 API has method getBalance. How does it work? geth just calculates and cache balances of all addresses, i.e. it works as block explorer? Or there is some magic?

How fast is getBalance? Can I make 100 requests per second to one geth instance?

1

I'm writing code that uses the RPC to query the node using C++. The goal of my code is to get the data as quickly as I can, so I've done some basic performance testing.

In general, I'm finding that the RPC is quite slow in itself relative to say caching the data (obviously), but I'm finding that certain functions are clearly faster than others. I initially thought that getBalance would be one of the slower functions, but I'm not finding it to be slow at all.

Of course, the only way for you to figure it out for your particular case is to write a simple test case and time it directly.

Concerning how it works, I'm not sure I understand your question exactly, but I am certain the node is querying a block explorer. Given its speed, I would guess the node holds balances for every account at every block (storing only changed values, of course). I doubt that the node recalculates balances each time it's requested, otherwise it would be much slower, I would think.

  • Hi. Thank you for sharing the results. Do you have any numbers from your tests? What 'slow' and 'fast' mean? – Victor Mezrin Jun 6 '17 at 23:15
  • 2
    No formal numbers, but I was hitting the node's RPC using C++ and 'curl' and it was maxed out at about 120 calls per second for the getBlock call. I would imagine the getBalance call is faster, but I didn't test that explicitly. – Thomas Jay Rush Jun 7 '17 at 2:34
1

https://twitter.com/rstormsf/status/1110250992111476737

How to optimize ethereum infura queries

Stop using web3.eth.getBalance or token.balanceOf if you need to get balance for more than 5 ethereum addresses.

Use the power of solidity to get any necessary data from ethereum blockchain.

Checkout this video tutorial: https://youtu.be/pL1dZhodxvI

Example:
Query eth balances and erc20 token balances in batches.

We need solidity contract:

pragma solidity >=0.4.22 <0.6.0;
interface ERC20 {
    function balanceOf(address owner) external view returns (uint256);
}
contract BalanceOracle {

    function exploreBalances(address[] calldata users) external view returns(uint256[] memory balances) {
        balances = new uint256[](users.length);
        for(uint i = 0; i < users.length; i++) {
            balances[i] = users[i].balance;
        }
    }

    function erc20Balances(address _token, address[] calldata users) external view returns(uint256[] memory balances) {
        ERC20 erc20 = ERC20(_token);
        balances = new uint256[](users.length);
        for(uint i = 0; i < users.length; i++) {
            balances[i] = erc20.balanceOf(users[i]);
        }
    }
}

Javascript example:

const ethers = require('ethers')
const {formatEther} = ethers.utils
const fs = require('fs')
let provider = new ethers.providers.InfuraProvider('mainnet')

const abi = [
    "function exploreBalances(address[] users) external view returns (uint256[] balances)"
]

const BALANCE_ORACLE_ADDRESS = "0x292c4fc2198998d2dc38ac1f302fddf843abbaa3"
const contract = new ethers.Contract(BALANCE_ORACLE_ADDRESS, abi, provider)

async function main() {
    let addresses = fs.readFileSync('./addresses.csv', {encoding: 'utf8'})
    addresses = addresses.split('\n')
    let balances = await contract.exploreBalances(addresses)
    let addressesWithBalances = []
    balances.forEach((balance, index) => 
        {
            return addressesWithBalances.push({
                address: addresses[index], balance: formatEther(balance)
            })
        }
    )

    console.log(addressesWithBalances)

}

main()

Profit!

Sponsored by https://peppersec.com

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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