Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERC-2309: ERC-721 Consecutive Transfer Extension #2309

Closed
pizzarob opened this issue Oct 7, 2019 · 21 comments
Closed

ERC-2309: ERC-721 Consecutive Transfer Extension #2309

pizzarob opened this issue Oct 7, 2019 · 21 comments

Comments

@pizzarob
Copy link
Contributor

pizzarob commented Oct 7, 2019

NOTE: This has been merged and is in Draft status. Please review https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2309.md before commenting

Hi there. I'd like to get a feel from the community about a new extension for the ERC-721 standard.

TLDR: I'm proposing a batch mint extension that includes a standardized event which supports the creation and transfer of many tokens at one time. I am not proposing how to implement a batch creation or batch transfer function, only the BatchTransfer event which would emitted when a group of tokens is created or transferred.


ERC-721 has great potential to create a digital representation for any unique asset in this world. New markets and jobs can be created with ideas that stem from creating digital representations of unique assets - either tangible, or digital. However, in its current form the ERC-721 standard is not scalable. Take this example:

I sell lemons and have a farm with 10,000 lemon trees. I want to turn each lemon tree into a non-fungible token that people can own. Each person that owns one of my non-fungible lemon tokens will receive a quarterly percentage of each sale. The problem is that I would need to create each of these tokens individually - which will cost me a lot of TIME and MONEY. Wouldn't it be easier to mint 10,000 non-fungible lemon tokens at once while adhering to the ERC-721 standard? I think so.

pragma solidity ^0.5.10;

/**
  @title ERC-2309: ERC-721 Batch Mint Extension
  @dev https://github.com/ethereum/EIPs/issues/2309
 */

interface ERC721BatchMint /* is ERC721 */ {
  /**
    @notice This event is emitted when ownership of a batch of tokens changes by any mechanism.
    This includes minting, transferring, and burning.

    @dev The address executing the transaction MUST own all the tokens within the range of
    fromTokenId and toTokenId, or MUST be an approved operator to act on the owners behalf.
    The fromTokenId and toTokenId MUST be a sequential range of tokens IDs.
    When minting/creating tokens, the `fromAddress` argument MUST be set to `0x0` (i.e. zero address).
    When burning/destroying tokens, the `toAddress` argument MUST be set to `0x0` (i.e. zero address).

    @param fromTokenId The token ID that begins the batch of tokens being transferred
    @param toTokenId The token ID that ends the batch of tokens being transferred
    @param fromAddress The address transferring ownership of the specified range of tokens
    @param toAddress The address receiving ownership of the specified range of tokens.
  */
  event BatchTransfer(uint indexed fromTokenId, uint toTokenId, address indexed fromAddress, address indexed toAddress);
}
@pizzarob
Copy link
Contributor Author

pizzarob commented Oct 7, 2019

I will also point out that it's possible to create 2^255 NFTs at one time however it's not possible to emit that many Transfer events which are part of the original spec. Creating many tokens at once can be done using efficient data structures, however the original Transfer event keeps us locked into O(n) time.

@pizzarob pizzarob changed the title ERC721 Batch Mint Extension ERC-2309: ERC-721 Batch Mint Extension Oct 8, 2019
@wighawag
Copy link
Contributor

Nice,
I was thinking to propose something along these lines too.

The problem I see is that there is no retro-compatibility:

Wallet supporting ERC-721 but not ERC-2309 will not be aware of the token minted this way.
If this event is used for Transfer (see my comments below), then these wallets will also fails to track ownership changes.

I guess there is no way around but though important to mention it.

Regarding Transfers:
I don't think these should be considered.
I would rename BatchTransfer to BatchMint and would remove the fromAddress parameter
Because while it is indeed possible to implement a transfer method that transfer token if specified in consecutive order, it is a pretty limited form of transfer that should not be a standard.
Batch Minting should be enough to create a huge amount of tokens (2^256-1 even) and a batch Transfer with tokenId array might let you do 3000 token transfer per block (did not tested, just a rough estimation)

But if this is really important for your use case, I would rename it ConsecutiveBatchTransfer to be more explicit about its limitations.

@pizzarob
Copy link
Contributor Author

pizzarob commented Oct 14, 2019

Good points @wighawag. Yeah unfortunately platforms/wallets would need to update to support the new event. Like you said, no way around it. It seems that either you will have to support a new standard, or a new event. Eventually the platform or wallet will need to update.

I like ConsecutiveBatchTransfer. I will update to that. A token ID array would work for a lot of cases, but I think a consecutive batch transfer method has its place as the array will eventually fail. Not to mention you could complete a batch transfer in constant time rather than O(n) with the array.

Thanks for the comments.

@pizzarob
Copy link
Contributor Author

pizzarob commented Oct 14, 2019

I think ConsecutiveTransfer covers it. Now that I'm thinking about it the extension could probably be renamed to the ERC-721 Consecutive Transfer extension.

@pizzarob
Copy link
Contributor Author

Updated in #2310

@pizzarob pizzarob reopened this Oct 25, 2019
@pizzarob pizzarob changed the title ERC-2309: ERC-721 Batch Mint Extension ERC-2309: ERC-721 Consecutive Transfer Extension Oct 25, 2019
@pizzarob
Copy link
Contributor Author

I think the standard should state that when emitting the ConsecutiveTransfer event the Transfer event should NOT be emitted. This can lead to bugs when using these events to determine token ownership and would require unnecessary complicated logic.

@pizzarob
Copy link
Contributor Author

^ added in #2522

@fulldecent
Copy link
Contributor

Please follow proper EIP format. Specifically, this is missing the required Backwards Compatibility section. And of note, this is NOT backwards compatible with ERC-721, please don't advertise it as compatible.

But let me be the first to welcome you to BREAK compatibility! And if you are going to break, keeping as much familiar as possible is helpful -- as this proposal does.

Application first -- standards last.

@pizzarob
Copy link
Contributor Author

pizzarob commented Jun 10, 2020

You're right - applications that are listening for and tracking transfer events would miss ConsecutiveTransfer events and would not have the correct information about token ownership. Will add backwards compatibility section.

@pizzarob
Copy link
Contributor Author

Added backwards compatibility in https://github.com/ethereum/EIPs/pull/2717/files

@pizzarob
Copy link
Contributor Author

Merged as final please re-open if this should be left open.

@MicahZoltu MicahZoltu reopened this Sep 23, 2020
@MicahZoltu
Copy link
Contributor

I believe discussions are intended to be left open... Though I'll ask around.

@arpu
Copy link

arpu commented Sep 25, 2020

@pizzarob is there any implementation guide for this?

@b0xtch
Copy link

b0xtch commented Sep 26, 2020

Some implementation examples would be helpful

@MicahZoltu
Copy link
Contributor

Discussed with other editors and closing this is fine. 😀

@flockonus
Copy link

flockonus commented Apr 19, 2021

I understand how this EIP could be implemented for the creation of a range of NFTs, but how do you guarantee security on the transfer on a range of existing items?

Say in a contract there is a certain ownership of tokens:

id : owner
1: 0xAA
2: 0xAA
….
997: 0xAA
998: 0xFF (!)
999: 0xAA

Say i wants to makes an order to move 1 ... 999, how would the contract be able to verify that one item is incorrectly owned in this range and prevent the transfer?

@fulldecent
Copy link
Contributor

@flockonus That's an implementation detail. Please start your own implementation and ask questions on SE or elsewhere--feel free to ping me.

But this EIP is final so GitHub Issues should not be the place to discuss implementations.

@froller
Copy link

froller commented Jul 7, 2021

Is there any canonical implementation of 2309?
Only one I've found is highly experimental one: https://github.com/veqtor/ERC2309

@ethereum ethereum deleted a comment from MadhvikNem Jul 15, 2021
@guyinthetie
Copy link

guyinthetie commented Oct 16, 2021

Love the idea. Are there any developers available familiar with the implementation of this function?

@Amxx
Copy link
Contributor

Amxx commented Jun 10, 2022

I don't think the "sequence" is properly defined in the document. Is it [fromTokenId, toTokenId[ or [fromTokenId, toTokenId]

In other words, would the equivalent loop be
for (uin256 tokenId = fromTokenId; tokenId < toTokenId; ++tokenId) { ... }
or
for (uin256 tokenId = fromTokenId; tokenId <= toTokenId; ++tokenId) { ... }

@TimTinkers
Copy link

TimTinkers commented Jul 30, 2022

I recently discovered this standard when my work-in-progress-NFT-marketplace's indexer failed to detect most of the items minted in the GoonzSchoolPhotos collection, which emitted ConsecutiveTransfer events in its minting process.

I'd previously viewed the fact that ERC-721 and ERC-1155 could not mint an NFT without emitting an event for each unique token or (in the case of ERC-1155) type of token as a sort of backstop against denial-of-service attacks. If someone wanted to flood my indexer with bogus NFTs, they would need to at least pay proportional gas to do so.

Honoring EIP-2309 without limits feels impossible: for the gas cost of a single event, a collection could signal that it is minting a full 2^256 - 1 items. Conventionally, my marketplace would then try to collect the metadata for each newly-minted token that it sees. To prevent the ConsecutiveTransfer event from being abused to fill my metadata collection queue with 2^256 - 1 pending calls, the only reasonable solution I see is for a marketplace to truncate overly-large token ID ranges.

It looks like the Chiru Labs implementation has a limit of 5,000 on the size of an EIP-2309 range. That GoonzSchoolPhotos collection that brought this to my attention minted things in batches of 1,000. The OpenSea token ID range size limit is 5,000.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

13 participants