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 객체를 불러올 수 있어야 함