NFT(CW721) 발행하기 (Vault)
CW721을 이용하면 XPLA 블록체인에서 쉽게 NFT를 발행할 수 있습니다. 직접 Vault로 NFT를 만들어보고, 게임에 적용해봅시다.
NFT란 무엇인가요?
NFT란 Non-Fungible Token
의 약자로, 대체 불가능한 토큰이란 뜻입니다. 대체 불가능
이라는 건 무슨 뜻일까요?
1달러짜리 지폐 두 장의 가치는 서로 같습니다. 둘 다 1달러의 가치를 지니므로, 하나가 다른 하나를 대체할 수 있습니다. 그러나 Alice가 그린 모나지라 그림과 루브르 박물관에 있는 모나리자의 가치는 어떨까요? Alice가 모나리자 그림의 모든 부분을 똑같이 묘사해도, 진짜 모나리자를 대체할 수는 없습니다. 이처럼 서로 대체할 수 없는 고유한 토큰을 두고 NFT라고 부릅니다.
NFT로 무엇을 할 수 있을까요? Alice는 그림을 하나 그려 프로필 사진으로 사용하려고 합니다. 그런데 누군가가 Alice의 그림을 복사하여 사용하고, 자신이 그린 그림이라고 주장하면 어떡할까요? Alice가 그림의 주요 정보를 NFT에 담는다면 그림의 소유권을 증명할 수 있을 것입니다.
CW721이란 무엇인가요?
XPLA 블록체인은 스마트 컨트랙트 플랫폼인 Cosmwasm
을 이용합니다. 이더리움의 ERC721처럼, CW721은 Cosmwasm
에서 대체 불가능한 토큰(Non-Fungible Tokens)에 대한 표준입니다. ERC721과 이름은 비슷할지 몰라도, 기능은 많이 다릅니다. 더 자세히 알고 싶다면 공식 문서를 참고해보세요.
CW721발행하기
다음과 같은 절차로 Vault를 통해 CW721 컨트랙트를 생성하고, NFT를 민팅할 수 있습니다.
Vault 접속
먼저 Chrome Extension 앱인 Vault에서 CW721 컨트랙트를 생성할 지갑을 선택하고, 네트워크를 testnet
으로 설정합니다.




Vault 웹사이트에 접속하고, 우측 상단 Connect
버튼을 클릭하여 지갑을 연결합니다.



CW721 컨트랙트 생성
Vault 웹에서 Contract 항목을 클릭합니다.

Instantiate
버튼을 클릭합니다.

Admin
이란 컨트랙트의 주인이 될 지갑 주소입니다. 예제에서는 xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk
지갑 주소를 입력하겠습니다.

CW721 컨트랙트의 Code ID
는 3
이므로, Code ID
에는 3
을 입력해줍니다.
Code ID란 무엇인가요?
EVM과 달리, Cosmwasm에서는 코드 배포(Code Deploy)와 컨트랙트 생성이 한번에 이뤄지지 않습니다. 먼저 코드를 블록체인에 배포(StoreCode)하면 해당 코드의 Code ID
를 발급 받습니다. 이후 Code ID
를 기반으로 컨트랙트를 생성(InstantiateContract)할 수 있습니다.
똑같은 Code ID로 생성된 컨트랙트들은 모두 같은 코드 기반입니다. 다만 컨트랙트를 생성할 때 입력하는 초깃값(init_msg)이 다르면, 컨트랙트의 세부 사항도 달라집니다. 더 자세한 사항은 XPLA Docs를 참고해보세요.

Init msg
에는 컨트랙트의 초깃값을 입력해주어야 합니다. 초깃값은 발행할 NFT에 대한 정보입니다. NFT 발행을 누가할 것인지(minter), NFT Collection의 이름(name) 등을 살펴볼 수 있습니다.
예제에서는 아래 형식으로 입력하도록 하겠습니다. 여러분은 minter 항목에 본인 지갑 주소를 입력하시면 됩니다. name, symbol 값도 바꾸고 싶다면 다른 값으로 넣어주세요.
{
"name": "YourNFTName",
"symbol": "YNN",
"minter": "xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk"
}

Amount
는 컨트랙트 Instantiate
를 진행할 때, 컨트랙트에 전송하고 싶은 XPLA 수량을 의미합니다. CW721 컨트랙트는 XPLA 코인을 보유할 이유가 없으므로, 이 부분은 생략하셔도 좋습니다.
Label
은 컨트랙트의 기능을 나타내도록 작성하는 것이 좋습니다. 예제에서는 My NFT
로 기입하겠습니다. 이후 Submit 버튼을 눌러주세요.

컨트랙트를 Instantiate
하고 싶은데, 각 항목에 어떤 값을 입력해야 할 지 모를 때가 있습니다. 그럴 때는 같은 Code ID
로 Instantiate
된 컨트랙트를 참고하면 됩니다. 예를 들어, Code ID
가 3인 다른 CW721 컨트랙트를 XPLA Explorer에서 살펴봅시다. Init Msg
값을 참고하여 여러분의 기호대로 내용을 수정하면, 쉽게 컨트랙트를 생성할 수 있습니다.
Submit 버튼을 누르면 Chrome Extension Vault 앱에서 팝업이 하나 뜨게 됩니다. 이때 Password를 입력하면, Instantatie
Method 트랜잭션에 서명하게 되는 것입니다. 지갑을 만들었을 때 설정했던 Password를 입력하고, Post 버튼을 눌러주세요.

서명이 완료되면 트랜잭션이 XPLA 블록체인에 기록될 때까지 기다려야 합니다. 트랜잭션이 생성되었다면 XPLA Explorer에서 트랜잭션 정보를 확인할 수 있습니다. Tx hash 값을 클릭해보세요.


EventLogs에서 여러분이 발행한 CW721 컨트랙트 주소를 알 수 있습니다.

예제에서 만든 CW721 컨트랙트의 주소는 xpla1wx3rm4qxf7l3tczj20mxz62wpnr74kme3f45tvk3muh78c432ucs2ceuqn
입니다.
NFT 민팅하기
이제 생성한 CW721 컨트랙트로 NFT를 민팅해봅시다. 다시 Vault 웹에서 Contract 탭에 접속해주세요.

검색 항목에 직접 만든 CW721 컨트랙트 주소를 넣고, Execute 버튼을 클릭합니다.

Msg
항목에는 발행할 NFT의 주요 정보(metadata)를 적어줍니다. 예제에서는 아래와 같이 작성하겠습니다. token_id
항목은 NFT의 고유한 번호입니다. 따라서 같은 CW721 컨트랙트에서 발행하는 NFT는 모두 token_id
가 달라야 합니다.
attributes
항목에는 NFT의 특성입니다. 예제에서는 체력(HP) 10, 전투능력(CP) 100인 Alice라는 이름의 캐릭터 NFT를 만든다고 가정하겠습니다.
{
"mint": {
"owner": "xpla1cwduqw0z8y66mnfpev2mvrzzzu98tuexepmwrk",
"token_id": "token_id_myExampleNFT1",
"extension": {
"name": "My Test XPLA NFT",
"attributes": [
{
"value": "Alice",
"trait_type": "CharacterName"
},
{
"value": "100",
"trait_type": "CP"
},
{
"value": "10",
"trait_type": "HP"
}
],
"description": "This is my First NFT in XPLA Blockchain!"
}
}
}

주요 정보(metadata)에는 어떤 값들이 들어가야 하나요?
주요 정보(metadata)에 들어갈 수 있는 항목들은 아래와 같습니다.
{
mint: {
owner: "NFT Owner의 주소를 입력합니다.",
token_id: "개별 NFT 고유 식별자로 사용되는 Token ID입니다.",
token_uri: "아래 extension 정보를 JSON 형식으로 제공하는 URI입니다. OpenSea에서 사용하는 형식과 동일합니다.",
extension: {
name : "NFT 이름입니다.",
description : "NFT에 대한 설명입니다.",
image : "NFT 이미지를 제공하는 URL입니다. 용량은 40MB를 권장하며, 최대 100MB까지 지원합니다.",
animation_url : "NFT 영상을 제공하는 URL 입니다. 용량은 40MB를 권장하며, 최대 100MB까지 지원합니다.",
youtube_url : "Youtube 영상의 URL 로, 현재는 지원하지 않습니다."
attributes: [ // NFT의 특징을 나타냅니다.
{
category : "NFT 아이템 카테고리를 나타냅니다.",
collection : "NFT Collection을 나타냅니다.",
creator : "NFT 창작자 혹은 저작권자를 나타냅니다.",
provider : "NFT 판매 혹은 배포 권리를 가진 사람을 나타냅니다.",
thumbnail_url : "NFT의 썸네일 이미지를 제공하는 URL 입니다.",
extension_url : "NFT extension 정보를 JSON 형식으로 제공하는 URL 입니다.",
// 아래와 같이 NFT의 특징을 추가할 수도 있습니다.
trait_type: "CharacterName",
value: "Alice",
},
],
},
},
};
더 자세히 알고 싶으시다면 CW721 Github을 살펴보시거나, XPLA Explorer에서 다른 NFT를 참고해보시기 바랍니다. OpenSea Metadata 기준을 읽어보시는 것도 좋습니다.
이후 단계는 이전과 동일합니다. Submit 버튼을 누르고, Password를 입력하면 트랜잭션이 생성됩니다.

XPLA Explorer Messages 탭에서 발행한 NFT에 대한 정보를 자세히 볼 수 있습니다.


이렇게 CW721 컨트랙트로 NFT를 발행해보았습니다. NFT도 토큰이기 때문에, 컨트랙트로 발행하는 것임을 기억해주세요. 단지 토큰마다 고유한 메타데이터가 있기 때문에, 같은 컨트랙트에서 만들어진 다른 토큰들과 대체할 수 없다는 것이 큰 특징입니다.