brunch

You can make anything
by writing

C.S.Lewis

by Nak Apr 19. 2021

NFT 만들기, NBA Top Shot를 곁들인

NBA Top Shot 따라하기 튜토리얼 - 1

최근 NFT 열풍이 일어남에 따라 국내 블록체인 매체 및 일반 매체에서 NFT로 부자가 된 사람들의 이야기를 마구 떠들어대고 있다. 비단 한국뿐만이 아니라 외국에서도. 그림 파일들을 짜집기한 파일이 몇백억에 팔렸는지에 대해서는 모두들 관심이 많은 듯 하지만 아직까지 NFT 기술이 실제로 어떻게 적용되는지에 대한 글이나 정보는 많지 않은 듯 보인다. 대부분은 NFT로 어떻게 돈을 벌까만 생각하지, 그 기술의 핵심이 무엇인지에 대해 궁금한 사람은 많지 않아 보인다. 


해외에서는 Dapper Labs의 FLOW와 IPFS를 이용해 NFT 기술을 어떻게 활용할지에 대한 논의가 조금씩 이루어지고 있는 가운데, FLOW와 IPFS를 이용하여 NFT를 어떻게 활용하는지에 대한 글이 있어 이번에 소개하려 한다. 글의 출처는 아래 참조.

https://medium.com/pinata/how-to-create-nfts-like-nba-top-shot-with-flow-and-ipfs-701296944bf

---------------------------------------------------------------------------------------------------------------------------


대체불가 토큰 시장이 그 열기를 더해감에 따라, NFT가 상대적으로 초기였던 시기를 반추해보고 그 당시 CryptoKitties로 인해 노출되었던 문제들을 기억해보고자 한다. Dapper Labs에 의해 만들어진 이 플랫폼은이더리움 블록체인에 기반을 둠과 동시에, 성장 가능성이 높은 기술들을 적용한 첫 사례이기도 하다.


그 이후로 NFT는  Rarible , OpenSeaFoundation, 그리고 Sorare 등장들과 함께 비상하기 시작하였다. 이 플랫폼들에서 이루어지는 결제액은 수백만 달러에 이르고 있다. 초기에는 여러가지 어려움들이 있었지만, 이더리움 블록체인 기반으로 대부분의 일들이 이루어진다. 하지만 Dapper Labs의 팀들은 CryptoKitties 경험을 통해서 새로운 블록체인을 만들기 시작했으며, 그것은 일반적인 목적을 위해서 만들어졌지만 NFT를 사용하기 위한 목적으로도 쓰이기를 원했다. 그러는 와중에 이더리움을 기반으로한 NFT를 사용 와중 발견된 여러가지 문제점들을 푸는 것이 목적이 되었고, 개발자와 수집가들에게 좀 더 편한 환경을 제공하고 싶은 바람도 깃들게 되었다. 그들의 새로운 블록체인 'Flow'는 결국 우리가 모두 알만한 회사들과 협업하는데 성공하였다. 그것은 바로 NBA, UFC 그리고 Dr.Seuss였다.


최근 우리는 IPFS를 기반으로 NFT를 만드는 것에 대한 글을 써왔으며, NFT가 가지는 반응성 문제와 이를 IPFS로 어떻게 해결할지에 대한 이야기를 나누었다. 이제는 Flow를 통해 NFT를 만드는데, IPFS를 곁들인....에 대한 이야기를 할 때가 온 것 같다. 플로우 블록체인의 가장 대표적인 초기 적용 사례는 바로 NBA Top Shot이다. 우리는 NFT를 mint(블록체인 안에 파일을 만들어 public하게 verification할 수 있도록 만드는 것)하는 과정을 따라해볼 것이며 NFT 메타데이터와 IPFS를 활용하여 이를 뒷바침 해볼 것이다.


piñatas(글쓴이 회사로 추정)를 사랑하기 때문에, NBA 하이라이트 비디오 대신, 우리의 NFT는 pinata에서 교환 가능한 비디오에 초점을 둘 것이다.


이 튜토리얼은 세 단계로 나뉘어져있다.


1. Contract 작성 및 토큰 발급

2. 위에서 만든 Contract를 통해 NFT를 볼 수 있는 app 생성

3. NFT를 다른사람과 교환할 수 있는 시장을 만들고 IPFS의 에셋을 기반으로 NFT 교환


그럼 이 튜토리얼을 시작해보도록 하자.


Setting UP


우선 Flow CLI를 인스톨해야 한다.  https://docs.onflow.org/flow-cli/install/ 링크로 가보면 인스톨 가이드가 있다. 복사본은 아래와 다음과 같다.


macOS

brew install flow-cli


Linux

sh -ci “$(curl -fsSL https://storage.googleapis.com/flow-cli/install.sh)"


Windows

iex “& { $(irm ‘https://storage.googleapis.com/flow-cli/install.ps1') }”


이제 우리가 해야할 일은 IPFS에 에셋 파일들을 저장해 놓는 것이다. 이걸 좀 더 쉽게 하기 위해서 pinata(https://pinata.cloud/ )를 사용할 것이다. 무료로 가입하여 API Key(https://pinata.cloud/keys)를 얻을 수 있다. 여기서 얻는 API는 두번째 튜토리얼에서 사용할 것이다. 하지만 Pinata 웹사이트는 이 튜토리얼에서도 사용할 예정이니 가입 해놓도록 하자.


또한 NodeJS 인스톨이 되어있어야 하며, 텍스트 에디터를 통해 Flow의 smart contract code(Cadence(https://docs.onflow.org/cadence)라는 언어를 사용한) 문법 강조 기능 도움을 받을 수 있을 것이다. 노드는 설치할 수 있고, Visual Studio Code는 https://docs.onflow.org/vscode-extension를 통해 extension 설치가 가능하다.


이 프로젝트를 넣을 공간인 디렉토리를 만들어 보도록 하자.


mkdir pinata-party


그 디렉토리로 들어간 후 새로운 flow 프로젝트를 초기화 하도록 하자:


cd pinata-party

flow project init


이제 자신이 애용하는 코드 에디터를 통해 프로젝트 오픈을 한 후 (다시한번 말하지만, 만약 Visual Studio Code를 사용한다면, Cadence extension를 설치하도록 하자), 실행하도록 해보자.


우리가 곧 사용할 flow.json 파일을 볼 수 있을 것이다. 우선 cadence라는 폴더를 만들어 보도록 하자. 그 폴더 안에 contracts라는 폴더를 만들어 보도록 하자. 그리고 최종적으로 contracts 폴더 안에 PinataPartyContract.cdc 파일을 만들도록 하자.


진행 전 알아두어야 할 점은 바로 지금 이 시점부터 Flow 블록체인에 관계된 모든 것은 에뮬레이터를 통해서 진행이 된다는 사실이다. 하지만 testnet이나 mainnet에 프로젝트를 배치하는 것은 flow.json 파일에 설정 세팅을 업데이트 하는 것만큼이나 간단하다. 그럼 에뮬레이터 환경을 위해서 파일 설정을 해보고 우리의 contract를 쓰기 시작해보도록 하자.


flow.json 안에 있는 contracts 오브젝트를 업데이트 하면 다음과 같다:


"contracts": {

     "PinataPartyContract": "./cadence/contracts/PinataPartyContract.cdc"

}


그 후 deployments 오브젝트를 아래와 같이 업데이트 하도록 해보자:


"deployments": {

     "emulator": {

          "emulator-account": ["PinataPartyContract"]

     }

}


위의 설정 업데이트는 Flow CLI에게 명령하여 "에뮬레이터를 통해 contract를 배치해" 라고 하는 것과 같다. 또한 에뮬레이터상 계정과 우리가 곧 만들 contract를 참조하기도 한다.


그럼 Contract를 만들어보도록 하자.


The Contract


Flow는 NFT contracts를 만드는데 뛰어난 튜토리얼을 제공하고 있다. 이것은 좋은 참고가 되기는 하지만, Flow가 스스로 지적하듯이, 그들은 아직 NFT 메타데이터에 대한 문제를 해결하지 못하였다.(https://github.com/onflow/flow-nft/issues/9) 그들은 메타데이터를 체인 속에 저장하고 싶어한다. 그것은 굉장히 좋은 아이디어이며, 논리적인 접근을 통해 해결책을 내놓을 것이라고 믿는다.

하지만 우리는 지금 당장 메타데이터를 활용해 토큰을 발급(Mint)하고 싶으며 NFT와 연관된 미디어 파일을 원한다. 메타데이터는 하나의 컴포넌트일 뿐이다. 우리가 하고자 싶어 하는 것은, 토큰이 묶여질 미디어에 중점을 두는 것이다.


만약 당신이 NFT의 이더리움 블록체인에 익숙하다면, 당신은 아마도 토큰들을 뒷받침해주는 수많은 assets들이 전통적인 데이터 저장소와 클라우드 호스팅 사이트에 저장되어 있다는 사실을 알 것이다. 이러한 형태는 그 형태가 작동하지 않을 때를 제외하고는 수긍할만 하다. 우리는 이전에 contents-addressable content의 천재성과 전통적인 클라우드 플랫폼에 블록체인 인접 데이터를 저장하는 방법의 취약점에 대해서 이야기 해본 적이 있다. 결국 이것은 두 가지 결론으로 귀결되게 된다:


1. Assets은 반드시 확인 가능해야 한다.

2. 책임성 유지의 교환이 간단해야 한다


IPFS(https://ipfs.io/)는 이 두 가지 포인트를 잡아준다. Pinata는 쉬운 방법을 통해 IPFS에 장기적인 컨텐츠를 고정시켜 준다. 이것이 바로 NFT를 돌봐주는 미디어에게 우리가 원했던 것이다. 우리가 확실하게 하고 싶은 것은 바로 NFT의 주인이 누구인지를 확인시켜주는 것과, NFT에 대한 데이터를 제공해주는 것과 그 안에 깔려있는 asset에 대한 통제권을 지니는 것이다(IPFS) - 미디어 혹은 다른 것이 되었든 - 적어도 복제품은 아닌 것에 대해서 말이다.


위에서 설명한 내용들을 기억하고, NFT를 발급(mint)하는 contract를 작성해보도록 하자. 그리고 NFT에 메타데이터를 연결시키고, IPFS에 저장된 asset에 메타데이터를 연결시켜보도록 하자.


그럼 우선 PinataPartyContract.cdc를 열고 약간의 수정을 가해보도록 하자


https://gist.github.com/polluterofminds/b3f59cba354c88d8d3c5cc5c95682d78


우선 우리의 contract를 정의해 보자. 우리는 이 cdc 파일에 훨씬 많은 것을 이후 집어 넣을 것이긴 하지만, PinataPartyContract를 정의한 후 진행할 것이다. 우선 이것을 정의한 후 그 안에 resource를 생성할 것이다. 이 리소스는 아이템 형태로 유저의 계정에 저장된다. 또한 접근 통제 방안들을 통해 접근 가능하기도 하다. 이 사례의 경우 NFT 리소스는 궁극적으로 소유된 NFT들을 나타내는데 사용된다고 볼 수 있다. NFT는 특별한 방식으로 구분이 가능하여야 한다. id의 경우 우리의 토큰을 확인하는 역할을 해준다.


다음으로 resource interface를 생성해야 하는데, 이것은 다른 이들에게 어떠한 것들이 가능한지 밝히는데 사용되는 것이다.(예를 들면 contract 소유자가 아닌 사람들)

https://gist.github.com/polluterofminds/7f30c66cd90fc976d428086393cd1490

위의 코드를 NFT resource 바로 밑에 넣도록 해보자. 이 NFTReceiver resource interface는 우리가 이 리소스에 접근 권한이 있다고 정의한 모든 이들에게 아래에 있는 메쏘드에 대한 호출을 가능케 해준다.


deposit


getIDs


idExists


getMetadata


다음으로 우리의 토큰 컬렉션 인터페이스를 정의해야한다. 이것을 사용자의 NFT를 가지고 있는 월렛이라고 생각해보자.

https://gist.github.com/polluterofminds/0cc4e3b18c18a9095783561dd0099043#file-pinatapartycontract-cdc


이 리소스에서 많은 것들이 진행되고 있는데, 곧 이해가 될 것이다. 첫번째로, ownedNFTs라는 변수를 살펴보자. 이 변수는 하는 일은 명확하다. 바로 사용자가 contract에 가지고 있는 모든 NFT를 추적하는 것이다.


그 다음으로 metadataObjs라는 변수를 살펴볼 수가 있다. 이건 조금 특별하기는 한데, 각각의 NFT에 맞는 메타데이터에 대한 매핑들을 저장하여, contract 기능성을 Flow로 확장시켜 주기 때문이다. 이 변수는 토큰 id를 그와 연결된 메타데이터로 연결지어주며, 이 변수를 설정하기 전 토큰 id가 필요하다.


마지막으로 이곳에 NFT 컬렉션 리소스에 대한 모든 기능들이 마련되어있다. 이 모든 기능들이 실제로 모두 사용될 수는 없다는 점을 기억하자. 기억할지 모르겠지만 NFTReceiver resource interface에서는 누구에게나 접근 가능한 기능들을 정의해 두었다.


한 가지 주목하고 싶은 기능 중 하나는 바로 deposit 기능이다. 우리가 기본 FLOW NFT contract를 metadataObjs 매핑 추가를 위해 확장하였듯이, 기본 depoist 기능을 확장하여 metadata 파라미터를 추가로 끌고올 것이다. 이것을 하는 이유는, 토큰을 발급한 사람만 그 토큰에 메타데이터를 추가할 수 있도록 하기 위함이다. 이것을 프라이빗하게 하기 위해 메타데이터의 초기 확장분에 대해서만 발급 실행을 제한할 것이다.


우리의 contract 코드가 거의 다 완성되었다. Collection 리소스 바로 아래 다음과 같은 사항을 추가하도록 해보자.

https://gist.github.com/polluterofminds/88086c739e39794305512dfb3d034045


우선 호출되었을 때, 빈 NFT 컬렉션을 생성하는 기능을 볼 수 있을 것이다. 우리의 contract와 처음으로 연결되는 기능이며, 사용자가 Collection 리소스와 매핑되는 저장소를 가지는 방법 중 하나이다.


그리고 만들어야 할 리소스가 하나 더 있다. 이건 매우 중요한 리소스로, 이것이 없으면 토큰을 발급(mint) 할 수 없다. NFTMinter 리소스는 idCount를 가지며 NFT에 중복되는 id가 없도록 스스로 증가한다.


NFTMinter 리소스 바로 아래, 메인 contract를 초기화 할 수 있도록 코드를 넣어보자.


https://gist.github.com/polluterofminds/8b19cbeb1523fefac83f3461944f1636


생성자 기능은 contract가 배치되었을 때만 호출이 된다. 이것이 하는 일은 아래 3가지이다:


1. 컬렉션 배치자를 위한 빈 컬랙션을 생성하여 contract의 소유자가 NFT를 contract로부터 소유하고 발급할 수 있도록 해준다.


2. Collection 리소스를 퍼블릭한 장소에 NFTReceiver 인터페이스 참조값과 함께 초기에 배치한다. 이를 통해 contract에게 NFTReceiver에 정의된 기능이 누구에게나 호출될 수 있음을 인지시킨다.


3. NFTMinter 리소스는 contract 생성인을 위한 저장소에 저장된다. 결국 contract를 생성하는 사람만 토큰을 발급할 수 있다는 뜻이다.


코드를 전부 합해 놓은 것은 이 링크에서 확인 가능하다.(https://gist.github.com/polluterofminds/17e961796b795a4c001c2e644bda6a41)


이제 한개의 contract가 준비되었으니, 배포할 시간이다. 물론 우리는 이것을 Flow Playground(https://play.onflow.org/)에서 테스트 해볼 수 있다. 이곳에 가서 클릭한 후 사이드바에 있는 첫번째 계정을 클릭해 보도록 하자. 샘플 contract 안에 있는 코드들을 우리의 contract 코드로 바꾼후 클릭후 Deploy를 눌러보아라. 만약 문제가 없다면, 아래와 같은 로그 기록을 볼 수 있을 것이다.


16:48:55 Deployment Deployed Contract To: 0x01


우리는 이제 내부적으로 돌아가는 에뮬레이터에 자신만의 contract를 배포할 준비가 끝났다. 이 커맨드 라인을 실행시켜 보자.


flow project start-emulator


에뮬레이터가 돌아가는 상태에서, flow.json 파일이 제대로 설정되었다면, contract를 배포할 수 있을 것이다. 아래의 커맨드를 입력하여 보자.


flow project deploy


문제가 없다면, 아래와 같은 결과물을 볼 수 있을 것이다:


Deploying 1 contracts for accounts: emulator-accountPinataPartyContract ->


0xf8d6e0586b0a20c7


Flow 에뮬레이터에서 하나의 contract가 활성화 되었지만, 토큰을 발행해야 한다. 이제 토큰을 발행하여 보자.


Minting The NFT


이곳에서는 발급 프로세스를 좀 더 사용자 친화적으로 하기 위해 앱과 유저 인터페이스를 활용하여 진행해볼 것이다. 발급과 Flow NFT과 함께 메타데이터가 어떻게 작동하는지를 알기 위해서, 우리는 Cadence 스크립트와 커맨드 라인을 사용할 것이다.


새로운 디렉토리를 pinata-party 프로젝트에 만들고, transactions으로 칭해보자. 폴더가 만들어지고 나면 MintPinataParty.cdc라는 파일을 만들어보도록 하자. 


거래 내역을 작성하기 위해서, NFT가 제공하는 메타데이터에 참조값을 걸 파일이 하나 필요하다. 그래서 Pinata를 통해 IPFS에 파일 하나를 업로드 해보도록 하겠다. Pinata(인형과 캔디가 장식으로 둘러싸여 천장에 달려있는 장식품이며, 어린아이들이 눈을 가리고 막대로 때려서 열리게 하는 행사용 데코 용품)이 강타당하는 비디오를 교환가능하도록하는 것에 초점을 맞춘 NFT이기 때문에, 생일에 pinata를 강타하는 어린이의 모습이 담긴 영상을 업로드할 예정이다. 독자의 경우 자신이 업로드 하고 싶은 영상을 자신의 취향에 맞춰 업로드 하면 된다. NFT에 연결될만한 어떤 형태의 asset이든 상관 없지만, 지금 우리가 하는 튜토리얼에서는 비디오 파일을 통해 튜토리얼을 진행할 것이다. 준비가 되면 이곳에 업로드 하도록 하자.(https://pinata.cloud/)


파일을 업로드 하게 되면 IPFS 해쉬값을 제공받을 수 있다.(Content identifier or CID로 불린다) 이 해쉬값을 복사하고, 이것을 발급 프로세스에서 사용하도록 하자.


MintPinataPart.cdc 파일안에 다음의 코드를 집어넣어 보도록 하자.

https://gist.github.com/polluterofminds/35f6b46abe8ad59237e491b280d30665


이렇게 보기에는 꽤나 간단해 보이는데, Flow 팀에서 이런 간단한 프로세스를 만들기 위해서 엄청난 노력을 투자했다는 것을 엿볼 수 있다. 처음 발견할 수 있는 부분은 맨 윗 부분에 있는 import 문구이다. 기억할지는 모르겠지만, contract를 배포할 때 계정을 받았었다. 그 계정이 바로 레퍼런스를 위한 계정이다. 그러니 0xf8d6e0586b0a20c7 를 배포할 때 받았던 account address로 교체하여 보자.


다음으로 해야할 일은 transaction을 정의하는 것이다. 여기서 발생하는 모든 것은 우리가 계획해서 실행할 transaction과 연관되어 있다. 


이 transaction에서 첫번재로 해야할 일은 바로 두개의 참조 변수들,receiverRefminterRef를 정의하는 것이다. 현재로서 우리는 NFT의 receiver(수신자)이자 동시에 minter(발급자)이다. 이 두개의 변수들은 우리가 contract에서 만들었던 리소스들을 참조한다. 만약 이 transaction을 실행하는 사람이 리소스에 대한 접근 권한을 지니지 않으면, transaction은 작동되지 않는다.


다음으로는 prepare 기능에 대해서 보도록 하자. 이 기능은 transaction을 실행하는 사람의 계정 정보를 끌어와서 확인 작업 실행한다. 우리가 정의한 NFTMinterNFTReceiver 두 개의 리소스에서 실행 가능한 부분들을 빌려오는 것을 시도할 것이다. 만약 transaction을 실행하는 사람이 이 리소스들에 대한 권한을 지니고 있지 않다면 정상적으로 작동하지 않을 것이다.


마지막으로 execute 기능이 남아있다. 이 기능은 NFT에 대한 메타데이터를 빌드업하고, NFT를 발급하며, 이 메타데이터를 우리의 계정에 디파짓하기 전에 결합시키는 역할을 한다. 눈치챘는지는 모르겠지만, metadata 변수를 확인할 수 있을 것이다. 그 변수 안에 우리의 토큰과 관련된 정보를 조금 넣어놨다. 우리의 토큰이 pinata가 파티에서 가격되는 사건을 나타내기 때문에, 그리고 NBA TOP SHOT에서 본 것을 우리가 따라할 예정이기 때문에, 메타데이터 안에 몇 가지 자료를 넣어놓았다. 어린 아이가 pinata를 배트로 가격하는 속도, 그 스윙의 앵글, 그리고 그에 대한 평가점수이다. 단순히 재미를 위해 이런 자료를 넣어 놓은 것이다. 이 글을 읽는 독자의 경우 자신이 발급할 토큰에 어울릴법한 정보를 넣으면 그만이다.


또한 uri라는 프로퍼티를 정의한 것을 메타데이터 안에 넣어 놓았다는 사실을 눈치채었는지 모르겠다. 이 uri는 IPFS 해쉬값와 이어질 것이며 이 해쉬는 에셋 파일을 제공해 NFT와 연결해준다고 생각하면 된다. 이러한 경우 피나타가 가격당하는 실제 비디오라고 생각하면 된다. 당신은 코드에 적혀있는 uri값을 당신이 위에서 업로드한 파일의 해쉬값으로 교체하면 된다.


이 해쉬 앞에는 ipfs://값을 넣어 앞 글자를 고정해 놓았다. 그 이유는 몇 가지가 있는데 그 중 첫번째는 바로 IPFS 상에서 파일에 대한 정확한 참조 경로 값이기 때문이며, 두번째는 바로 이것이 IPFS 데스크탑 클라이언트와 브라우저 익스텐션에서 사용될 수 있기 때문이다. 우리는 이 값을 Brave 브라우저에 다이렉트로 붙여넣을 것이다. 왜냐하면 그들이 IPFS 컨텐트에 대한 서포트를 지원해주기 때문이다.(https://brave.com/ipfs-support/)


이제 mintNFT 기능을 호출하여 토큰을 생성하여 보자. 그 이후에는 deposit 기능을 호출하여 우리의 계정에 놓아야 한다. 여기서 바로 메타데이터를 전송해야 한다. 기억할지 모르겠지만, deposit 기능에서 변수 결합을 정의하였으며 이를 통해 연관된 토큰 id에 메타데이터를 추가하였다.


드디어 토큰 발급과 디파짓에서 간단하게 빠져나오도록 하자.


transaction 송신과 NFT 발급을 코 앞에 두고 있다. 하지만 그 전에 우리는 계정을 준비해야 한다. 프로젝트의 루트 폴더안에서 커맨드 라인에 들어가 사인을 위한 private key를 생성하여 보자.


아래의 커맨드를 실행시켜 보자.


flow keys generate


위 커맨드를 실행시킴으로써 public key 와 private key를 만들 수 있다. **항상 PRIVATE KEY를 잘 간수하도록 하자**


transaction에 등록하기 위해서 private key가 필요하다. 그렇기 때문에  private key를 flow.json 파일에 붙여 넣을 것이다. 여기서 사인 알고리즘을 조금 더 구체화할 필요가 있는데, flow.json 파일의 accounts 오브젝트를 수정하면 아래와 같다.


"accounts": {

  "emulator-account": {

     "address": "YOUR ACCOUNT ADDRESS",

     "privateKey": "YOUR PRIVATE KEY",

     "chain": "flow-emulator",

     "sigAlgorithm": "ECDSA_P256",

     "hashAlgorithm": "SHA3_256"

  }

},


혹시 이 프로젝트를 github에 저장하거나, 다른 git 저장소에 저장할 경우 private key는 다른 사람들에게 노출되지 않도록 해라. 너의 flow.json 전체 파일에 대한 .gitignore를 실행할 수도 있을 것이다. 내부 에뮬레이터를 통해서 실행하고는 있지만, private key를 보호하는 것은 꼭 갖춰야 할 습관이다.


이제 업데이트 하였으니, transaction을 보내보자. 다음의 코드를 실행하면 간단하게 할 수 있다.


flow transactions send --code ./transactions/MintPinataParty.cdc --signer emulator-account


여기서 참조하는 값은 업데이트한 transaction 파일이며, flow.json 파일에 있는 계정 값을 참고한다. 만약 문제가 없다면, 아래와 같은 결과값을 얻을 수 있을 것이다.


Getting information for account with address 0xf8d6e0586b0a20c7 ...Submitting transaction with ID 4a79102747a450f65b6aab06a77161af196c3f7151b2400b3b3d09ade3b69823 ...Successfully submitted transaction with ID 4a79102747a450f65b6aab06a77161af196c3f7151b2400b3b3d09ade3b69823


이제 마지막으로 해야할 것은 토큰이 계정에 속하는 것인지를 확인하고, 메타데이터를 불러오도록 해보자. 이걸 위해서는 매우 간단한 커맨드 라인이 필요하다.


프로젝트 루트 폴더에 들어가서 새로운 폴더를 만들고 이름을 scripts라고 지어보자. 그 안에 파일을 하나 만들고 CheckTokenMetadata.cdc이라고 해보자. 그 파일을 아래의 코드로 채워보자.


https://gist.github.com/polluterofminds/4f8275f5302ffd81a1849a6315fdca24


이 스크립트는 이더리움의 smart contract가 활용하는 읽기 전용 방식과 똑같은 방식이라고 생각하면 된다. 이것들은 무료이며, contract로부터 데이터를 간단하게 리턴한다.


배포된 주소로부터 contract를 임포트하고, main 기능을 정의한다.(이 스크립트를 돌리기 위해서는 필수로 들어가야 하는 이름이다.). 이 기능 안에 3개의 변수를 넣어놓았다.


nftOwner: 이 변수는 NFT를 지니고 있는 계정이다. NFT를 발급한 계정은 contract를 배포한 계정이기도 하다. 그렇기 때문에 우리의 예시에서 이 두 개의 주소는 같은 것이어야 한다. 추후 contract의 디자인 형태에 따라서 달라질 수는 있다.

capability: 배포된 contract의 이용 가능한 기능을 "borrow" 해와야 한다. 기억해야할 것은 이 기능은 접근 통제가 가능하다는 것이다. 그렇기 때문에 만약 그 기능을 빌려오려는 주소값이 이용 가능하지 않다면, 스크립트 자체가 오작동 할 것이다. NFTReceiver 리소스로부터 이 기능들을 빌려온다.

receiverRef: 이 변수는 기능들을 선택한 후 배포된 contract로부터 필요한 기능을 빌려오라고 신호하는 역할을 한다.


이제 이용 가능한 기능들을 호출할 수가 있다. 이 경우 불확실한 주소가 실제로 우리가 발급한 NFT를 수신하는지를 확인한 후 토큰과 관련된 메타데이터를 봐야 한다.


스크립트를 실행하고 결과값을 보도록 하자. 아래의 커맨드 라인을 입력해 보도록 하자.


flow scripts execute ./scripts/CheckTokenMetadata.cdc


아래와 같은 결과값을 볼 수 있을 것이다.


{"name": "The Big Swing", "swing_velocity": "29", "swing_angle": "45", "rating": "5", "uri": "ipfs://QmRZdc3mAMXpv6Akz9Ekp1y4vDSjazTx2dCQRkxVy1yUj6"}


Congratulations! Flow의 smart contract를 성공적으로 생성했고, 토큰도 발급하였다. 또한 토큰에 메타데이터를 결합시켰고, IPFS 디지털 파일과 토큰을 저장하였다. 첫번째 튜토리얼 치고는 나쁘지 않은 결과다.


다음에 우리가 할 일은 바로 리액트로 프론트엔드 어플리케이션을 만든 후 메타데이터를 불러와 NFT를 보이도록 할 것이다.




매거진의 이전글 [번역] 자바로 블록체인 만들기 파트 2 - 트랜잭션
작품 선택
키워드 선택 0 / 3 0
댓글여부
afliean
브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari