ERC721URIStorage.sol 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // SPDX-License-Identifier: MIT
  2. pragma solidity ^0.8.0;
  3. import "../ERC721.sol";
  4. /**
  5. * @dev ERC721 token with storage based token URI management.
  6. */
  7. abstract contract ERC721URIStorage is ERC721 {
  8. using Strings for uint256;
  9. // Optional mapping for token URIs
  10. mapping(uint256 => string) private _tokenURIs;
  11. /**
  12. * @dev See {IERC721Metadata-tokenURI}.
  13. */
  14. function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
  15. require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");
  16. string memory _tokenURI = _tokenURIs[tokenId];
  17. string memory base = _baseURI();
  18. // If there is no base URI, return the token URI.
  19. if (bytes(base).length == 0) {
  20. return _tokenURI;
  21. }
  22. // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
  23. if (bytes(_tokenURI).length > 0) {
  24. return string(abi.encodePacked(base, _tokenURI));
  25. }
  26. return super.tokenURI(tokenId);
  27. }
  28. /**
  29. * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
  30. *
  31. * Requirements:
  32. *
  33. * - `tokenId` must exist.
  34. */
  35. function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
  36. require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
  37. _tokenURIs[tokenId] = _tokenURI;
  38. }
  39. /**
  40. * @dev Destroys `tokenId`.
  41. * The approval is cleared when the token is burned.
  42. *
  43. * Requirements:
  44. *
  45. * - `tokenId` must exist.
  46. *
  47. * Emits a {Transfer} event.
  48. */
  49. function _burn(uint256 tokenId) internal virtual override {
  50. super._burn(tokenId);
  51. if (bytes(_tokenURIs[tokenId]).length != 0) {
  52. delete _tokenURIs[tokenId];
  53. }
  54. }
  55. }