[BEB] Section4 : ERC-721 과 NFT / Remix, Truffle을 이용한 ERC-721 개발

jsg_ko·2022년 1월 30일
0

ERC-721과 NFT

🔥ERC-721을 NFT라 부르는 이유

EIP-721, 이더리움 개선 제안의 721번째 토론에서는 하나하나의 구분 가능한 토큰에 대한 토론이 이뤄졌다. ERC-20으로 생성한 Fungible Token, 완전히 대체 가능한 토큰이 아니라 단 하나의 토큰으로써 식별이 가능하고, 하나의 토큰을 추적할 수 있게 하는 토큰이 NFT(Non-Fungible Token)이다.

💡 ERC-20과 ERC-721에 차이점 예
철수가 가지고 있는 1000원과 영희가 가지고 있는 1000원은 동일한 가치를 가지고 있으며 대체가능한 즉 교환이 가능하다. 반면에 미술품이나, 문화재는 각각의 가치를 가지고 있으며 대체 불가능하다.

🔥NFT 거래 플랫폼

세계 최대 규모의 이더리움 기반 NFT 거래 플랫폼은 OpenSea 이다. 오픈씨에는 미술(Art), 음악(Music), 도메인 이름(Domain Names), 가상 세계(Virtual Worlds), 트레이딩 카드(Trading Cards) 등 다양한 형태의 NFT가 거래되고 있다.

NFT의 영역에서 가장 대표적인 카테고리는 미술이다. Art 탭으로 이동하면, 무수히 많은 개인작가 또는 pfp 프로젝트 들의 콜렉션을 찾을 수 있다. 이 하나하나의 콜렉션이 전부 하나의 스마트 컨트랙트로 구성되어 있다.

ERC-721에서 스마트 컨트랙트의 이름과 심볼을 설정할 수 있다. 이 이름은 콜렉션의 이름이, 이 심볼은 콜렉션의 심볼이 된다.오픈씨에서는 스마트 컨트랙트의 오너를, 콜렉션의 오너로 자동으로 등록한다. 스마트 컨트랙트의 오너 지갑으로 오픈씨에 로그인하면, 자신의 콜렉션을 수정할 수 있다.

🔥NFT 사용 플랫폼

ERC-721을 사용한 최초의 NFT 플랫폼은 Crypto Kitty 이다.

크립토키티는 옛날의 다마고치와 비슷한 게임이다. 이더리움을 지불하고 고양이 캐릭터를 생성한다. 두 개의 고양이를 교배하여 새로운 고양이 캐릭터를 생성할 수 있다.

모든 고양이는 NFT로 발행된다. NFT의 특성을 유지하기 위해, 크립토키티의 모든 고양이는 중복되지 않는다. 더 많은 사람들이 더 희귀한 고양이 캐릭터를 가지려고 노력했고, 팬덤의 영향력으로 인해, 더 많은 사람들이 더 희귀한 고양이 캐릭터를 거래했다.

ERC-721 함수의 기능

ERC721은 옵션 확장이 여러 개 있는 ERC20보다 더 복잡한 표준이며 여러 계약으로 분할된다. OpenZeppelin 계약은 사용자 정의 유용한 확장과 함께 결합 방법에 대한 유연성을 제공한다. 이에 대한 자세한 내용은 API 레퍼런스 확인.

GameItem에서 NFT 사용하기 - awardItem

ERC721을 사용하여, 각각 고유한 속성이 있는 게임 아이템을 생성할 수 있다. 플레이어에게 보상될 때마다 새로운 NFT가 발행되어 플레이어에게 전송된다.

모든 플레이어의 계정에서 awardItem 을 통해 아이템 생성을 호출 할 수 있다. 어떤 계정이 아이템을 만들 수 있는지 제한하기 위해 Access Control 을 추가할 수도 있다.

다음은 awardItem 의 예시이다.

🔥IERC721

ERC721 준수 계약의 필수 인터페이스이다.

https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#IERC721

ApprovalForAll

ApprovalForAll(address owner, address operator, bool approved)

컨트랙트 오너(owner)가 오퍼레이터(operator)에게 모든 자산을 관리할 수 있는 권한을 부여하거나 없앨 수 있다.ApprovalForAllTransfer(from, to, tokenId), Approval(owner, approved, tokenId) 와 함께 함수가 아닌 이벤트로 취급된다.setApprovalForAll 함수를 실행하면, 이 이벤트가 발생한다.

ownerof

ownerOf(uint256 tokenId)address owner

tokenId 가 반드시 존재해야 하며, tokenId 에 해당하는 NFT 소유자를 리턴한다.

함수 ownerOf는 public으로 공개해 사용한다. tokenId 를 입력받고, 해당 토큰을 소유하고 있는 주소를 리턴한다. 토큰의 소유자가 없다면(오너의 주소값이 0이라면), 에러를 발생한다.

serApprovalForAll

setApprovalForAll(address operator, bool _approved)

오퍼레이터(operator)의 모든 자산을 관리할 수 있는 권한을 부여하거나 없앨 수 있다.

이 함수를 실행하면 ApprovalForAll(owner, operator, approved) 이벤트가 발생한다.

💡 오퍼레이터는 이 함수를 호출할 수 없다.

setApprovalForAll 함수는 public으로 공개해 사용한다. 실제 함수 내부에서는 전달받은 파라미터 operatorapproved 를 함수 _setApprovalForAll 로 전달하고 있다.

함수 _setApprovalForAll 은 함수 내부에서만 사용가능한 internal 함수이다. 함수 _setApprovalForAll 은 import한 ERC721.sol 파일에 다음과 같이 작성되어 있다.

require 구문을 통해, owner와 operator가 서로 다른지 검사한다. 오너가 자기 자신을 제외한 다른 주소에게 권한을 주는 함수이므로, require를 통해 검증 후 다음 코드로 넘어간다. _operatorApprovals 객체는 오너와 오퍼레이터를 매칭하고, 오퍼레이터에게 권한을 준상태이면 true, 그렇지 않으면 false로 상태를 담고 있다. 파라미터로 전달된 approved에 따라 결정된다. 마지막으로 emit ApprovalForAll(owner, operator, approved) 으로 이벤트를 발생시킨다.

getApproved

getApproved(uint256 tokenId)address operator

tokenId 가 반드시 존재해야 하며, tokenId 피라미터로 입력받아 , tokenId 와 매핑된 주소 즉, 승인된 어카운트(account)를 리턴한다.

isApprovedForAll

isApprovedForAll(address owner, address operator)bool

오퍼레이터가 오너의 모든 자산을 관리할 수 있는 권한의 여부를 리턴한다.

owner의 주소와 operator의 주소를 입력받고, owner가 operator에게 준 권한의 유무를 boolean으로 리턴합니다.

onERC721Received

onERC721Received(address operator, address from, uint256 tokenId, bytes data)bytes4

함수 onERC721Received 는 컨트랙트 IERC721Receiver 에 작성된 함수이다. IERC721Receiver 는 자산의 컨트랙트에서 safeTransfer를 지원하려는 모든 컨트랙트에 대한 인터페이스이다.

NFT의 수신을 처리하는 이 컨트랙트는 safeTransfer 후, 수신자가 구현한 이 함수를 호출한다. 이 함수는 반드시 함수 선택자를 반환해야 한다. 만약 그렇지 않을 경우, 호출자의 트랜잭션은 되돌려 진다. 반환될 SelectorIERC721.onERC721Received.selector 로 얻을 수 있다.

다음은 OpenZeppelin에서 onERC721Received 예시이다.

tokenURI

tokenURI(uint256 tokenId)string

인터페이스 IERC721Metadata 에 작성되어 있는 이 함수는, tokenId 를 입력받아 URI를 리턴한다. 일반적으로 NFT에 포함될 이름, 설명, 이미지 URI, Properties를 포함하는 JSON 파일의 형태를 저장한 URI를 입력한다.

tokenURI 함수는 위와 같이 public으로 공개해 사용한다. 실제 함수 내부에서는 전달받은 파라미터 tokenId가 이미 존재하는지 검사한다. tokenId에 해당하는 NFT가 있다면, 리턴값을 준비한다.

함수_baseURI를 실행하여, baseURI가 설정되어 있는지 검사한다. baseURI가 설정되어 있다면, baseURI와 tokenId를 합친 문자열을 리턴한다. baseURI가 없다면 빈 문자열을 리턴한다.

tokenByIndex

tokenByIndex(uint256 index)uint256

인터페이스 IERC721Enumerable 에 작성되어 있는 이 함수는, 컨트랙트에 의해 저장된 모든 토큰의 index를 기반으로 token ID를 리턴한다. totalSupply 와 함께 사용하여 모든 토큰을 열거할 수 있다.

tokenOfOwnerByIndex

tokenOfOwnerByIndex(address owner, uint256 index)uint256 tokenId

인터페이스 IERC721Enumerable 에 작성되어 있는 이 함수는, 토큰 목록의 인덱스를 기반으로 오너가 소유한 토큰 ID를 리턴한다. balanceOf 와 함께 사용하여 오너의 모든 토큰을 열거할 수 있다.

🔥ERC-165

ERC165는 ERC-721 스마트 컨트랙트를 생성할 때 반드시 구현해야하는 인터페이스(Interface)를 검사하고, 언제 사용하는지 감지한다.

인터페이스 ERC165는 함수 supportsInterface(bytes4 interfaceID)bool 만 가지고 있다. 이 함수의 파라미터로 ERC-721의 인터페이스 ID를 입력해야만, ERC-721 스마트 컨트랙트가 정상적으로 동작한다.

다음은 인터페이스 ERC165이다.

인터페이스 ERC165를 통해 사용가능한 인터페이스인지 확인할 수 있다.EIP-721에 작성되어 있는 인터페이스 id는 0x80ac58cd이다.인터페이스 id는 ERC-721에 작성된 기본적인 인터페이스를, 몇 번의 암호화 과정을 거쳐 축약한다.인터페이스 id는 작성된 함수를 하나의 잎(leaf)으로 두고 생성한 머클 루트(root)로 볼 수 있다.

Remix를 이용한 ERC-721 개발

이전과 마찬가지로 웹 브라우저로 스마트 컨트랙트를 빌드, 배포할 것이기 때문에 Remix에 MetaMask가 연결되어 있어야 한다.

🔥Remix에서 ERC-721 개발하기 (1)

  1. 새로운 Workspaces 를 생성한다

  2. contracts 폴더 내에 자동으로 생성된 파일을 삭제하고, ERC-721 개발 코드를 작성할 파일을 생성한다


  3. NFT를 위한 스마트 컨트랙트의 상위 객체는 ERC-721이다.새로운 컨트랙트를 생성하고, openzeppelin 의 ERC721 객체를 상속한다.

    스크린샷, 2022-01-30 16-28-50.png

  4. 탭을 선택하고, 코드를 컴파일한다. 아래의 이미지와 같이 나타나는 경고는 무시하더라도 컴파일하는데에 문제는 없다.

💡 이 경고는 public 이나 external 같은 가시성 지정자(Visibility Specifiers) 에 대한 내용이다. 위 코드에서 불필요한 부분을 제거하면, 이 경고도 사라진다.

  1. Remix에 MetaMask를 연결했고, 네트워크가 Ropsten 테스트넷인지 확인하고 NFT에 적용 될 namesymbol을 입력한다.

  2. 나타나는 MetaMask의 팝업창에서 확인 버튼을 눌러 디지털 서명을 완료하면 아럐와 같이, Remix 하단의 CLI 화면에서 배포가 완료된 것을 확인할 수 있다.

  3. 화면의 왼쪽에서, 배포된 컨트랙트와 소통할 수 있다. 그러나 openzeppelin 의 ERC-721만을 상속받아 생성한 컨트랙트는, NFT를 발행하는 기능이 없다. 가지고 있는 기능은 approve,safeTransferFrom, setApprovalForAll, transferFrom 의 트랜잭션 생성 함수와, 몇 가지의 call 함수이다.

🔥Remix에서 ERC-721 개발하기 (2)

openzeppelinERC721.sol 에는 ERC-721 표준만 구현되어 있다. 한정된 수량의 토큰을 관리할 때에는 미리 발행해두고 토큰의 데이터(tokenUri)를 업데이트하는 것으로 관리할 수 있다. 만약 컨트랙트를 이용해 새로운 NFT를 발행하려면, 새로운 기능을 추가해야 한다.

  1. 새로운 NFT 발행을 위해, Ethereum NFT Tutorials를 살펴보자. STEP 10에 작성된 예시를 복사하고, Remix에 붙여넣는다.


  2. 코드를 붙여넣고, 몇 가지를 수정한다.

    • solidity version을 사용하는 컴파일러의 버전(^0.8.7)으로 변경한다.
    • 발행할 컨트랙트의 이름을 지정한다. 공식 튜토리얼로부터 복사한 컨트랙트의 이름은 MyNFT 이지만, 이 콘텐츠에서 사용한 컨트랙트의 이름은 MyNFTs 이다.
  3. 컨트랙트의 컴파일을 진행 배포 탭으로 이동한다. CONTRACT를 클릭하고, 배포할 컨트랙트를 선택합니다. 그 다음, Deploy 를 눌러 컨트랙트를 배포한다. 나타나는 MetaMask 팝업 창에서 디지털 서명을 완료하고 잠시 기다리면 배포가 완료된다.

  4. 배포된 컨트랙트를 통해 NFT를 발행할 수 있다. 이전과 달리, mintNFT 트랜잭션 생성 함수가 포함된 걸 확인할 수 있다. 함수 mintNFT 는 컨트랙트 MyNFTs 에 포함된 함수이다.

    이 함수는 컨트랙트의 오너(owner)만이 새로운 토큰을 생성할 수 있게하는 함수다. 코드를 보며 다시 살펴보자.

    contract MyNFTs is ERC721URIStorage, Ownable {
        using Counters for Counters.Counter;
        Counters.Counter private _tokenIds;
    
        constructor() public ERC721("MyNFTs", "MNFT") {}
    
        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;
        }
    }

    함수 mintNFT 는 컨트랙트 Ownable 에 포함된 함수 제어자 onlyOwner를 통해, 함수를 실행한 지갑의 주소와 오너의 주소가 같은지 검사한다. 만약 함수를 실행한 지갑의 주소와 오너의 주소가 같다면, 함수를 정상적으로 실행한다. 함수 mintNFT 는 라이브러리 Counters 를 이용해 변수 토큰의 ID(_tokenIds)를 관리한다. NFT는 규칙에 따라, 유일무이한 형태로 제공되어야 한다. 따라서, 하나의 토큰 id는 유니크해야 한다.

    NFT를 생성할 때, 파라미터 tokenURI 를 전달한다. tokenURI 는 NFT에 적용할 정보를 담고 있는 json 객체의 엔드포인트이다. 다시 말해, tokenURI 에 접근하면 NFT의 규칙에 맞는 json 객체를 불러올 수 있어야 한다.

    tokenURI 는 다음과 같이 객체 형태의 JSON 메타데이터 name, description, image, attributes 등을 담고 있다. name 은 NFT의 이름, description 은 NFT에 대한 설명, image 는 image URI, attributes 는 개발자가 사용하려고 넣어둔 메타데이터이다.

    {
    	"name": "name #1",
    	"description": "description",
    	"image": "imageUri",
    	"attributes": [
    		{
    			"trait_type": "Background",
    			"value": "White"
    		}
    	]
    }

    tokenURI에 의해 제공되는 메타데이터 JSON은, OpenSea에 적용된 NFT 예시를 통해 쉽게 이해할 수 있다. 아래의 NFT는 CryptoPunks에서 발행된 NFT이다. token URI로 부터 얻은 메타데이터(JSON 객체)에 포함된 내용을 화면에 보여주고 있다. 이미지는 image 에 포함된 image URI로부터, Description과 Properties는 각각 descriptionattributes 로부터 불러와 적용되어 있다.


  5. 테스트를 위해, 새로운 JSON 메타데이터를 생성하였다. 이 메타데이터는 다음과 같다.

    {
      "name": "Codestates #1",
      "description": "Deep dive into Blockchain Engineering Bootcamp!",
      "image": "https://urclass-images.s3.ap-northeast-2.amazonaws.com/beb/section4/unit4/Gray.png",
      "attributes": [
        {
          "trait_type": "Power",
          "value": "Max"
        }
      ]
    }

    이 json 파일을 아마존 s3 버킷에 업로드했다. 이 s3 버킷에 위치한 json 파일의 uri를 복사한 다음, Remix의 배포 탭에서 mintNFT 를 실행한다. 이때 주소는 컨트랙트의 오너 지갑 주소를 입력한다.

    지갑 주소와 tokenUri를 정확히 입력했다면, transact 를 눌러 mintNFT 함수를 실행한다.

    이 함수의 실행 결과로 나타난 트랜잭션 해시를 복사하여, 이더스캔에서 검색해보자.

    정상적으로 NFT가 발행된 걸 확인할 수 있다. 하지만 Ropsten 테스트 네트워크에서 발행한 토큰을 OpenSea에서 확인할 수는 없다. 발행한 NFT를 OpenSea에서 확인하려면, Rinkeby 테스트 네트워크를 사용해야 한다.

💡 이더스캔에서 트랜잭션의 Input Data 에서 Decode Input Data 를 클릭하면, tokenURI 를 확인할 수 있다

Rinkeby 테스트 네트워크를 통해 발행한 NFT 예시

🔥IPFS와 NFT

IPFS(InterPlanetary File System; 분산 파일 시스템)는 모든 컴퓨터를 연결하고자 하는 분산된 P2P 파일 시스템이다. IPFS Web는 기존의 HTTP Web의 문제점을 해결하고 보완한 새로운 Web이다.

IPFS의 특징

  • 중앙화된 서버 없이 노드들의 P2P 통신으로 실현한 더 빠르고 안전하고 열린 네트워크 이다. 대형 서버의 연결이 차단되면 치명적인 결과를 낳는 과거 HTTP Web과는 달리, IPFS에서는 몇몇 노드들이 연결이 끊어지더라도 생태계가 안정적으로 유지된다.
  • 고용량의 파일을 빠르고 효율적이게 전달할 수 있으며(BitSwap), 파일들의 중복을 알 수 있기 때문에 저장소도 효율적으로 사용할 수 있다(Merkle DAG, contents-addressed)
  • IPFS 상에 업로드된 파일의 이름은 영원히 기록되며, 만약 IPFS 상에서 지키고 싶은 파일은 원하는 만큼 지켜낼 수 있다(pinning). 또한 파일의 버전 관리(Git)가 가능하다.
  • 인터넷에 원활하게 접속할 수 없는 상황이더라도 IPFS의 생태계는 유지된다.

IPFS의 동작원리

  • 각각의 파일은 여러 개의 블록으로 이루어져 있으며, 각각의 블록은 해시로 표현된 고유의 이름이 있다.
  • IPFS는 모든 파일의 이름을 데이터베이스 속에 저장하며, 동일 파일의 중복을 배제하고, 각 파일의 버전 정보를 트래킹한다.
  • 각 노드는 본인이 관심있는 파일만 저장소에 보관하며, 인덱싱 정보를 통해 누가 어떤 파일을 저장하고 있는지 알 수 있다.
  • 네트워크에서 파일을 찾기 위해서는, 파일명을 조회하고 해당 파일을 갖고 있는 노드를 물어보면 된다
  • IPNS를 통해 모든 파일명은 인간이 읽기 쉬운 형태(DNS와 유사한 개념)로 변환할 수 있다.

IPFS에 파일을 업로드하면, 업로드된 파일의 해시값이 산출된다. 이 해시값은 업로드된 파일의 영구적인 이름으로 상용된다. 이 해시값을 이용해, IPFS를 제공하는 노드의 엔드포인트를 tokenURI로써 블록체인에 저장하여 온체인 NFT를 구현할 수 있다.

IPFS를 직접 설치하고 파일을 업로드하는 방법과, 대표적인 IPFS 노드에 파일을 업로드하는 방법이 있다. 어느 방법이든 IPFS에 파일을 업로드하면, 더 이상 파일을 수정할 수 없다.

따라서 제공하려는 NFT의 특징에 따라 IPFS를 선택할 수도, 또는 아마존 s3 버킷과 같은 클라우드 컴퓨팅을 사용할 수도 있다.

Remix에서 IPFS에 배포하기

Remix에서 컨트랙트를 배포할 때 위 사진처럼 Publish to IPFS 체크박스가 존재한다. 이 체크박스에 체크하는 것으로, 컨트랙트를 IPFS와 함께 배포할 수 있다.

Truffle을 이용한 ERC-721 개발

🔥Local에서 ERC-721 개발하기

ERC-721에는 메타데이터가 포함되어야 한다. tokenUri 를 통해 이미지를 포함한 각종 메타데이터를 전달할 수 있다는 걸 배웠다. 이 유닛에서는 로컬 환경에서 ERC-721을 개발하고, Truffle을 이용한 배포를 실습한다. NFT와 메타데이터를 연동하는 부분은 다른 유닛에서 다룬다.

  1. 로컬에서 NFT를 개발하기 위해, Truffle과 Ganache를 사용한다. 먼저, 새로운 폴더를 생성하고 Truffle을 이용한 개발 환경을 준비한다.

    # 폴더 생성
    mkdir erc721
    # 폴더 진입
    cd erc721
    # truffle 초기화
    truffle init
    # npm 초기화
    npm init
  2. 개발 환경 준비를 마쳤다면, VScode를 실행한다.

    먼저 몇 가지 세팅을 해야한다. truffle-config.js 를 열고, solc를 설정한다. solc 는 Solidity, Compiler의 버전 등을 설정한다. 이 예시에서 사용하는 Solidity의 버전은 "0.8.7"이고, Compiler의 버전은 "london"이다. 주석을 제거하고, 다음과 같이 설정을 수정한다.

    다음은 네트워크 설정을 편집한다. Ganache를 이용해 로컬 환경에서 테스트할 예정이므로, 먼저 Ganache를 등록한다. 주석을 제거하고, developement 를 구분하기 좋게 ganache 로 변경한다.


    이제 로컬 환경에서 Truffle과 Ganache를 이용해 개발하는 환경을 구축했다.

  3. 이전 콘텐츠에서 작성한 코드를 가져와 파일을 생성해 복붙한다. 이 코드를 그대로 이용해도 좋지만, CLI 환경에서 보다 편리하게 테스트하기 위해 다음과 같이 편집하여 사용한다.

    함수 mintNFT 에서 변경된 부분은 다음과 같다.

    • 파라미터 address recipient 삭제

    • 파라미터 address recipient 를 사용하는 _mint 함수 실행부에서, recipientmsg.sender 로 대체

      이렇게 변경하면, 오너의 지갑 주소에서만 함수 mintNFT 를 실행할 수 있고, 새로운 NFT는 항상 오너의 지갑 주소로 발행된다.

      💡 mint 함수는 사용하려는 형태에 따라 편집해서 사용한다. 정해진 수량의 NFT만 제공하는 경우, NFT를 미리 발행해둔 채 tokenUri 만 업데이트하는 형태로 사용하기도 한다. 개인 작가처럼 꾸준히 새로운 작품을 NFT로 발행하려면, mint 함수를 생성해두는 편이 좋다. 상황에 따라 알맞는 형태로 함수를 구현해야 한다.

  4. 이 파일에서는 OpenZeppelin의 파일을 참조하고 있다. 따라서, npm 을 통해 openzeppelin 을 설치해야 한다.

    npm install @openzeppelin/contracts
  5. 붙여넣은 코드가 정상적으로 배포되기 위해서는, migration 파일을 설정해야 한다.1_initial_migration.js 파일을 연다. 그리고 다음과 같이 편집한다.

    이걸로 ERC721을 이용한 개발을 마쳤다. 배포 콘텐츠를 통해, 작성한 컨트랙트를 로컬에서 Truffle과 Ganache로 배포한다.

🔥Truffle로 ERC-721 배포하기

  1. 로컬 환경에서 Ganache를 이용해 컨트랙트를 배포한다. 먼저, 새로운 터미널을 열고 Ganache를 실행한다.

    가나슈 다운로드

    ./ganache-2.5.4-linux-x86_64.AppImage
  2. 트러플을 이용해 컨트랙트를 컴파일 한 후에 가나슈 네트워크에 컨트랙트를 배포한다.

    truffle compile --network ganache // 컨트랙트 컴파일
    
    truffle migrate --network ganache // 컨트랙트 배포


  3. 컨트랙트의 배포가 잘 이루어졌다면, 다음은 Truffle console에 진입한다. Truffle console을 이용해 컨트랙트를 조작할 수 있다.

    truffle console --network ganache
  4. Truffle console에서, 배포한 컨트랙트의 인스턴스를 받아온다. 그리고 배포한 컨트랙트가, 작성한 코드와 일치하는지 확인한다.

  5. 배포된 컨트랙트에 대한 확인을 마쳤으면, 작성한 함수가 잘 동작하는지 확인한다. 이때 함수의 마지막 파라미터로 실행할 지갑 주소를 함께 전달해야 한다. 이 지갑의 주소는 ganache 의 첫번째 지갑(0번째 인덱스 지갑) 주소이다. Ganache를 이용해 컨트랙트를 배포할 때에는, default로 첫번째 지갑(0번째 인덱스 지갑)의 주소에서 컨트랙트를 배포한다.

    instance.mintNFT("https://urclass-images.s3.ap-northeast-2.amazonaws.com/beb/section4/unit4/test.json", { from: accounts[0] })


  6. 그 다음 발행된 NFT로부터 tokenURI 를 확인한다.


가나슈 gui를 확인해보면 블록 생성, 컨트랙트 배포등 정상적으로 작동된 이력을 확인 할 수 있다.

앞으로 다른 네트워크(ex. 메인넷)에 배포할 때에도 truffle-config.js 에 네트워크 정보를 추가하고, Truffle 명령어 중 옵션 -network 와 함께 네트워크의 정보를 담고있는 키를 입력하면 된다.

Minting 플랫폼

개발자 또는 프로젝트의 관리자가 작품을 직접 민팅해두지 않고, 민팅할 수 있는 총 수량만 제한한 채 컨트랙트를 발행할 수 있다. 또는 자체 웹 페이지를 구축하고 서버와 통신한 다음, 개인이 직접 NFT를 민팅할 수 있게 하기도 한다. 이런 형태의 민팅을 웹 민팅이라고 한다.

웹 기반 민팅 플랫폼이 하나 둘 생겨나고 있으며, 개발자 없이 민팅할 수 있도록 도와주는 플랫폼도 존재한다.


대표적으로 오픈씨는 이더리움과 폴리곤 기반의 NFT를 몇 가지 메타데이터와 이미지 파일만으로 발행할 수 있다.

이외에도 웹사이트를 제공하고, 거래소를 생성하는 경우도 있다. Terra 기반의 randomearth.io는 거래소 기능과 함께, NFT 프로젝트의 웹 민팅을 도와주고 있다. 사람들이 NFT를 발행하면, 웹 애플리케이션에 연결한 지갑 주소로 NFT를 발행하고, 그 대가로 지정된 암호화폐 또는 토큰을 지불한다.

예를 들어 Terra 기반의 최초 NFT, Galatic Punks는 초기 사용자를 대상으로 3 $Luna에 1개의 NFT를 발행할 수 있도록 했다.

웹 애플리케이션은 기획자나 개발자에 의해 기능이나 방식이 얼마든지 변경될 수 있다.

profile
디버깅에서 재미를 추구하면 안되는 걸까

0개의 댓글