1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- // SPDX-License-Identifier: MIT
- // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/extensions/ERC721URIStorage.sol)
- pragma solidity ^0.8.20;
- import {ERC721} from "../ERC721.sol";
- import {Strings} from "../../../utils/Strings.sol";
- import {IERC4906} from "../../../interfaces/IERC4906.sol";
- import {IERC165} from "../../../interfaces/IERC165.sol";
- /**
- * @dev ERC721 token with storage based token URI management.
- */
- abstract contract ERC721URIStorage is IERC4906, ERC721 {
- using Strings for uint256;
- // Optional mapping for token URIs
- mapping(uint256 tokenId => string) private _tokenURIs;
- /**
- * @dev See {IERC165-supportsInterface}
- */
- function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721, IERC165) returns (bool) {
- return interfaceId == bytes4(0x49064906) || super.supportsInterface(interfaceId);
- }
- /**
- * @dev See {IERC721Metadata-tokenURI}.
- */
- function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
- _requireMinted(tokenId);
- string memory _tokenURI = _tokenURIs[tokenId];
- string memory base = _baseURI();
- // If there is no base URI, return the token URI.
- if (bytes(base).length == 0) {
- return _tokenURI;
- }
- // If both are set, concatenate the baseURI and tokenURI (via string.concat).
- if (bytes(_tokenURI).length > 0) {
- return string.concat(base, _tokenURI);
- }
- return super.tokenURI(tokenId);
- }
- /**
- * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
- *
- * Emits {MetadataUpdate}.
- *
- * Requirements:
- *
- * - `tokenId` must exist.
- */
- function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
- if (_ownerOf(tokenId) == address(0)) {
- revert ERC721NonexistentToken(tokenId);
- }
- _tokenURIs[tokenId] = _tokenURI;
- emit MetadataUpdate(tokenId);
- }
- /**
- * @dev See {ERC721-_update}. When burning, this override will additionally check if a
- * token-specific URI was set for the token, and if so, it deletes the token URI from
- * the storage mapping.
- */
- function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {
- address previousOwner = super._update(to, tokenId, auth);
- if (to == address(0) && bytes(_tokenURIs[tokenId]).length != 0) {
- delete _tokenURIs[tokenId];
- }
- return previousOwner;
- }
- }
|