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

add 165 to 721 #972

Merged
merged 8 commits into from
Jun 8, 2018
Merged

add 165 to 721 #972

merged 8 commits into from
Jun 8, 2018

Conversation

shrugs
Copy link
Contributor

@shrugs shrugs commented Jun 1, 2018

Fixes #840

πŸš€ Description

Adds 165 to 721 using lookup table.

  • πŸ“˜ I've reviewed the OpenZeppelin Contributor Guidelines
  • βœ… I've added tests where applicable to test my new functionality.
  • πŸ“– I've made sure that my contracts are well-documented.
  • 🎨 I've run the JS/Solidity linters and fixed any issues (npm run lint:all:fix).

@shrugs shrugs changed the title WIP: add 165 to 721 add 165 to 721 Jun 8, 2018
Copy link
Contributor

@come-maiz come-maiz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job @shrugs. This seems pretty harmless to me. I have questions, but they shouldn't block this PR and if required, we can work on them later.

I love the tests that verify the hardcoded hashes!

As an aside, I would prefer changes like context to be done on separate PRs. But I know we have been doing a poor job reviewing. Once we catch up with the backlog and get this under control, I would love to have very small prs that we review and land quickly.

@@ -0,0 +1,20 @@
pragma solidity ^0.4.23;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would you think of moving this to contracts/introspection/ERC165.sol

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure

* @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
* @dev uses less than 30,000 gas.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question here: what happens if there are too many methods and interfaces and this ends up consuming more than 30000 gas?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The lookup will always use less than 30k gas; the gas limit would come in if we're doing some special calculations with a bunch of branches in the code, I think.

/**
* @dev private method for registering an interface
*/
function _registerInterface(bytes4 _interfaceId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we check here that _interfaceId is not 0xffffffff?
And another question, where does that 0xffffffff comes from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 0xff... is a magic value. If it returns true for that query, the chances of the contract having implemented the function supportsInterface(bytes4) is infinitesimally low (since the return value of a function which has no return value is garbage data, which is, 99.99999999...% of the time != false. so if the function returns true, it wasn't implemented.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting. I wonder why this is not explained in the EIP.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I had to come to that conclusion on my own; maybe it's an existing pattern? comments don't mention it either Β―_(ツ)_/Β―

event Transfer(
address indexed _from,
address indexed _to,
uint256 _tokenId
uint256 indexed _tokenId
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have a policy for which ones to make indexed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually looking at the current spec and making sure it's conformant.

* @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
* @dev uses less than 30,000 gas.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a test to check gas usage? While the current lookup implementation will always be below the limit, I feel this would be nice to have for completeness, and to safeguard against future changes to said implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done!

/**
* @dev private method for registering an interface
*/
function _registerInterface(bytes4 _interfaceId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hate to be a blocker for this but I think this function should require(_interfaceId != 0xffffffff) due to the spec of supportsInterface (link):

@return `true` if the contract implements `interfaceID` and
 `interfaceID` is not 0xffffffff, `false` otherwise

(Alternatively we could add the precondition to supportsInterface but I think the registering helper is the right place.)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just saw that there was a previous comment about this. I would still add this line just to be super clear that we're correctly implementing the spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frangio I thought the purpose of the magic value was to test the implementation as well; if the implementation, without the check, returns true for 0xffffffff, it shouldn't be trusted. And the default value for the key 0xffffffff in the supportedInterfaces map is false, so we theoretically shouldn't need a special check.

Like how in the ERC165MappingImplementation from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md#implementation they just say "don't set 0xffffffff to true".

@frangio frangio merged commit 259b9da into OpenZeppelin:master Jun 8, 2018
@frangio
Copy link
Contributor

frangio commented Jun 8, 2018

Thank you all!

@shrugs shrugs deleted the feat/erc721-updates branch June 8, 2018 22:49
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

Successfully merging this pull request may close these issues.

ERC-721 tokens / note about ERC-165
4 participants