ERC721URIStorageUpgradeable.sol 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721URIStorage.sol)
  3. pragma solidity ^0.8.0;
  4. import "../ERC721Upgradeable.sol";
  5. import "../../../proxy/utils/Initializable.sol";
  6. /**
  7. * @dev ERC721 token with storage based token URI management.
  8. */
  9. abstract contract ERC721URIStorageUpgradeable is Initializable, ERC721Upgradeable {
  10. function __ERC721URIStorage_init() internal onlyInitializing {
  11. }
  12. function __ERC721URIStorage_init_unchained() internal onlyInitializing {
  13. }
  14. using StringsUpgradeable for uint256;
  15. // Optional mapping for token URIs
  16. mapping(uint256 => string) private _tokenURIs;
  17. /**
  18. * @dev See {IERC721Metadata-tokenURI}.
  19. */
  20. function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
  21. require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
  22. string memory _tokenURI = _tokenURIs[tokenId];
  23. string memory base = _baseURI();
  24. // If there is no base URI, return the token URI.
  25. if (bytes(base).length == 0) {
  26. return _tokenURI;
  27. }
  28. // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
  29. if (bytes(_tokenURI).length > 0) {
  30. return string(abi.encodePacked(base, _tokenURI));
  31. }
  32. return super.tokenURI(tokenId);
  33. }
  34. /**
  35. * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
  36. *
  37. * Requirements:
  38. *
  39. * - `tokenId` must exist.
  40. */
  41. function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
  42. require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
  43. _tokenURIs[tokenId] = _tokenURI;
  44. }
  45. /**
  46. * @dev Destroys `tokenId`.
  47. * The approval is cleared when the token is burned.
  48. *
  49. * Requirements:
  50. *
  51. * - `tokenId` must exist.
  52. *
  53. * Emits a {Transfer} event.
  54. */
  55. function _burn(uint256 tokenId) internal virtual override {
  56. super._burn(tokenId);
  57. if (bytes(_tokenURIs[tokenId]).length != 0) {
  58. delete _tokenURIs[tokenId];
  59. }
  60. }
  61. /**
  62. * This empty reserved space is put in place to allow future versions to add new
  63. * variables without shifting down storage in the inheritance chain.
  64. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
  65. */
  66. uint256[49] private __gap;
  67. }