Depend on 165

This commit is contained in:
William Entriken 2018-02-16 03:37:15 -05:00 committed by GitHub
parent 8743a2286c
commit 2b4971e3d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 28 deletions

View File

@ -8,6 +8,7 @@ Type: Standard
Category ERC
Status: Draft
Created: 2018-01-24
Requires: ERC-165
```
## Simple Summary
@ -37,31 +38,27 @@ The **baseline specification** is REQUIRED for all ERC-721 implementations (subj
```solidity
pragma solidity ^0.4.19;
import "./ERC165.sol";
/// @title Interface for contracts conforming to ERC-721: Deed Standard
/// @author William Entriken (https://phor.net), et. al.
/// @dev Specification at https://github.com/ethereum/eips/XXXFinalUrlXXX
interface ERC721 {
interface ERC721 /* is ERC165 */ {
// COMPLIANCE WITH ERC-165 (DRAFT) /////////////////////////////////////////
/// @dev ERC-165 (draft) interface signature for itself
// bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = // 0x01ffc9a7
// bytes4(keccak256('supportsInterface(bytes4)'));
// this.supportsInterface.selector;
/// @dev ERC-165 (draft) interface signature for ERC721
// bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xda671b9b
// bytes4(keccak256('ownerOf(uint256)')) ^
// bytes4(keccak256('countOfDeeds()')) ^
// bytes4(keccak256('countOfDeedsByOwner(address)')) ^
// bytes4(keccak256('deedOfOwnerByIndex(address,uint256)')) ^
// bytes4(keccak256('approve(address,uint256)')) ^
// bytes4(keccak256('takeOwnership(uint256)'));
/// @notice Query a contract to see if it supports a certain interface
/// @dev Returns `true` the interface is supported and `false` otherwise,
/// returns `true` for INTERFACE_SIGNATURE_ERC165 and
/// INTERFACE_SIGNATURE_ERC721, see ERC-165 for other interface signatures.
function supportsInterface(bytes4 _interfaceID) external pure returns (bool);
/// @dev ERC-165 (draft) interface signature for itself
// bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // xxxxxx
// this.ownerOf.selector ^
// this.countOfDeeds.selector ^
// this.countOfDeedsByOwner.selector ^
// this.deedOfOwnerByIndex.selector ^
// this.approve.selector ^
// this.takeOwnership.selector ^
// this.transfer.selector;
// PUBLIC QUERY FUNCTIONS //////////////////////////////////////////////////
@ -148,9 +145,9 @@ interface ERC721Metadata {
/// @dev ERC-165 (draft) interface signature for ERC721
// bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0x2a786f11
// bytes4(keccak256('name()')) ^
// bytes4(keccak256('symbol()')) ^
// bytes4(keccak256('deedUri(uint256)'));
// this.name.selector ^
// this.symbol.selector ^
// this.deedUri.selector;
/// @notice A descriptive name for a collection of deeds managed by this
/// contract
@ -192,9 +189,9 @@ interface ERC721Enumerable {
/// @dev ERC-165 (draft) interface signature for ERC721
// bytes4 internal constant INTERFACE_SIGNATURE_ERC721Enumerable = // 0xa5e86824
// bytes4(keccak256('deedByIndex()')) ^
// bytes4(keccak256('countOfOwners()')) ^
// bytes4(keccak256('ownerByIndex(uint256)'));
// this.deedByIndex.selector ^
// this.countOfOwners.selector ^
// this.ownerByIndex.selector;
/// @notice Enumerate active deeds
/// @dev Throws if `_index` >= `countOfDeeds()`
@ -220,8 +217,9 @@ interface ERC721Enumerable {
The 0.4.19 Solidity interface grammar is not expressive enough to document the ERC-721 specification. A contract which complies with ERC-721 must also abide by the following:
- [Solidity issue #3412](https://github.com/ethereum/solidity/issues/3412): This interface includes explicit mutability guarantees for each function. Mutability guarantees are, in order weak to strong: `payable`, implicit nonpayable, `view`, and `pure`. Your implementation must meet the mutability guarantee in this interface or you may meet a stronger guarantee. For example, a `payable` function in this interface may be implemented as nonpayble (no state mutability specified) in your contract. We expect a later Solidity release will allow your stricter contract to inherit from this interface, but a workaround for version 0.4.19 is that you can edit this interface to add stricter mutability before inheriting from your contract.
- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): If a contract is not compliant with `ERC721` then it is not compliant with `ERC721Metadata` or `ERC721Enumerable`.
- [Solidity issue #3419](https://github.com/ethereum/solidity/issues/3419): If a contract is not compliant with `ERC721` then it is not compliant with `ERC721Metadata` or `ERC721Enumerable`. ERC-721 implements the requirements of interface [ERC-165](https://github.com/ethereum/EIPs/pull/881).
- [Solidity issue #2330](https://github.com/ethereum/solidity/issues/2330): If a function is shown in this specification as `external` then a contract will be compliant if it uses `public` visibility.
- [Solidity issue #3494](https://github.com/ethereum/solidity/issues/3494): Use of `this.*.selector` is marked as a warning by Solidity, a future version of Solidity will not mark this as an error.
*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.*
@ -255,11 +253,11 @@ Creating of new deeds and destruction of deeds is not included in the specificat
The transfer functions `approve`, `takeOwnership` and `transfer` are payable. Yes, really. The standard contemplates a real estate ownership application where transfer of property will require paying tax and/or various fees (including, but not limited to mining fees and pre-set transference fees), which may be paid by the old and/or new owner in any pre-arranged amount. Such an application would be compliant under this specification. Note that your contract may be nonpayable (syntactic sugar for `require(msg.value == 0)`) and be compliant, see caveats.
**Supports interface**
**ERC-165 interface**
This specification includes a function `supportsInterface` so that any contract MAY query your contract to see if it complies with ERC-721 and the extensions. In the interest of GETTING THINGS DONE, we have inlined ERC-165. This EIP does NOT require the passage of ERC-165. To be clear: if you ask a contract if it supports ERC-721 and get a positive response, then it is still possible that the contract has lied to you and that its implementation does not meet the specification in this document.
This specification includes a function `supportsInterface` which is standardized in [ERC-165](https://github.com/ethereum/EIPs/pull/881) (draft pending acceptance). So any contract MAY query your contract to see if it complies with ERC-721 and the extensions. This creates a dependency, which is a risk. However, ERC-165 is an extremely simple proposal, has implementations deployed in the wild for years and the draft meets all EIP requirements for acceptance, including [the new requirements](https://github.com/ethereum/pm/blob/master/All%20Core%20Devs%20Meetings/Meeting%2031.md#10957-decision-process-for-eips) that aren't even documented yet. The lead author of this standard is also the official champion for ERC-165.
This inline `supportsInterface` function uses `pure` mutability. The significance is that a contract which is deployed and not compliant with ERC-721 cannot make changes to become ERC-721 compliant. The benefit is that results of `supportsInterface` can be cached. This decision [has not achieved full consensus in the ERC-165 discussion](https://github.com/ethereum/EIPs/issues/165).
We chose ERC-165 over competing standard ERC-820 because of maturity. We consider ERC-165 low risk. But ERC-820, as recently as two weeks ago, [discovered a complete show-stopping flaw](https://github.com/ethereum/EIPs/issues/820#issuecomment-362049573). ERC-820 may be a great option, but we deem dependency on that standard an unacceptable risk at this time.
**Gas and complexity**