[Solidity] ERC-721 기반 NFT 만들기 (Rinkeby Testnet)
ERC-721 / ERC-165 / NFT / pinata / OpenSea
ERC-721 기반 NFT 만들기
Rinkeby 테스트넷에 ERC-721 토큰 만들고 배포하기
-1. 메타마스크에 접속하고, Rinkeby 테스트 네트워크를 선택한다
-2. Remix IDE 에서 MyNFTs.sol
파일을 생성한다
-3. ERC-721 코드를 입력한다
-4. MyNFTs.sol
파일을 컴파일한다
-5. DEPLOY & RUN TRANSACTIONS 항목으로 이동한다
5-1. ENVIRONMENT 부분을 Injected Web3로 변경하여 ‘메타마스크’와 연동한다
5-2. DEPLOY에 들어갈 인자값을 입력한다
- NAME 👉 NFT 이름
- GETSYMBOL 👉 NFT 이름약자
5-3. 설정이 완료되면 transact 버튼을 누른다
-6. CONTRACT를 클릭하고 배포할 컨트랙트를 MyNFTs
로 선택하고 Deploy
한다
-7. 배포된 함수중에 mintNFT
를 선택해서 빈칸을 입력한다
- recipient 에는 ‘메타마스크 주소’를 입력하면 되고
- tokenURI 에는 NFT화 시킬 이미지가 저장되어있는 ‘주소’를 입력하면 된다
-8. pinata 사이트에 접속해서 https://www.pinata.cloud/ (👈 pinata 사이트)
8-1. NFT화 시킬 이미지를 업로드 한다 👆
8-2. 업로드한 이미지의 CID를 복사해서 ‘json 파일’로 만들어야한다 👆
{
"attributes" : [ {
"trait_type" : "Breed",
"value" : "Maltipoo"
}, {
"trait_type" : "Eye color",
"value" : "Mocha"
} ],
"description" : "The world's most adorable and sensitive pup.",
"image" : "ipfs://이부분에 CID 를 복사해서 넣음",
"name" : "이름 지정하기"
}
8-3. “image” 에 CID를 붙여넣는데 앞에
ipfs://
를 꼭 써줘야한다
8-4. 그리고 다시 json 파일을 업로드 👆
-9. json 파일의 CID를 복사해서 ‘tokenURI’ 에 넣고 transact 버튼을 누른다
CID를 붙여넣는데 앞에
ipfs://
를 꼭 써줘야한다 👆
-10. ‘OpenSea 테스트넷’ 에 들어가서 메타마스크와 지갑연결을 하고 보면
NFT가 정상적으로 발행된걸 확인 할 수 있다
https://testnets.opensea.io/ (👈 OpenSea 테스트넷 사이트)
ERC-721 기반 토큰을 만들기 위한 함수
-
ApprovalForAll
👉 컨트랙트 오너(owner)가 오퍼레이터(operator)에게 모든 자산을 관리할 수 있는 권한을 부여하거나 없앨 수 있다 -
setApprovalForAll
👉 오퍼레이터(operator)의 모든 자산을 관리할 수 있는 권한을 부여하거나 없앨 수 있다 -
ownerOf
👉 tokenId 가 반드시 존재해야 하며, tokenId 에 해당하는 NFT 소유자를 리턴한다 -
getApproved
👉 tokenId 가 반드시 존재해야 하며, tokenId 에 대해 승인된 어카운트(account)를 리턴한다 -
isApprovedForAll
👉 오퍼레이터가 오너의 모든 자산을 관리할 수 있는 권한의 여부를 리턴한다 -
awardItem
👉 아이템 생성을 호출, 토큰을 다른사람들과 거래할수 있다
ERC-165 함수
-
onERC721Received
👉 NFT의 수신을 처리하는 이 컨트랙트는 safeTransfer 후, 수신자가 구현한 이 함수를 호출한다 이 함수는 반드시 함수 선택자를 반환해야 한다
만약 그렇지 않을 경우, 호출자의 트랜잭션은 되돌려진다 -
tokenURI
👉 tokenId 를 입력받아 URI를 리턴한다 NFT에 포함될 이름, 설명, 이미지 URI, Properties를 포함하는 JSON 파일의 형태를 저장한 URI를 입력한다 -
tokenByIndex
👉 컨트랙트에 의해 저장된 모든 토큰의 index를 기반으로 token ID를 리턴한다 totalSupply 와 함께 사용하여 모든 토큰을 열거할 수 있음 -
tokenOfOwnerByIndex
👉 토큰 목록의 인덱스를 기반으로 오너가 소유한 토큰 ID를 리턴한다 balanceOf 와 함께 사용하여 오너의 모든 토큰을 열거할 수 있음
ERC-721 기반 토큰을 만들기 위한 코드
//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract MyNFTs is ERC721URIStorage, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
// 👉 함수 mintNFT 는 라이브러리 Counters 를 이용해 변수 토큰의 ID(_tokenIds)를 관리한다
constructor() ERC721("MyNFTs", "MNFT") {}
// 함수 mintNFT 는 컨트랙트 MyNFTs 에 포함된 함수이다
// 이 함수는 컨트랙트의 오너(owner)만이 새로운 토큰을 생성할 수 있게하는 함수이다
// 👉 함수 mintNFT 는 컨트랙트 Ownable 에 포함된 onlyOwner를 통해,
// 👉 함수를 실행한 지갑의 주소와 오너의 주소가 같은지 검사한다
// 👉 만약 함수를 실행한 지갑의 주소와 오너의 주소가 같다면, 함수를 정상적으로 실행한다
function mintNFT(address recipient, string memory tokenURI)
public
onlyOwner
returns (uint256)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
}
// NFT를 생성할 때, 파라미터 tokenURI 를 전달한다
// tokenURI 는 NFT에 적용할 정보를 담고 있는 json 객체의 엔드포인트이다
// 다시 말해, tokenURI 에 접근하면 NFT의 규칙에 맞는 json 객체를 불러올 수 있어야 함