0

How to I transfer many of my ERC721 tokens to many addresses?

MyERC721:

function mintUniqueTokenTo (
    address _to,
    uint256 _tokenId,               
    string  _tokenURI // Store, receipient's name, grade and program details
) public
{        
    super.mint(_to, _tokenId);        
    super._setTokenURI(_tokenId, _tokenURI);
}

Mint to one token is easy:

nftInstance.mintUniqueTokenTo(address, tokenId, tokenURI)

With many receipients, I thought of creating a distribution contract but solidity cannot accepts array of strings. So I cannot pass it the tokenIds and tokenURIs

addresses[]; //List of receipients of my NFT tokens
tokenIds[];
tokenURIs[];

So this is where I'm stuck. Is my approach wrong?

3 Answers 3

0

There are a couple of ways you can approach setting up the ERC721 "token metadata URI".

1. Compute URI in code

Since we pass the "addresses" and "tokenIds" as arrays, we can compute the URI string by concatenating the "base_uri" + current tokenId, then set it.

2. Create your own data serialisation / deserialisation code.

As you noticed Solidity's ABI ( Application Binary Interface ) does not support handling nested / multi level arrays.

Since a string is already a byte array, ( first 32 bytes contains the length uint256 0x00 to 0x20 / next 0x20 to any contains the actual data ) we can write a custom data parser, either in pure solidity or solidity assembly.

This parser could handle just the tokenURIs or even combine all parameters we need ( address / tokenId / tokenURI ).

Check out Zoom Src / Zoom Docs for an idea on how this is done directly in assembly.

Hope this helps.

0

The code for Su Squares includes this nugget:

/// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
/// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
///  3986. The URI may point to a JSON file that conforms to the "ERC721
///  Metadata JSON Schema".
function tokenURI(uint256 _tokenId)
    external
    view
    mustBeValidToken(_tokenId)
    returns (string _tokenURI)
{
    _tokenURI = "https://tenthousandsu.com/erc721/00000.json";
    bytes memory _tokenURIBytes = bytes(_tokenURI);
    _tokenURIBytes[33] = byte(48+(_tokenId / 10000) % 10);
    _tokenURIBytes[34] = byte(48+(_tokenId / 1000) % 10);
    _tokenURIBytes[35] = byte(48+(_tokenId / 100) % 10);
    _tokenURIBytes[36] = byte(48+(_tokenId / 10) % 10);
    _tokenURIBytes[37] = byte(48+(_tokenId / 1) % 10);

}

In this approach, the URI is calculated dynamically. You could use a similar approach for the URI and this allows you to use the array approach for your own mintUniqueTokensTo function.

^ This assumes you are working with a moderate number of mint operations. For example, OpenSea recently introduced bundles transfers (see one of them here) which are limited to 30 items. If you are doing something much larger than that you need a more scaleable solution. We can discuss those but it is out of scope of this question.

0

Have a look at ERC721A, which was designed for minting multiple NFTs in one transaction by saving gas. https://github.com/chiru-labs/ERC721A

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.