I've just implemented several SCs in order to accomplish the ERC721 functionality but I'm facing a critical issue related to the scalability when I want to create a great number of tokens. I'm storing all the data regarding uniques tokens through IPFS platform, thus when I create a token I push this identifier to 2 different arrays and set the IPFS hash into several tokens (I want to add the same IPFS hash to several tokens). But the gas cost is too high, so I wonder if there is a better way to achieve my outcome of creating at least 100 tokens in each transaction. I've tested with 50 tokens and the gas cost is around 7 mill. Furthermore, I'm going to increase the gas per block.

function _mint(
    address _to, 
    uint256[] _tokenIds,
    string _dataId
) internal 
    for (uint256 x = 0; x < _tokenIds.length; x++) {
        // Add the token ID to the owner token array
        super._mint(_to, _tokenIds[x]);

        // Add to the token ID to the tokens array

        // Add token data
        setTokenData(_tokenIds[x], _dataId);            

PD: Do you think it makes sense to use it when you need to create 10k of tokens every day?

Thanks in advance!

  • Have you considered that you may not need to create 20,000 tokens every day (at least not initially)? Unless you have thousands of active users per day, what is the likelihood that those tokens will ever be used? – AnAllergyToAnalogy Jun 4 '18 at 0:13
  • @AnAllergyToAnalogy It aims to create 1 token per Mw generated every day. It will be approximately 10k of tokens per day :/ (I have just updated my answer --> 7mill of gas per 50 tokens). I would like to know the scalability in a long-term app with this dairy amount of inputs (latency or something related to that). – zyzz Jun 4 '18 at 9:40
  • Also, please explain more about your use case and why you are creating 10k per day. Are you creating them and selling them one-by-one? Are they kitties that breed? Are you selling them in bulk? I have different answers based on these questions. – William Entriken Jan 3 '19 at 16:36

Without knowing your exact application, it's worth noting that the ERC721 specification doesn't actually have any requirements regarding minting or destroying tokens other than that they must emit the Transfer event as per the following rules:

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

With that in mind, rather than creating 20,000 tokens every day, you could create a single token with an assigned "value" of 20,000. Then allow any token to be divided by the token owner into two or more tokens of lesser values that add up to the value of the original token. That process would actually destroy the original token, then mint two new tokens.

If needed, it would still allow you to divide your single token (which was initially worth 20,000 Mw) into 20,000 separate tokens, but only as needed.

Otherwise, ERC721 may not be your best option. It seems like all the tokens you mint during a given batch are identical to each other (ie, they all have the same data associated). It depends whether or not it's meaningful for a person's balance of two tokens from different days to be added together.

If not, they aren't really non-fungible tokens. Rather, each day you're creating 20,000 Fungible tokens, (which are identical to each other, but separate from the previous day). Rather than using ERC721, you may want to develop a contract that deploys a new fungible token contract instead (like ERC20).

  • The first layer of my SCs is ERC721, the function mentioned above is one of the custom functions that I've created in order to match the requirements. Every token must be unique and non-fungible due to every one represents a particular certificate and the data previously mentioned is the minimum useful data that I can store in the BC, the rest of them are stored off-chain. Maybe a side chain would be useful. Thanks for your answer, I'm going to think another way to accomplish this madness. – zyzz Jun 4 '18 at 13:02

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.