-
Notifications
You must be signed in to change notification settings - Fork 5.3k
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
EIP-721 Non-Fungible Token Standard #841
Conversation
# TO DO: - [ ] Get to status accepted - [ ] Write test cases - [ ] Write implementation (on OpenZeppelin?) - [ ] Get to status final
For history. Version 39067a2 / 2018-03-08 / just before draft accepted---Preamble
Simple SummaryA standard interface for non-fungible tokens, also known as deeds. AbstractThe following standard allows for the implementation of a standard API for NFTs within smart contracts. This standard provides basic functionality to track and transfer NFTs. We considered use cases of NFTs being owned and transacted by individuals as well as consignment to third party brokers/wallets/auctioneers ("operators"). NFTs can represent ownership over digital or physical assets. We considered a diverse universe of assets, and we know you will dream up many more:
In general, all houses are distinct and no two kittens are alike. NFTs are distinguishable and you must track the ownership of each one separately. MotivationA standard interface allows wallet/broker/auction applications to work with any NFT on Ethereum. We provide for simple ERC-721 smart contracts as well as contracts that track an arbitrarily large number of NFTs. Additional applications are discussed below. This standard is inspired by the ERC-20 token standard and builds on two years of experience since EIP-20 was created. EIP-20 is insufficient for tracking NFTs because each asset is distinct (non-fungible) whereas each of a quantity of tokens is identical (fungible). Differences between this standard and EIP-20 are examined below. SpecificationThe key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119. Every ERC-721 compliant contract must implement the pragma solidity ^0.4.20;
/// @title ERC-721 Non-Fungible Token Standard
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
/// Note: the ERC-165 identifier for this interface is 0x6466353c
interface ERC721 /* is ERC165 */ {
/// @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 _tokenId);
/// @dev This emits when the approved address for an NFT is changed or
/// reaffirmed. The zero address indicates there is no approved address.
/// When a Transfer event emits, this also indicates that the approved
/// address for that NFT (if any) is reset to none.
event Approval(address indexed _owner, address indexed _approved, uint256 _tokenId);
/// @dev This emits when an operator is enabled or disabled for an owner.
/// The operator can manage all NFTs of the owner.
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
/// @notice Count all NFTs assigned to an owner
/// @dev NFTs assigned to the zero address are considered invalid, and this
/// function throws for queries about the zero address.
/// @param _owner An address for whom to query the balance
/// @return The number of NFTs owned by `_owner`, possibly zero
function balanceOf(address _owner) external view returns (uint256);
/// @notice Find the owner of an NFT
/// @param _tokenId The identifier for an NFT
/// @dev NFTs assigned to zero address are considered invalid, and queries
/// about them do throw.
/// @return The address of the owner of the NFT
function ownerOf(uint256 _tokenId) external view returns (address);
/// @notice Transfers the ownership of an NFT from one address to another address
/// @dev Throws unless `msg.sender` is the current owner, an authorized
/// operator, or the approved address for this NFT. Throws if `_from` is
/// not the current owner. Throws if `_to` is the zero address. Throws if
/// `_tokenId` is not a valid NFT. When transfer is complete, this function
/// checks if `_to` is a smart contract (code size > 0). If so, it calls
/// `onERC721Received` on `_to` and throws if the return value is not
/// `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`.
/// @param _from The current owner of the NFT
/// @param _to The new owner
/// @param _tokenId The NFT to transfer
/// @param data Additional data with no specified format, sent in call to `_to`
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data) external payable;
/// @notice Transfers the ownership of an NFT from one address to another address
/// @dev This works identically to the other function with an extra data parameter,
/// except this function just sets data to ""
/// @param _from The current owner of the NFT
/// @param _to The new owner
/// @param _tokenId The NFT to transfer
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
/// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE
/// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE
/// THEY MAY BE PERMANENTLY LOST
/// @dev Throws unless `msg.sender` is the current owner, an authorized
/// operator, or the approved address for this NFT. Throws if `_from` is
/// not the current owner. Throws if `_to` is the zero address. Throws if
/// `_tokenId` is not a valid NFT.
/// @param _from The current owner of the NFT
/// @param _to The new owner
/// @param _tokenId The NFT to transfer
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
/// @notice Set or reaffirm the approved address for an NFT
/// @dev The zero address indicates there is no approved address.
/// @dev Throws unless `msg.sender` is the current NFT owner, or an authorized
/// operator of the current owner.
/// @param _approved The new approved NFT controller
/// @param _tokenId The NFT to approve
function approve(address _approved, uint256 _tokenId) external payable;
/// @notice Enable or disable approval for a third party ("operator") to manage
/// all your asset.
/// @dev Emits the ApprovalForAll event
/// @param _operator Address to add to the set of authorized operators.
/// @param _approved True if the operators is approved, false to revoke approval
function setApprovalForAll(address _operator, bool _approved) external;
/// @notice Get the approved address for a single NFT
/// @dev Throws if `_tokenId` is not a valid NFT
/// @param _tokenId The NFT to find the approved address for
/// @return The approved address for this NFT, or the zero address if there is none
function getApproved(uint256 _tokenId) external view returns (address);
/// @notice Query if an address is an authorized operator for another address
/// @param _owner The address that owns the NFTs
/// @param _operator The address that acts on behalf of the owner
/// @return True if `_operator` is an approved operator for `_owner`, false otherwise
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}
interface ERC165 {
/// @notice Query if a contract implements an interface
/// @param interfaceID The interface identifier, as specified in ERC-165
/// @dev Interface identification is specified in ERC-165. This function
/// uses less than 30,000 gas.
/// @return `true` if the contract implements `interfaceID` and
/// `interfaceID` is not 0xffffffff, `false` otherwise
function supportsInterface(bytes4 interfaceID) external view returns (bool);
} A wallet/broker/auction application MUST implement the wallet interface if it will accept safe transfers. /// @dev Note: the ERC-165 identifier for this interface is 0xf0b9e5ba
interface ERC721TokenReceiver {
/// @notice Handle the receipt of an NFT
/// @dev The ERC721 smart contract calls this function on the recipient
/// after a `transfer`. This function MAY throw to revert and reject the
/// transfer. This function MUST use 50,000 gas or less. Return of other
/// than the magic value MUST result in the transaction being reverted.
/// Note: the contract address is always the message sender.
/// @param _from The sending address
/// @param _tokenId The NFT identifier which is being transfered
/// @param data Additional data with no specified format
/// @return `bytes4(keccak256("onERC721Received(address,uint256,bytes)"))`
/// unless throwing
function onERC721Received(address _from, uint256 _tokenId, bytes data) external returns(bytes4);
} The metadata extension is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your smart contract to be interrogated for its name and for details about the assets which your NFTs represent. /// @title ERC-721 Non-Fungible Token Standard, optional metadata extension
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
/// Note: the ERC-165 identifier for this interface is 0x5b5e139f
interface ERC721Metadata /* is ERC721 */ {
/// @notice A descriptive name for a collection of NFTs in this contract
function name() external pure returns (string _name);
/// @notice An abbreviated name for NFTs in this contract
function symbol() external pure returns (string _symbol);
/// @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 returns (string);
} This is the "ERC721 Metadata JSON Schema" referenced above. {
"title": "Asset Metadata",
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Identifies the asset to which this NFT represents",
},
"description": {
"type": "string",
"description": "Describes the asset to which this NFT represents",
},
"image": {
"type": "string",
"description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive.",
}
}
} The enumeration extension is OPTIONAL for ERC-721 smart contracts (see "caveats", below). This allows your contract to publish its full list of NFTs and make them discoverable. /// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
/// Note: the ERC-165 identifier for this interface is 0x780e9d63
interface ERC721Enumerable /* is ERC721 */ {
/// @notice Count NFTs tracked by this contract
/// @return A count of valid NFTs tracked by this contract, where each one of
/// them has an assigned and queryable owner not equal to the zero address
function totalSupply() external view returns (uint256);
/// @notice Enumerate valid NFTs
/// @dev Throws if `_index` >= `totalSupply()`.
/// @param _index A counter less than `totalSupply()`
/// @return The token identifier for the `_index`th NFT,
/// (sort order not specified)
function tokenByIndex(uint256 _index) external view returns (uint256);
/// @notice Enumerate NFTs assigned to an owner
/// @dev Throws if `_index` >= `balanceOf(_owner)` or if
/// `_owner` is the zero address, representing invalid NFTs.
/// @param _owner An address where we are interested in NFTs owned by them
/// @param _index A counter less than `balanceOf(_owner)`
/// @return The token identifier for the `_index`th NFT assigned to `_owner`,
/// (sort order not specified)
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
} CaveatsThe 0.4.20 Solidity interface grammar is not expressive enough to document the ERC-721 standard. A contract which complies with ERC-721 MUST also abide by the following:
If a newer version of Solidity allows the caveats to be expressed in code, then this EIP MAY be updated and the caveats removed, such will be equivalent to the original specification. RationaleThere are many proposed uses of Ethereum smart contracts that depend on tracking distinguishable assets. Examples of existing or planned NFTs are LAND in Decentraland, the eponymous punks in CryptoPunks, and in-game items using systems like DMarket or EnjinCoin. Future uses include tracking real-world assets, like real-estate (as envisioned by companies like Ubitquity or Propy. It is critical in each of these cases that these items are not "lumped together" as numbers in a ledger, but instead each asset must have its ownership individually and atomically tracked. Regardless of the nature of these assets, the ecosystem will be stronger if we have a standardized interface that allows for cross-functional asset management and sales platforms. "NFT" Word Choice "NFT" was satisfactory to nearly everyone surveyed and is widely applicable to a broad universe of distinguishable digital assets. We recongize that "deed" is very descriptive for certain applications of this standard (notably, physical property). Alternatives considered: distinguishable asset, title, token, asset, equity, ticket NFT Identifiers Every NFT is identified by a unique The choice of Transfer Mechanism ERC-721 standardizes a safe transfer function
Additionally, an authorized operator may set the approved address for an NFT. This provides a powerful set of tools for wallet, broker and auction applications to quickly use a large number of NFTs. The transfer and accept functions' documentation only specify conditions when the transaction MUST throw. Your implementation MAY also throw in other situations. This allows implementations to achieve interesting results:
Failed transactions will throw, a best practice identified in ERC-223, ERC-677, ERC-827 and OpenZeppelin's implementation of SafeERC20.sol. ERC-20 defined an Creating of NFTs ("minting") and destruction NFTs ("burning") is not included in the specification. Your contract may implement these by other means. Please see the Alternatives considered: only allow two-step ERC-20 style transaction, require that transfer functions never throw, require all functions to return a boolean indicating the success of the operation. ERC-165 Interface We chose Standard Interface Detection (ERC-165) to expose the interfaces that a ERC-721 smart contract supports. A future EIP may create a global registry of interfaces for contracts. We strongly support such an EIP and it would allow your ERC-721 implementation to implement Gas and Complexity (regarding the enumeration extension) This specification contemplates implementations that manage a few and arbitrarily large numbers of NFTs. If your application is able to grow then avoid using for/while loops in your code (see CryptoKitties bounty issue #4). These indicate your contract may be unable to scale and gas costs will rise over time without bound. We have deployed a contract, XXXXERC721, to Testnet which instantiates and tracks 340282366920938463463374607431768211456 different deeds (2^128). That's enough to assign every IPV6 address to an Ethereum account owner, or to track ownership of nanobots a few micron in size and in aggregate totalling half the size of Earth. You can query it from the blockchain. And every function takes less gas than querying the ENS. This illustration makes clear: the ERC-721 standard scales. Alternatives considered: remove the asset enumeration function if it requries a for-loop, return a Soldity array type from enumeration functions. Privacy Wallets/brokers/auctioneers identified in the motivation section have a strong need to identify which NFTs an owner owns. It may be interesting to consider a use case where NFTs are not enumerable, such as a private registry of property ownership, or a partially-private registry. However, privacy cannot be attained because an attacker can simply (!) call Metadata Choices (metadata extension) We have required We remind implementation authors that the empty string is a valid response to A mechanism is provided to associate NFTs with URIs. We expect that many implementations will take advantage of this to provide metadata for each NFT. The image size recommendation is taken from Instagram, they probably know much about image usability. The URI MAY be mutable (i.e. it changes from time to time). We considered an NFT representing ownership of a house, in this case metadata about the house (image, occupants, etc.) can naturally change. Metadata is returned as a string value. Currently this is only usable as calling from Alternatives considered: put all metadata for each asset on the blockchain (too expensive), use URL templates to query metadata parts (URL templates do not work with all URL schemes, especially P2P URLs), multiaddr network address (not mature enough) Community Consensus A significant amount of discussion occurred on the original ERC-721 issue, additionally we held a first live meeting on Gitter that had good representation and well advertised (on Reddit, in the Gitter #ERC channel, and the original ERC-721 issue). Thank you to the participants:
A second event was held at ETHDenver 2018 to discuss distinguishable asset standards (notes to be published). We have been very inclusive in this process and invite anyone with questions or contributions into our discussion. However, this standard is written only to support the identified use cases which are listed herein. Backwards CompatibilityWe have adopted Example NFT implementations as of February 2018:
Note: "Limited edition, collectible tokens" like Curio Cards and Rare Pepe are not distinguishable assets. They're actually a collection of individual fungible tokens, each of which is tracked by its own smart contract with its own total supply (which may be The Test CasesTO DO Test cases for an implementation are mandatory for EIPs that are affecting consensus changes. Other EIPs can choose to include links to test cases if applicable. ImplementationsSu Squares -- an advertising platform where you can rent space and place images
ERC721ExampleDeed -- an example implementation
XXXXERC721, by William Entriken -- a scalable example implementation
ReferencesStandards
Issues
Discussions
NFT Implementations and Other Projects
CopyrightCopyright and related rights waived via CC0. |
I assume this is meant to supersede/continue the original #721 but I don't understand why everything is now called a deed instead of an NFT. That was never part of the discussion in 721 and I don't see why that needed to change. Also is it not inherently a risk to include an implementation of a another draft standard (#165) in what we hope will become the standard for NFTs? What will happen if/when #165 changes? I fully support a push to finalise the standard since it seems dete has other priorities at the moment, but I don't agree with changing things just for the sake of it. Referring to NFTs and "tokenIds" instead of 'deeds' and "deedIds" seems more inclusive to me. |
I like the standard in general. Thank you for pushing for finalization. I agree with @Nanolucas the change to "deed" seems odd. This then extends to function There is a typo in the interface code given. For Text typos:
|
Nice one to see things are summing up clearly, and of course the push for finalisation. I too agree with @Nanolucas and @Beskhue about the use of "deed" word instead "NFTs" or "Asset" that was discussed during the gitter chat. |
As a person more focused on real estate (and very new to blockchain), I like "deed" (and the consistency of "deedId") or "title" (though it is horribly generic) as this relates to terms used in the real estate world - however, as a developer/programmer planning to work with this, I think care (and respect of prior discussion) should be used to not confuse. I'm not a fan of "NFT" (means nothing to someone not familiar with the history of how it came about - how easy will that be to recognize for future users?). Other terms, such as Certificate of Ownership and Certificate of Title don't lend themselves to short wording - so, "deed" (and a consistent use of that throughout function naming, etc.), to me, is the best choice - easy to remember and find on searches years from now, etc... ============ In the main doc, this should not be in there..... ============= Change (for clarity) It is also not clear to me on how to split the fees, which is another common thing in real estate - it can be any amount as agreed by the two parties - usually done in % of the total or a set amount as in "I will pay up to $X of the fees - anything over that, you pay". Is it envisioned that each individual transfer of ownership will have the option to set this for each party (and perhaps a set 'standard' amount in the contact)? Therefore, I think I'm happy to see any wording that helps clarify the above - I think it applies to any real-world transaction, I've included only details from my experience in real estate. ======= In addition to the typos shown, I question " or they may return an empty string / unable value." - should that be "unusable"? |
One other thing that I realized - in real-world application of Deeds - and certainly for utilizing this technology as a replacement for a Public Records system - there is a requirement for retaining not only an owner by address, but by their legal name as well as a mechanism to search by such name (or portion thereof, for most Public Records searches). I understand this is 0% privacy, though that is what make it 'Public Records'.... I think this would fit fine in the ERC-721 Accountability Extension, simply adding on an ownerByName (or ownerByLegalName ?) function. |
EIPS/eip-721.md
Outdated
Type: Standard | ||
Category ERC | ||
Status: Draft | ||
Created: 2018-01-31 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see a future date.
EIPS/eip-721.md
Outdated
|
||
## Abstract | ||
|
||
**This a standard interface for smart contracts to handle deed ownership.** Deeds can represent ownership of physical property, like houses, or digital property, like unique pictures of kittens. In general, all houses are distinct and no two kittens are alike. Therefore you must track each deed separately; it is insufficient to simply count the deeds you own. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This a standard interface
"is" is missing.
Regarding "deed" name @Beskhue, backwards compatibility with existing contracts is not a design goal of this specification. Such is the risk of implementing standards that are not finalized. Please note that ERC-20 was designed as a consensus standard to meet existing implementations, and it suffered accordingly. I argue that deeds are more general than tokens (and, by extension, NFTs). The word title is probably more correct, but title has other unrelated meanings that are much better known. CASE STUDY, CRYPTO KITTIES: See the CASE STUDY, HOUSES: In most (all?) counties in the United Status, house ownership is recorded by a county deed recorder, the instrument of house ownership is a deed. The deed is distinct from the house. In fact, the house may change, the taxes on the house might change. However the deed is permanent, until it is transferred. These two case studies illustrate how a deed is separate from the thing which it declares ownership over. In token standards, the token itself is what you have ownership over. In deed standards, you always want ownership of a separate thing. Such is the motivation for the distinct name. ^^^ If there is a more elegant way to explain this, I'd like to include it in the EIP. |
@TCOA, thank you, I have incorporated these updates. As for transfer mechanisms that include transference fees, I believe this standard does sufficiently allow all such implementations. As for searching by owner. One implementation may implement this by only allowing smart contracts to have ownership of the deeds. Those smart contracts may have additional requirements, such as having a name. Additionally, an implementation may require additional metadata be recorded with each deed. These types of applications are considered and are applicable with this standard. However, I do not see that they should be required for the standard. |
We are moving along, and thanks for all your help, seriously. Please scroll up and vote to accept this EIP --> 🎉 Accepting does not mean you agree with everything. It means we should list this as an active proposal on https://github.com/ethereum/eips/ and get more people involved in the discussion because it is serious. See workflow in the top comment for what happens after acceptance. |
I agree with @fulldecent that tracking names is out of scope for ERC-721. For such cases one could indeed use named contracts, or perhaps track a mapping of Ethereum addresses to legal entity names inside the contract implementing ERC-721 itself. I now also somewhat reluctantly agree with the name "deed." It seems it captures the concept better, but it also seems out of place in the common Ethereum / blockchain terminology. |
another thought - in making this really work for Public Records (and even many private ones), there needs to be a method to both subdivide (creating 2-x number of smaller parcels, each covered by their own deed and defined in something like an IPFS) and combine (bringing in multiple smaller parcels to make one large deed - ex: an older neighborhood being taken up by 'eminent domain' to build an airport). These activities are often governed by various planners/engineers and require an approval from a central authority before they can be made part of the record - so, just who/how can that be tracked and authorized? One more..... How might the community envision such 'reverse lookup' things? I realize I'm going a bit further here - and some of these things are either best handled in another way, or perhaps put on the 'future spec' list, though I was attracted to Ethereum blockchain as a Public Records replacement system, not only recording 'vaporland'. If all these things can be brought in up front, though, how great would that be? |
@TCOA Those are definitely interesting use-cases. However, I think ERC-721 should focus on what it means for something to be "non-fungibly transferable." In the case of property, there would be a contract implementing ERC-721, as well as a means of transforming a single deed into multiple other deeds (subdividing) or transforming multiple deeds into a single deed (combining). This would not be functionality specific to ERC-721, but rather something making use of the properties of ERC-721. |
@Beskhue thanks for clarifying. I'm still new to 'contracts' as known in blockchain though I'm starting to see just how expanded they can become. One more 'for the record just to say it was brought up' (though from what I'm learning I think it may apply to the specific way a blockchain contract developed for a particular Public Records entity might be built) - Liens and other 'hindrances' and/or 'attachments' to a particular deed (and, of course, the process of their removal). As the type of such things vary from governing body I place them all into a heading of what we know as "dirty title" - how would you feel about this? In normal research of the property, such 'dirt' gets brought out by a Title Company (another entity that I would happily see eliminated by the blockchain...), however, in the proposed 'exchange of NFT', there is only a chain of title, while real-world mechanisms are much more involved. When 'dirt' is found (sometimes not even known by the seller), various processes are required to remove it and the end result is a 'clean' title - guaranteed by a Title Company as being "as clean as we can figure out from the research we did and so we believe we can say it is 'clean' so the buyer won't likely get slapped later" - the Title Company gets paid 'insurance' (which I am positive is out of the scope here) and the sale goes through. What I'm going for here - Is there a use-case here worthy of specifying the requirement for the seller to state this is a 'clean title'? (I'm getting the feeling I know what you will say - and that then makes a business case for a 'Blockchain Title' company..... :( |
@fulldecent for the "^^^ If there is a more elegant way to explain this, I'd like to include it in the EIP." part, maybe you would want to say something in the lines of: |
@TCOA Your discussion and creative thinking are especially welcome here. If there is something that is incompatible with the standard then we need to decide if the standard should change. But so far you are just testing our creative thinking skills. Subdivisions or combinations of property should probably be implemented by creating a new deed and assigning ownership of the new deed to the own owner(s). See Regarding your note about searching by parcel identifier or street name. This is a similar situation as searching by owner name. And equally compatible with this standard. |
Regarding encumbered titles. The liens mechanism is such that you cannot transfer a deed if liens exist. And liens come from various sources but they are ultimately recognized by the deed-recording organization. This standard is compatible with such a process. Please see text of the |
I’m not 100% what the error is yet but can you please report this to
Solidity and reference the open PR about overloading/overriding. They
definitely want to know about this. Thank you!
On Fri, Mar 16, 2018 at 11:23 Nick Mudge ***@***.***> wrote:
I noticed that when using Solidity compiler version 0.4.21 I get an error
when I try to compile the ERC721 interface. It does not like this part:
function safeTransferFrom(address _from, address _to, uint256 _tokenId)
external; function safeTransferFrom(address _from, address _to, uint256
_tokenId, bytes _data) external;
This is the error:
TypeError: Function overload clash during conversion to external types for
arguments.
Is this a bug in the 0.4.21 version of the Solidity compiler? When using
0.4.20 there is no error. I am using the solidity compiler in remix.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#841 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AAXU50YOwMvCm7hAG52PKBx3jQaUxjMCks5te9jdgaJpZM4Rqw7z>
.
--
Regards,
Will
William Entriken
+1 267-738-4201
|
@fulldecent Nevermind about the function overloading error , it was a bug in my code. Sorry. |
What should happen if the zero address(0) is passed to the setApprovalForAll and isApprovedForAll functions? Throw? or no? |
@fulldecent Is it the plan to leave unspecified what happens when the zero address is passed to either of the functions setApprovalForAll and isApprovedForAll ? |
Hi @fulldecent, First of all, thanks for all the hard work! Quick question on the ERC-165 identifier of the ERC-721 interface. In the draft standard it is mentioned that the ERC-165 identifier of the interface should be equal to For some reason, I can't get our implementation to reflect that value, whereas the values for At Aethia we're looking to replace our current ownership contract with the current draft as it suits our needs a bit better. We just happened to notice this discrepancy while writing the new tests for the ownership contract. |
The natspec for |
@HACKDOM Good find, thank you. Can you please make a pull request to correct this and mention me? |
@mananz Thank you very much for reporting this. You are correct, the right interfaceID should be 0x80ac58cd // confirmed at https://ethfiddle.com/uJgB9kJMXC The other two interface IDs are correct as is. Would you please make a pull request to update 741.md? Also, please make an issue at https://github.com/fulldecent/su-squares-bounty and email me, I would like to pay you for this discovery! |
@mananz Can you please also email me more details about Aethia. I will be speaking at Explore 721 in Dallas this weekend and can talk about it. |
@mudgen Thank you for bringing this up. Currently the standard is silent on this item and I have added it to the OPEN ITEMS at the top here. Currently OpenZeppelin's in-progress implementation treats the zero address like any other address for setApprovalForAll. Of course, there is no practical importance to this question. The zero address will never send transactions to a contract. However, it is a valid question. Potential ideas are to throw or to allow it or to silently fail. And lastly there is undefined behavior, which we currently have. If we don't make an active decision on this then I'll ask the audience at Explore 721 and we can make an active decision. |
Is there a possibility to go include “approveAndCall” ? It would be nice 👍🏼 |
@nicola Thanks for sharing. At present, many people are using the interface and we are not considering to add required functions unless a serious problem is found with the existing. BUT DON'T LET THAT STOP YOU. Rock on definitely include that where you need it. And if you need on the NFT side and on the wallet side then that's awesome. As other people adopt the idea too then that's when it's time to talk about updating the standard. |
It's a bit annoying that we don't have approveAndCall, since you can't really make erc721 "programmable", unless you ask the user to do two requests :( I really need to do: approve the cryptokitty for the auction and create an auction! |
First, of course. CryptoKitties is already deployed. Any change to the standard will not affect that specific application. If you are writing your own application that you can definitely use approveAndCall functionality. You could implement this on the ERC721 side or on the wallet side. At present, no change is likely to happen in 721. But if you would like to discuss further, please mention me on your repository when you have a working prototype. |
I have a question regarding transfers. I want to make NFT where transfers are not payable. For that I need to change the interface to remove payable if I want to implement it as MyContract is ERC721. Otherwise I get an error (TypeError: Overriding function changes state mutability from "payable" to "nonpayable".). If I change the interface and calculate interfaceID for it (for EIP165) will it be different than expected? Or should the whole implementation of MyContract is ERC721 be different? |
@MoMannn The 'payable' modifier is not part of the ABI, so you can add or remove it without affecting anything else (including the interface ID). |
@MoMannn Please see the caveats section. You are welcome to update the interface from payable to default non-payable by editing the interface. This is a known Solidity issue cited in the standard. In the future (version 0.4.22) that TypeError will disappear in such a situation. Also (as noted in the standard) when this new Solidity version is released, I intend to edit the EIP and "rebase" it against the new Solidity. |
I think the mutability for the They're both set to The mutability guarantee rules allow for strengthening, but not weakening, so I think they should be changed to |
@AnAllergyToAnalogy This is discussed in #1072 and I support your change. |
@paulbarclay @dekz We have reviewed on an invalid assumption when deciding which event topics should be indexed. We had assumed that indexed topics are not recoverable in plain text. However, according to the Su Squares actual deployed contract, we can see that the addresses are viewable. Please scroll down to: 0x23de16e75c4b8... https://etherscan.io/address/0x6731560e455537c9f088ea02a47a0ecfa28a9231#events You can see the _from and _to which are indexed. I suppose that Of course there may be a question of whether the standard should be edited to require all contracts to use Thank you to @gnarco for bringing this up. #721 (comment) |
CHANGE ACCEPTED TO 721 #1072 |
@fulldecent Is the standard going to be updated with indexed tokenId for the Transfer and Approval events? I think it makes sense. |
/// @dev This emits when the approved address for an NFT is changed or | ||
/// reaffirmed. The zero address indicates there is no approved address. | ||
/// When a Transfer event emits, this also indicates that the approved | ||
/// address for that NFT (if any) is reset to none. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
does this means, Approval event needs to be emitted too upon transfer or does this means the Transfer event is sufficient ? The text here could be clearer maybe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Approval event is not emitted on transfer.
Here is a minor implementation note which is related to the Constantinople EVM (which went live last year on the Ethereum mainnet but is not currently live on some EVM derivatives, like Wanchain). This relates to Previously this was implemented using If you are not sending tokens using If you are interested in nitty-gritty test cases, track that here ➡️ nibbstack/erc721#235 To discuss this ➡️ #2401 All the hard work on this is done by: @MoMannn & @frangio. I'm just here to report. Since this change is technically WITHIN the original specification the new implementations are compliant with the standard. I do not think it is necessary to amend the EIP or to make a new EIP. And perhaps this small GitHub comment posted here, which is the "discussion-to" URL for ERC-721 is all that needs to be said in the EIP standards context. But of course, to discuss the technical details further please see the links above. |
STATUS: DRAFT STANDARD PUBLISHED, SEE https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
Thanks for all your help and hard work!
How to discuss
And you can always reach out to me directly.
TO DO:
ERC721Metadata
interfaceERC165
compliancesetApprovedForAll
allow the zero address?What is this?
This pull request is the ERC-721 standardization document.
This PR is represents the contributions of dozens of people imagining a future where smart contracts will manage ownership of important things in the real world and online. Thanks for your help and support!
Please react with party emoji 🎉 if you believe this EIP should be accepted. Acceptance is NOT final. The significance of acceptance is detailed in EIP-1:
When this is accepted, then we can begin the work of writing test cases and implementations. We can still discuss and change things. Another benefit is that it gets listed on the EIP homepage, this increases the audience of this EIP and will get more people involved and scrutinizing this standard.
You are the collaborators.