블록체인/NFT & BRIDGE
ERC721) token URI에 대한 코드 분석
체인의정석
2022. 2. 8. 15:45
728x90
ERC721에서 token URI는 토큰아이디와 base URI의 조합으로 만들어 진다.
IERC721Metadata.sol
function tokenURI(uint256 tokenId) external view returns (string memory);
ERC721.sol
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
tokenURI 의 id는 다음과 같이 baseURI와 tokenID 를 받아와서 인코딩을 해주고 string으로 형변환을 해준 값이다.
이를통해 Wrapped ERC721을 만드려고 하면 익스텐션 컨트렉트를 사용해야 한다.
contract ERC721MetadataMintable is ERC721, ERC721Metadata, MinterRole {
/**
* @dev Function to mint tokens.
* @param to The address that will receive the minted tokens.
* @param tokenId The token id to mint.
* @param tokenURI The token URI of the minted token.
* @return A boolean that indicates if the operation was successful.
*/
function mintWithTokenURI(address to, uint256 tokenId, string memory tokenURI) public onlyMinter returns (bool) {
_mint(to, tokenId);
_setTokenURI(tokenId, tokenURI);
return true;
}
}
위와 같이 tokenURI를 받아와서 써야 하는데 이를 ERC721 표준의 조회하는 함수를 사용하면 된다.
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId) public view returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
// If there is no base URI, return the token URI.
if (bytes(_baseURI).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(_baseURI, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(_baseURI, tokenId.toString()));
}
위의 부분이 공식 코드이지만
function tokenURI(uint256 tokenId) public view returns (string memory) {
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
기능을 잘 하는것이 중요하니 나는 더 간단하게 이렇게 만들어야 겠다.
tokenURI의 정체는 결국 조회 함수 였고 api 가 이를 불러와서 데이터를 가져오는 거였다니 반전이였다.
이래서 그렇게 찾기가 어려웠나 보다.
생각해보니 굳이 저장을 따로 할 필요는 없어보인다.
이번글은 클론네버다이 개발자 게뜨님에게 물어보고 더 자세히 알게 되었다.
감사합니다 :)
728x90
반응형