I have an ERC721 compliant contract with multiple NFT tokens.

I'm looking for a way to randomly select one of the token owners. Is there a way to get the current list or all token owners from ERC721 or do I need to create the mapping myself?

If creating the mapping myself, I guess I would need to add the minters address to a mapping of all owners, then whenever the token is transferred I need to update the new owner address. How do I override all the transfer functions?

2 Answers 2


You can try to fetch all emitted Transfer events using getPastEvents function. Based on ERC721 interface Transfer event is emitted when ownership changes.

/// @dev This emits when ownership of any NFT changes by any mechanism.
///  This event emits when NFTs are created (`from` == 0) and destroyed
///  (`to` == 0). Exception: during contract creation, any number of NFTs
///  may be created and assigned without emitting Transfer. At the time of
///  any transfer, the approved address for that NFT (if any) is reset to none.

event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);

The ERC721Enumerable extension is designed so that this use will be super simple.

Another option is possible if your token IDs are sequential, just randomly pick a number in the correct range and look up that owner.

If you do not use ERC721Enumerable and there is no predictable pattern of token IDs then the only way to select a random token is to generate (off-chain) a list of all tokens using the Transfer event and select from there.

The Su Squares update script includes just such an example code,. It is permissively licensed, works with Ethers.js and is documented. You can use it to generate a list of all minted tokens and do with them what you please, including looking up the owner, metadata and any other stuff you want to analyze.

  • ERC721Enumerable is not great idea, not only cost gas fee in creation and it doesn't solve the thread issue, you need to loop and call them one by one which is not great Feb 8 at 10:12
  • You do not need to loop. The thread question is to get a random one. So just token.ownerOf(token.tokenByIndex(RANDOM % token.totalSupply())) Feb 10 at 0:28

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.