2

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?

Mikko Ohtamaa
  • 22,269
  • 6
  • 62
  • 127
marteenas
  • 21
  • 1
  • 2

2 Answers2

1

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);

mmr
  • 46
  • 3
0

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.

William Entriken
  • 4,690
  • 15
  • 42
  • 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 – Dell Watson Feb 08 '22 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())) – William Entriken Feb 10 '22 at 00:28