-
Notifications
You must be signed in to change notification settings - Fork 11.8k
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
feat: add baseTokenURI to ERC721Metadata #1970
Conversation
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.
Neat, thanks @nachomazzara! I wonder if we should add this to the base ERC721Metadata
contract, or create a new one. Having it all in the same place seems like the way to go. @frangio?
Also, could you please add a changelog entry under 2.5? Thanks!
I think we should add this feature as a new contract. The proposed name in #1745 was Edit: I was talking about a different feature, see below. |
Actually, the approach in this PR is quite different from the one proposed in #1745. It doesn't use But I still think we should implement Have you considered this approach and discarded it? If so, please share more details about that! |
A contract like the following could be added to the PR and cover the functionality of #1745. ERC721DefaultURI.solpragma solidity ^0.5.0;
import "./ERC721.sol";
import "./ERC721Metadata.sol";
import "./ERC721Enumerable.sol";
import "../../access/roles/MinterRole.sol";
import "../../drafts/Strings.sol";
/**
* @title ERC721DefaultURI
* @dev ERC721 minting logic with a default URI.
*/
contract ERC721DefaultURI is ERC721, ERC721Metadata, ERC721Enumerable, MinterRole {
/**
* @dev Constructor function
*/
constructor (string memory name, string memory symbol, string memory uri) public ERC721Metadata(name, symbol) {
_setBaseTokenURI(uri);
}
/**
* @dev Function to mint tokens
* @param to The address that will receive the minted tokens.
* @return A boolean that indicates if the operation was successful.
*/
function mint(address to) public onlyMinter returns (bool) {
uint256 tokenId = totalSupply().add(1);
_mint(to, tokenId);
return true;
}
/**
* @dev Returns an URI for a given token ID.
* Throws if the token ID does not exist. May return an empty string.
* @param tokenId uint256 ID of the token to query
*/
function tokenURI(uint256 tokenId) public view returns (string memory) {
require(_exists(tokenId), "ERC721DefaultURI: URI query for nonexistent token");
return string(abi.encodePacked(_baseTokenURI(), Strings.fromUint256(tokenId)));
}
} |
Thanks for the review!!
Yes, I did. My idea is to add flexibility, re-usability and reduce gas costs while keeping the ERC721Metadata standard. Maybe I used #1745 wrong misunderstanding the main goal of it. /**
* @dev Returns an URI for a given token ID.
* Throws if the token ID does not exist. May return an empty string.
* @param tokenId uint256 ID of the token to query
*/
function tokenURI(uint256 tokenId) public view returns (string memory) {
require(_exists(tokenId), "ERC721DefaultURI: URI query for nonexistent token");
return string(abi.encodePacked(_baseTokenURI(), Strings.fromUint256(tokenId)));
} As everything requested for In our actual case at Decentraland using only the |
I see! I slightly disagree with your point regarding the relationship between this and #1745, but we can continue the discussion in the issue. Let's continue this PR as it was originally. |
@frangio @nachomazzara I ended up removing some of the getters that were causing naming issues, since they are probably not required anyway. I also changed the behavior of |
Thanks, @nventuro. The changes are ok, but I think that we still need a way to get the I will keep it as private but I would add:
|
After thinking about this some more, we may want to consider adding a custom event that logs the setting of a base URI.
Are there any particular use cases you have in mind for this? We often try to keep the API surface as small as possible, and perhaps there are better ways to achieve what you want to do. |
I thought about it and I would leave it for children's contract implementation keeping the same behavior when setting the
Sure, maybe you want to override the function tokenURI(uint256 tokenId) public view returns (string memory) {
return string(abi.encodePacked(baseTokenURI(), Strings.fromUint256(tokenId)));
} This will save gas by not using the IMO |
Hm, those are good arguments, thanks! I'll add it back. |
I've updated the PR, adding back that getter and improving the docs a bit. However, I've also rolled back the change on the visibility of I think this is now ready to be merged. @frangio? |
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.
Great work guys!
Fixes #1745
baseURI
variable.baseURI
.tokenURI
thebaseURI
tokenURI()
fromexternal
topublic
._tokenURI()
function to expose thetokenURI
isolated without the base.Notes: I used
_baseURI
asprivate
and_baseTokenURI
asinternal
to not change the existing ERC721Metadata interface.