setTokenURI와 setBaseURI의 차이

옛날에 만들어진 ERC721 튜토리얼을 보면 아래와 같이 minter와 id를 맵핑하고, id와 uri를 맵핑했다.

_mint(minter, tokenId);
_setTokenURI(tokenId, tokenURI);

하지만 최근 nft 프로젝트의 컨트랙트 스타일을 보면 setTokenURI는 아예 사라졌다.

이 이유는 검색하면 바로 나오는데

https://forum.openzeppelin.com/t/why-doesnt-openzeppelin-erc721-contain-settokenuri/6373

because using storage in this way is expensive and we decided to make the default mechanism significantly cheaper.”

즉... 토큰id와 토큰uri를 맵핑하는 storage를 사용하는 방식은 비싸기 때문이다!

따라서 openzepplin에서는 ERC721에 BaseURI를 설정하는 기능을 추가한다. BaseURI는 minting하고자 하는 nft의 metadata들을 모아둔 폴더의 URI이다. 이는 보통 contract가 배포될 때 한번만 실행되는 함수인 constructor에서 정의된다.

constructor(string memory baseURI) ERC721("Cool Cats", "COOL")  {
		//이 부분
        setBaseURI(baseURI);

        // team gets the first 4 cats
        _safeMint( t1, 0);
        _safeMint( t2, 1);
        _safeMint( t3, 2);
        _safeMint( t4, 3);
    }

bayc나 coolcat 처럼 갯수가 정해진 nft collection을 minting하는 경우, baseURI가 모든 nft에 대해 동일하므로 각 nft마다 setTokenURI 함수로 tokenID와 tokenURI를 맵핑(저장)하는 방식대신 baseURI 하나만 storage에 저장한다. 이는 직접적으로 특정 nft의 tokenURI가 storage에 저장되는 방식은 아니지만, 해당 nft의 tokenURI를 찾아볼 수 있는 baseURI가 storage에 저장되어 있고 baseURI와 tokenID를 합친 URI가 해당 nft의 tokenURI로 간주한다.

하지만 만약 미리 IPFS에 올린 nft collection에 대해서 민팅하는것이 아니라, 사용자가 직접 이미지를 업로드하여 민팅하는 방식이라면?

→ 이런 경우는 baseURI가 매번 달라질 것이기 때문에 setTokenURI 를 쓰는 방식이 합리적이다.

결론
미리 IPFS에 업로드된 정해진 NFT collection을 민팅하는 경우에는 setBaseURI 방식이 비용 측면에서 유리하고,
다양한 nft를 dynamic하게 민팅하는 경우엔 setTokenURI 방식을 사용한다.
전자의 경우엔 coolcats, bayc 등의 nft collection이 있고
후자의 경우엔 opensea와 같은 marketplace에서 사용자가 nft를 민팅하는 경우가 있다.

좋은 웹페이지 즐겨찾기