Anyone know how to work with ERC-2309
? It's an extension to the ERC-721
Token standard and it's supposed to make it possible to mint a large number of ERC-721
tokens (meaning 100's or even 1000's of them) in a SINGLE TRANSACTION.
This is particularly relevant these days (Autumn of 2020) as ETH gas prices have continued to skyrocket – making the launching of any project that requires multiple ERC-721
tokens really really expensive. (And for some indie devs – downright impossible, which of course is really a shame.)
Below is a Contract I wrote with a mintBatch()
function to try and test the minting of multiple 721's. It works just fine (in my Truffle/Ganache
dev environment) when I mint 10, 20, even 40 tokens in one shot – but at 50 I get the "out of gas" error. (This number seems to vary though as I run it in different times.)
Either way, how exactly is ERC-2309
supposed to fit into all this? And, is my mintBatch
function even the right way to go about doing this?
contract ColorToken is ERC721Full, Ownable {
string public constant name = "ColorToken";
string public constant symbol = "CLRT";
struct RegularColor {
uint8 red;
uint8 green;
uint8 blue;
}
RegularColor[] colorsArray;
constructor() ERC721Full("ColorToken", "CLRT") public {
}
// Test mint function - intended to mint a bunch of ERC721 tokens all at once:
function mintBatch(address ownerAddress, uint256 numColors) onlyOwner external {
for(uint tempColorCounter = 0; tempColorCounter < numColors; tempColorCounter++) {
// 1. Create a "random" RGB Color:
RegularColor memory tempColor = RegularColor(uint8(now), uint8(now-28000), uint8(now+12500));
// 2. Push the new color to the colorsArray:
colorsArray.push(tempColor);
// 3. Finally, MINT a new ERC721 Token:
super._mint(msg.sender, tempColorCounter);
}
}
function getColorOfTokenWithID(uint tokenID) public view returns(uint8 rd, uint8 gr, uint8 bl) {
return (colorsArray[tokenID].red, colorsArray[tokenID].green, colorsArray[tokenID].blue);
}
}
=========================
UPDATED CODE:
// Moved my minting FOR loop into the Constructor so that all
// my NFT's get minted upon this Contract's Creation/Deployment:
constructor() ERC721Full("ColorToken", "CLRT") public {
for(uint tempColorCounter = 0; tempColorCounter < 50; tempColorCounter++) {
// 1. Create a "random" RGB Color:
RegularColor memory tempColor = RegularColor(uint8(now), uint8(now-28000), uint8(now+12500));
// 2. Push the new color to the colorsArray:
colorsArray.push(tempColor);
// 3. Finally, MINT a new ERC721 Token:
super._mint(msg.sender, tempColorCounter);
}
}
Best Answer
Yes. The standard is fully specified at https://eips.ethereum.org/EIPS/eip-2309. That is how you work with it.
This line is not using the ERC-2309 standard because that
_mint
implementation is emitting an event each time. You will need to rewrite your minting implementation if you want to use ERC-2309.ERC-2309 allows you to save the gas associated with emitting N events to create N tokens. A very creative implementation is then able to create N tokens with O(1) resources.
Also note, the original ERC-721 implementation already allows O(1) token creation, but only during contract deployment, as specified in ERC-721, and cited in ERC-2309: "Exception: during contract creation, any number of NFTs may be created and assigned without emitting Transfer."