Skip to content

Commit

Permalink
provide 'automatic' token URI by appending the token ID to the base U…
Browse files Browse the repository at this point in the history
…RI (#2174)

* provide 'automatic' token URI by appending the token ID to the base URI, if a base is set but no token-specific URI is available

* make the three cases more explicit, avoid else after return

* adjust comments to reflect reality
  • Loading branch information
KaiRo-at committed Apr 15, 2020
1 parent 4ca719b commit b6513f6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 12 deletions.
26 changes: 16 additions & 10 deletions contracts/token/ERC721/ERC721.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
import "../../utils/EnumerableSet.sol";
import "../../utils/EnumerableMap.sol";
import "../../utils/Strings.sol";

/**
* @title ERC721 Non-Fungible Token Standard basic implementation
Expand Down Expand Up @@ -132,8 +133,9 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable
/**
* @dev Returns the URI for a given token ID. May return an empty string.
*
* If the token's URI is non-empty and a base URI was set (via
* {_setBaseURI}), it will be added to the token ID's URI as a prefix.
* If no base URI was set (via {_setBaseURI}), return the token ID's URI.
* If a base URI was set, it will be added as a prefix to the token ID's URI,
* or to the token ID itself, if no URI is set for that token ID.
*
* Reverts if the token ID does not exist.
*/
Expand All @@ -142,19 +144,22 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable

string memory _tokenURI = _tokenURIs[tokenId];

// Even if there is a base URI, it is only appended to non-empty token-specific URIs
if (bytes(_tokenURI).length == 0) {
return "";
} else {
// abi.encodePacked is being used to concatenate strings
// If there is no base URI, return the token URI.
if (bytes(_baseURI).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(_baseURI, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(_baseURI, Strings.fromUint256(tokenId)));
}

/**
* @dev Returns the base URI set via {_setBaseURI}. This will be
* automatically added as a preffix in {tokenURI} to each token's URI, when
* they are non-empty.
* automatically added as a prefix in {tokenURI} to each token's URI, or
* to the token ID if no specific URI is set for that token ID.
*/
function baseURI() public view returns (string memory) {
return _baseURI;
Expand Down Expand Up @@ -444,7 +449,8 @@ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable

/**
* @dev Internal function to set the base URI for all token IDs. It is
* automatically added as a prefix to the value returned in {tokenURI}.
* automatically added as a prefix to the value returned in {tokenURI},
* or to the token ID if {tokenURI} is empty.
*/
function _setBaseURI(string memory baseURI_) internal virtual {
_baseURI = baseURI_;
Expand Down
4 changes: 2 additions & 2 deletions test/token/ERC721/ERC721.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,10 @@ describe('ERC721', function () {
expect(await this.token.tokenURI(firstTokenId)).to.be.equal(newBaseURI + sampleUri);
});

it('token URI is empty for tokens with no URI but with base URI', async function () {
it('tokenId is appended to base URI for tokens with no URI', async function () {
await this.token.setBaseURI(baseURI);

expect(await this.token.tokenURI(firstTokenId)).to.be.equal('');
expect(await this.token.tokenURI(firstTokenId)).to.be.equal(baseURI + firstTokenId);
});

it('tokens with URI can be burnt ', async function () {
Expand Down

0 comments on commit b6513f6

Please sign in to comment.