ERC721URIStorage.sol 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // SPDX-License-Identifier: MIT
  2. // OpenZeppelin Contracts (last updated v5.1.0-rc.0) (token/ERC721/extensions/ERC721URIStorage.sol)
  3. pragma solidity ^0.8.20;
  4. import {ERC721} from "../ERC721.sol";
  5. import {Strings} from "../../../utils/Strings.sol";
  6. import {IERC4906} from "../../../interfaces/IERC4906.sol";
  7. import {IERC165} from "../../../interfaces/IERC165.sol";
  8. /**
  9. * @dev ERC-721 token with storage based token URI management.
  10. */
  11. abstract contract ERC721URIStorage is IERC4906, ERC721 {
  12. using Strings for uint256;
  13. // Interface ID as defined in ERC-4906. This does not correspond to a traditional interface ID as ERC-4906 only
  14. // defines events and does not include any external function.
  15. bytes4 private constant ERC4906_INTERFACE_ID = bytes4(0x49064906);
  16. // Optional mapping for token URIs
  17. mapping(uint256 tokenId => string) private _tokenURIs;
  18. /**
  19. * @dev See {IERC165-supportsInterface}
  20. */
  21. function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) {
  22. return interfaceId == ERC4906_INTERFACE_ID || super.supportsInterface(interfaceId);
  23. }
  24. /**
  25. * @dev See {IERC721Metadata-tokenURI}.
  26. */
  27. function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
  28. _requireOwned(tokenId);
  29. string memory _tokenURI = _tokenURIs[tokenId];
  30. string memory base = _baseURI();
  31. // If there is no base URI, return the token URI.
  32. if (bytes(base).length == 0) {
  33. return _tokenURI;
  34. }
  35. // If both are set, concatenate the baseURI and tokenURI (via string.concat).
  36. if (bytes(_tokenURI).length > 0) {
  37. return string.concat(base, _tokenURI);
  38. }
  39. return super.tokenURI(tokenId);
  40. }
  41. /**
  42. * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
  43. *
  44. * Emits {MetadataUpdate}.
  45. */
  46. function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
  47. _tokenURIs[tokenId] = _tokenURI;
  48. emit MetadataUpdate(tokenId);
  49. }
  50. }