EIP 4096 has an interesting method of updating your metadata with events, more details here.
So lets see how to implement it with an example.
First you need to create a file with interface that has this code in it
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/// @title EIP-721 Metadata Update Extension
interface IERC4906 is IERC165 {
/// @dev This event emits when the metadata of a token is changed.
/// Third-party platforms such as NFT marketplaces can listen to
/// the event and auto-update the tokens in their apps.
event MetadataUpdate(uint256 _tokenId);
/// @dev This event emits when the metadata of a range of tokens is changed.
/// So that the third-party platforms such as NFT market could
/// timely update the images and related attributes of the NFTs.
event BatchMetadataUpdate(uint256 _fromTokenId, uint256 _toTokenId);
}
then we can implement that interface like example below (we also need to use
supportsInterface function) and call our event BatchMetadataUpdate in the case of updating of _baseTokenURI as this means all NFTs have new URIs and probably new metadata.
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "./IERC4906.sol";
contract ERC4906 is ERC721, IERC4906 {
string private _baseTokenURI = "some URI"
constructor(string memory name_, string memory symbol_) ERC721(name_, symbol_) {
}
function supportsInterface(
bytes4 interfaceId
) public view virtual override(ERC721A, IERC165) returns (bool) {
return super.supportsInterface(interfaceId);
}
function setBaseURI(string calldata baseURI) external onlyOwner {
emit BatchMetadataUpdate(1, type(uint256).max);
_baseTokenURI = baseURI;
}
}
One of the good things is that this EIP has been supported by Open Sea, which means it should be useful and standardized across industry.