In the ERC721Token contract, I am wondering the limits of:

 mapping (address => uint256[]) private ownedTokens;

I am interested in providing functionality for users to potentially have thousands of ERC721 tokens.

What are the upper limits for returning their entire array in ownedTokens fetches?

I am trying to think up possible paging mechanisms by subclassing ERC721 token, but it seems to necessitate an entire new ERC721 implementation.

We also intend to cache token ownership off chain, however there will come times we'd need to sync ownership arrays with on chain.

  • 1
    Could you link to the ERC721Token contract you're talking about?
    – user19510
    Mar 7, 2018 at 2:34
  • added link, zeppelin solidity is the source, thx!
    – Kevin
    Mar 7, 2018 at 3:53
  • 1
    That seems a bit nonstandard and, as you pointed out, limited in scalability. The current ERC 721 proposal uses tokenOfOwnerByIndex to fetch tokens one at a time instead. I think some sort of pagination would be even better.
    – user19510
    Mar 7, 2018 at 3:55

2 Answers 2


I tested things out for large numbers of tokens 10s of thousands, I found the current implementation of zeppelin solidity's erc721 does not allow for speedy enumeration when the owner's tokens get into the 1000's

Given the ERC721's member mapping vars are all private, it's not possible to access ownedTokens directly:

mapping (address => uint256[]) private ownedTokens;

so, changing that to internal allows us to modify directly:

mapping (address => uint256[]) internal ownedTokens;

I can then subclass the ERC721 with an enumerator:

  function tokenOfOwnerByIndex(address _owner, uint256 _index) 
    returns (uint256 _tokenId) 
    require(_index < balanceOf(_owner));
    return ownedTokens[_owner][_index];

This is much faster, and can iterate over 80 tokens in a second for paging purposes.


This specific issue, scalability, is addressed in the standard. We have an implementation that successfully deploys MANY tokens and does not run out of gas:

We have deployed a contract, XXXXERC721, to Testnet which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. You can query it from the blockchain. And every function takes less gas than querying the ENS.

And, yes, that's a reference to XKCD 865.

Reference: https://github.com/ethereum/EIPs/pull/841


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.