_setTokenURI 와 tokenURI의 관계

안녕하세요 오픈제플린을 이용해서 코드를 작성중이구요.

opensea에서 다양한 정보들을 보여주기위해
tokenURI 함수를 다음과같이 작성해뒀는데요.

    constructor(string memory _name, string memory _symbol, string memory _metadataURI) ERC721(_name, _symbol) {
        metadataURI = _metadataURI;
    }

    function tokenURI(uint _tokenId) override public view returns (string memory) {
       // metadataURI는 최초발행시 작성할수있도록 구현
        return string(abi.encodePacked(metadataURI, '/', _tokenId, '.json'));
    }

포럼을 좀 읽어보다보니까 추후를 대비하여 tokenURI를 업데이트 할 수 있도록 구현하라는 뉘앙스의 글을 본것같아서요.

최초 발행시 metadataURI를 지정해줄게아니라
민팅시 _setTokenURI 함수를 통해 구현하려고합니다.
그렇게 되면 tokenURI는 오픈제플린에서 구현되어있으니까 따로 함수를 만들필요가 없는거죠?
따로 만들지않아도 _setTokenURI를 통해 구현해두면 오픈씨에서도 정상적으로 메타데이터를 불러들이나요?

또 서버단에서 json 파일을 서버에 저장하여 반환해줘야지만 하나요? 아니면 그냥 json포맷을 반환해줘도 되는건가요?

마지막으로 민팅 후에 만약에 tokenURI를 변경해야할일이 생긴다면 어떻게 구현을 해야 기존 컨트랙트를 유지하면서 업데이트를 할수있을지 방법이 궁금합니다. 힌트라도 부탁드립니다.

안녕하세요

아래 코드처럼 baseUri를 바꿔줄수있도록 추가하였고 Ownable의 onlyOwner modifier를 통해 권한을 부여했습니다.

해당 코드를 더 개선하여 확장자 부분을 tokenURI 함수안에 추가할수도있습니다.

contract SomeNFT is KIP17Full, KIP17Pausable, Ownable {
  using Strings for uint256;
  using Address for address;

  string private _baseUri;

  function _baseURI() internal view returns (string memory) {
    return _baseUri;
  }

  function tokenURI(uint256 tokenId) external view returns (string memory) {
    require(_exists(tokenId), "URI query for nonexistent token");
    string memory baseURI = _baseURI();
    return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
  }

  function setBaseUri(string calldata _newBaseUri) external onlyOwner {
    _baseUri = _newBaseUri;
  }
}
1 Like