일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- multicall
- 컨트렉트 배포 자동화
- 티스토리챌린지
- vue기초
- 스마트컨트렉트 예약어 함수이름 중복
- SBT표준
- 러스트기초
- 스마트컨트렉트 함수이름 중복 호출
- erc4337
- 스마트 컨트렉트 함수이름 중복
- Vue
- Vue.js
- git rebase
- erc4337 contract
- ethers typescript
- ethers
- 러스트 기초
- 컨트렉트 동일한 함수이름 호출
- chainlink 설명
- 러스트 기초 학습
- ethers websocket
- 스마트컨트렉트테스트
- 체인의정석
- ethers type
- ambiguous function description
- rust 기초
- 오블완
- 계정추상화
- ethers v6
- 머신러닝기초
Archives
- Today
- Total
체인의정석
ERC721) token URI에 대한 코드 분석 본문
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
반응형
'블록체인 > NFT & BRIDGE' 카테고리의 다른 글
ERC721의 safeTransferFrom (0) | 2022.02.14 |
---|---|
Solidity 에서 token URI 와 toString 라이브러리 (0) | 2022.02.09 |
ERC721 Receiver에 대한 설명 (0) | 2022.02.08 |
Waffle 사용기 - ERC721 테스트 코드 작성하기 (0) | 2022.01.28 |
hardhat 사용법 정리 02- ERC721 배포해보기 (0) | 2022.01.18 |
Comments