I saw a lot of questions over the internet on how to determine the number of token holders in solidity and everybody says that its impossible to be determined without interacting with a solution that is stored off the blockchain.

I have an idea for this issue that got stuck in my head and I cannot see any downside except slightly higher gas required for each transaction.

The solution would be to define a unit property in the contract and initialize it in the constructor with the number of addresses that will hold balance at the end of the constructor logic execution. In the method that performs the transaction, write some logic that will increase the counter if the balance of the receiver is 0 and decrease the counter if the balance of the sender becomes 0 after the transaction.

  contract MyToken is ERC20{
    uint holders;
    constructor(string memory name, string memory symbol) ERC20 (name, symbol){
        holders = 0;
    function transfer(address recipient, uint256 amount) public override returns (bool) {    
        _transfer(_msgSender(), recipient, amount);
        if(balanceOf(recipient) - amount == 0) holders++;
        if(balanceOf(_msgSender()) == 0) holders--;
        return true;

Is there anything that I miss and will cause this solution to fail?

  • 1
    That should work, similar modifications has to be made for every function that changes the balances, for example transferFrom, burn or mint.
    – Ismael
    May 16 at 4:00

I wonder why OpenZappelin didn't implement so useful functionality. Talking about your code:

  1. holders = 0; not necessary, it is already zero
  2. you don't count partially sending, it should increase holders count
  3. compute changes for all operations transfer/transferFrom/mint/burn or use OpenZappelin ERC20 implementation and use_beforeTokenTransfer (or reproduce it in your ERC20 class)
  • What do you mean by partially sending? Jul 21 at 7:42

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.