If I have a token address how can I navigate and find certain things like:

  • tokenholder addresses
  • transactions for the token holders including when they made the transaction

I'm new to smart contracts and solidity and the whole ethereum development world so I may be asking a fairy simple question.

I'm wondering if the token address might have member variables such as a mapping for token holders and if so does the token holder have a log of the transactions they made?

Thank you!

4 Answers 4


I am own searching best way to do it because I consider the way I use is complicated a bit. But approach could be usefull for you if you don't have any solution yet. At least it works

As I know there are two ways to distinct etherium data:

If you use IPCProvider (e.g geth):

  • take all transaction of your token filtering it

    filter = web3.eth.filter({ 'fromBlock': _min_block, 'toBlock': _max_block, 'address':ERC20address }) tx_list = filtering.get(only_changes=False)'

    more about filterring here: https://web3py.readthedocs.io/en/stable/filters.html

  • tx_list is the list of transactions with participating defined ERC20 — iterate it to extract addresess and timestamp (time when they made it). Note: transaction entire doesn't contain timstamp, but you can get it through timestamp of block this transaction.

    raw_addresses_list = [] for tx in tx_list: from_ = tx['topics'][1] to_= tx['topics'][2] raw_addresses_list.extend([from_,to_]) timestamp = web3.eth.getBlock(tx['blockHash'])['timestamp'] unique_addresses = set(raw_addresses_list)

If you use HTTPprovider (e.g infura):

it's a bit more complicated since infura doesn't support filter method

  • take all transaction of your token through iterating all blocks for block in range(_min_block,_max_block+1)): block_data = web3.eth.getBlock(block) for tx in block_data['transactions']: tx = web3.eth.getTransaction(tx) input_ = tx['input'].split(delimeter) from_ = tx['from'] to_ = input_ [0][10:] timestamp = block_data['timestamp']
  • I was wondering how can I set the value for _min_block and _max_block in your code snippet?
    – Somdip Dey
    Apr 5 at 16:44

(Almost all) ERC-20 token contracts do not maintain a list of iterable token holders, but you need to build a database offchain yourself. mapping in EVM is not iterable, you can only check for a known key value.

I have created a standalone tool which collects ERC-20 token holders and transactions to SQLite database and using web3.py library.

  • Take a token contract address

  • Iterate over all Transfer events for token using eth_getLogs JSON-RPC API

  • Build a local database of these events

  • Allow you to use SQL to query any account balance on any point of time (block num)

You can find the command line application execution example how to build the token holder database here

The core Python logic is here.

There are some quirks here and there: for example detecting mint / creation event for some tokens is not straightforward. Thus, you will may negative balance on the account receiving initial total supply if you rely on Transfer event only.


Not sure if you are trying to do it programmatically to learn or because you don't know an easier way, if its the latter: https://etherscan.io/tokens

  • I'm looking to do it programmatically, I've looked into my token contract and some events that could be helpful now I'm confused on how to call certain events if anyone could give me examples using web3.py. For example: Apr 13, 2018 at 16:08

You should checkout TrueBlocks. It can do exactly this. Unlike above answers this will report on every transaction including mint events (even if the token contract doesn't generate mint events. If you're not running your own node, it can fall back on getting the same data as is available with EtherScan. If you are running your own node, it will build a queriable index which you can then query for a full list of every transaction on any address. From there, you can build your own list of token holders.

Full disclosure: I wrote TrueBlocks

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.