Openzeppelin-contracts: Support EIP-2309: ERC-721 Consecutive Transfer Extension

Created on 11 Sep 2020  路  13Comments  路  Source: OpenZeppelin/openzeppelin-contracts

馃 Motivation
Support EIP-2309: ERC-721 Consecutive Transfer Extension
Enables minting any number of tokens in a single transaction

馃摑 Details

EIP is an extension to ERC-721, for a standardized event emitted when creating/transferring one, or many non-fungible tokens using consecutive token identifiers.
https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2309.md

EIP is final status.

Creating issue for discussion on how EIP could be supported

Most helpful comment

Hi @arpu & @Soren74,

I have reached out to Sean Papanikolas to ask if they can share an implementation.

@Soren74 my assumption is that you don't use any loops (as this would have limits on the amount of tokens that could be minted), instead you need to use additional state to capture the start and end of a series of tokens.

All 13 comments

It seems that the EIP only standardizes an event, we have to figure out what it means for us to support it. Should we add an ERC721 flavor with batch minting/transfering?

Also worth noting that our ERC721 preset uses consecutive ids so we may want it to emit this event.

I'm interested to see an example implementation. I hope that Sean Papanikolas will be able to share one.

maybe https://github.com/pizzarob can help on this?
i am also interested in this Extension

Yes, I too am very curious about how to actually implement this extension.

I've tried creating a quick Contract that is ERC721Full
-I then added to it the ConsecutiveTransfer(...) event declaration (which the dev. said we're supposed to use):
event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress);
-I made a for loop in the constructor to mint 100 Tokens
-but then... I realized I can't call the inherited super._mint function in the loop like we're used to doing, as follows:
super._mint(msg.sender, tempColorCounter);

right?
Because that mint function internally calls the Transfer event, which dev explicitly said we're NOT supposed to use anymore. Instead we're supposed to use his new ConsecutiveTransfer(...) event.

So... color me confused.

Also noticed none of dev's contracts have been verified on etherscan...

Hi @arpu & @Soren74,

I have reached out to Sean Papanikolas to ask if they can share an implementation.

@Soren74 my assumption is that you don't use any loops (as this would have limits on the amount of tokens that could be minted), instead you need to use additional state to capture the start and end of a series of tokens.

Hi @abcoathup,

Can you elaborate on what you wrote: "you need to use additional state to capture the start and end of a series of tokens" - cause I'm not sure I follow.
What would capturing this state do? Meaning how would it play into mass-minting tokens?

Also, in terms of using a for loop, you wrote: "this would have limits on the amount of tokens that could be minted" - but I'm thinking that the upper limit would be passed in as an argument. Meaning you don't do the looping in the Constructor but rather in another function (call it mintMany(uint256 howMany)), so that every time you call it you can pass in the number of tokens you want minted, giving you that flexibility.

Thoughts?

Hi @Soren74 ,

The EIP gives examples of minting, transfer and burning large quantities of tokens:

Batch token creation
emit ConsecutiveTransfer(1, 100000, address(0), toAddress);

If you had a for loop doing individual mint/transfer/burns then I assume this function would exceed the gas limit for large quantities. That is why I assume that additional state would be required in the token to track this functionality.

I am interested to see an implementation of the EIP to see how this is being done.

Hey @abcoathup,

I'm not sure I interpreted ConsecutiveTransfer the way you did.
Put it this way: to me, merely emitting this ConsecutiveTransfer event doesn't _actually_ mint anything.
I think it _announces_ that you've minted something, but it doesn't actually do any of that minting.
At least that's the way I understand it.

So the EIP isn't really giving us any examples of anything - other than making announcements.

Check out Sean Papanikolas' post in the Docs section of his Cargo.build website (at: https://docs.cargo.build/advanced-information/batch-minting-non-fungible-tokens):

"with the Consecutive Transfer extension you could emit one event to track the creation of all 2^255 NFTs. It could look something like this:

function mint(uint amount, address from, address to) public {

  // Create NFTs and assign ownership
  // ...
  // Emit Consecutive Transfer Event
  emit ConsecutiveTransfer(lastMintedId + 1, lastMintedId + amount, from, to);
}

"The lastMintedId would be the last consecutive token that was created. For example lastMintedId would initially be 0 . After creating the first NFT it would become 1 . Then if you created five more NFTs the range of NFTs created would be 2 to 6 . "

So the way I read what he's saying there is that you _can_ have your for loop, put all your minting code in it - meaning create your Token object/struct, add it to the various mappings or arrays you're using to keep track of ID's, Ownership, etc. - but don't emit any Transfer events in this loop!
Instead, upon exiting the loop, emit the ConsecutiveTransfer event once - and only once, and that should take care of everything.

Again, I could be dead wrong about this, but that's what I think he's talking about.

What do you think?

Gotta say, I feel like if we put our minds together we could figure this out - cause Mr. Papanikolas sure doesn't seem to wanna share the knowledge at this point, which is quite disappointing - but also rather revelatory.

Hi @Soren74,

I assume that the contract needs to do some tracking of what it has minted and who owns what consecutive tokens, which is why I assume that additional state is needed. Ideally Sean and the team from Cargo will be able to share an implementation, rather than having to reinvent the wheel.

@abcoathup I started on a new implementation that builds on top of openzeppelin ERC721 implementation.

  1. I added the event ConsecutiveTransfer() event to IERC721.sol
  2. Added a new function named _batchMint() to ERC721.sol which is similar to _mint() but I removed the Transfer event.
  3. Now I am testing a data structure that is able to keep track of a range of tokens to a single address. mapping(address => Tokens[]) hodlers; This the first thing that came to mind.
  function batchMint(address to) public virtual onlyAdmin {
    uint256 fromTokenId = _tokenIds.current();

    /// fancy data structure

    emit ConsecutiveTransfer(fromTokenId, _tokenIds.current(), address(0), to);
  }
  • We can loop and batch mint but you'll run out of gas pretty fast.
  • This might be a wrong approach, would be awesome if someone can share or discuss their data structure implementation.

@Soren74 recently I got started with erc2309, so if you want to share ideas lmk!

@BotchM Yeah, I was very excited to do this - but the guy who developed 2309 hasn't responded to any of us, so it's kinda stuck.
I must say this really reflect _very_ poorly on him as his refusal to share implementations completely goes against the very ethos of GitHub and what it's all about.
Oh well.

I personally don't have any clue how to implement this - whatever ideas or questions I had I've already posted up above, so if any of those help you somehow, run with 'em! And of course I'd be happy to see what you're doing and comment on it, try to contribute to it, etc.

Thanks!

@Soren74 Sounds good! I am sure they have their reasons. Sean also created cargo which is a platform for batch minting, so I guess it's fair to be competitive and not share the whole sauce. It would be awesome to even just get an example or even the data structure used. I only started iterating over an implementation, so I will definitely share if I get anywhere.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maraoz picture maraoz  路  3Comments

spalladino picture spalladino  路  4Comments

valmack picture valmack  路  3Comments

nventuro picture nventuro  路  4Comments

bh2smith picture bh2smith  路  4Comments