paint-brush
Flow와 Cadence를 사용하여 디지털 수집품 포털을 구축하는 방법(1부)~에 의해@johnjvester
375 판독값
375 판독값

Flow와 Cadence를 사용하여 디지털 수집품 포털을 구축하는 방법(1부)

~에 의해 John Vester20m2024/02/13
Read on Terminal Reader

너무 오래; 읽다

디지털 수집품 수집에 초점을 맞춘 새로운 웹사이트를 구축하여 Flow 블록체인 및 Cadence 스마트 계약 언어에 대해 자세히 알아보세요.
featured image - Flow와 Cadence를 사용하여 디지털 수집품 포털을 구축하는 방법(1부)
John Vester HackerNoon profile picture

이 튜토리얼에서는 블록체인 Flow에서 디지털 수집품(또는 NFT)을 수집하기 위한 웹사이트를 구축하는 방법을 알아봅니다. 우리는 스마트 계약 언어 Cadence를 React와 함께 사용하여 이 모든 것을 실현할 것입니다. 또한 Flow와 Flow의 장점, 사용할 수 있는 재미있는 도구에 대해서도 알아봅니다.


이 기사가 끝나면 Flow 블록체인에서 자신만의 분산형 애플리케이션을 만드는 데 필요한 도구와 지식을 갖게 될 것입니다.


바로 뛰어 들어 봅시다!


우리는 무엇을 만들고 있나요?

우리는 디지털 수집품을 위한 애플리케이션을 구축하고 있습니다. 각 수집품은 대체 불가능한 토큰(NFT)입니다. (초보이고 NFT를 이해하지 못한다면 여기를 살펴보세요.) 우리 앱을 사용하면 NFT를 수집할 수 있으며 각 항목은 다른 항목과 고유합니다.


이 모든 작업을 수행하기 위해 우리는 이러한 특수 디지털 항목(이더리움의 ERC-721과 유사)을 관리하는 데 도움이 되는 규칙 집합인 Flow의 NonFungibleToken 표준을 사용할 것입니다.

전제조건

시작하기 전에 시스템에 Flow CLI를 설치해야 합니다. 아직 수행하지 않은 경우 다음 설치 지침을 따르십시오.

설정

프로젝트를 시작할 준비가 되었다면 먼저 명령 흐름 설정을 입력하세요.


이 명령은 프로젝트의 기초를 설정하기 위해 뒤에서 몇 가지 마법을 수행합니다. 폴더 시스템을 생성하고 flow.json이라는 파일을 설정하여 프로젝트를 구성함으로써 모든 것이 정리되고 준비가 되었는지 확인합니다!


프로젝트 구조

프로젝트에는 cadence 폴더와 flow.json 파일이 포함됩니다. (flow.json 파일은 프로젝트의 구성 파일이며 자동으로 유지 관리됩니다.)

Cadence 폴더에는 다음이 포함되어 있습니다.

  • /contracts: 모든 Cadence 계약이 포함되어 있습니다.
  • /scripts: 모든 Cadence 스크립트를 보관합니다.
  • /transactions: 모든 Cadence 트랜잭션을 저장합니다.


Flow NFT Standard를 사용하려면 아래 단계를 따르세요.

1단계: 파일을 생성합니다.

먼저 flow-collectibles-portal 폴더로 이동하여 cadence 폴더를 찾으세요. 그런 다음 contracts 폴더를 엽니다. 새 파일을 만들고 이름을 NonFungibleToken.cdc 지정합니다.

2단계: 복사하여 붙여넣습니다.

이제 NFT 표준이 포함된 NonFungibleToken 이라는 링크를 엽니다. 해당 파일의 모든 콘텐츠를 복사하여 방금 만든 새 파일("NonFungibleToken.cdc")에 붙여넣습니다.


그게 다야! 프로젝트의 표준을 성공적으로 설정했습니다.

이제 코드를 작성해 봅시다!


그러나 코딩을 시작하기 전에 개발자가 코드를 구성하는 방법에 대한 정신적 모델을 설정하는 것이 중요합니다.


최상위 수준에서 우리의 코드베이스는 세 가지 주요 구성 요소로 구성됩니다.

  1. NFT: 각 수집품은 NFT로 표시됩니다.


  2. 컬렉션: 컬렉션은 특정 사용자가 소유한 NFT 그룹을 의미합니다.


  3. 전역 함수 및 변수: 이는 스마트 계약의 전역 수준에서 정의된 함수 및 변수이며 특정 리소스와 연결되지 않습니다.

스마트 계약 구조

스마트 계약 기본 구조

cadence/contracts 내에 Collectibles.cdc 라는 새 파일을 만듭니다. 이것이 우리가 코드를 작성할 곳입니다.


계약 구조

 import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ pub var totalSupply: UInt64 // other code will come here init(){ self.totalSupply = 0 } }


코드를 한 줄씩 분석해 보겠습니다.


  1. 먼저, 소위 "NonFungibleToken"을 포함하여 NFT를 구축하고 있음을 표준화해야 합니다. 이는 각 NFT 스마트 계약에 포함되어야 하는 다음 기능 세트를 정의하는 Flow에서 구축한 NFT 표준입니다.


  2. 가져온 후 계약을 작성해 보겠습니다. 이를 위해 pub contract [contract name] 사용합니다. 새 계약을 생성할 때마다 동일한 구문을 사용하십시오. contract name 입력할 수 있습니다. 우리의 경우 이를 Collectibles 라고 부르겠습니다.


  3. 다음으로 우리는 계약이 NonFungibleToken의 특정 기능 및 규칙 세트를 따르는지 확인하려고 합니다. 이를 위해 `:`의 도움으로 NonFungibleToken 인터페이스를 추가합니다.
    이와 같습니다( `pub contract Collectibles: NonFungibleToken{}` )


  4. 모든 단일 계약에는 init() 함수가 있어야 합니다 . 계약이 처음 배포될 때 호출됩니다. 이는 Solidity가 생성자라고 부르는 것과 유사합니다.


  5. 이제 데이터 유형이 UInt64totalSupply 라는 전역 변수를 만들어 보겠습니다. 이 변수는 총 수집품을 추적합니다.


  6. 이제 totalSupply0 으로 초기화합니다.


그게 다야! 우리는 Collectibles 계약의 기반을 마련했습니다. 이제 더 많은 기능을 추가하여 더욱 흥미롭게 만들 수 있습니다.


계속 진행하기 전에 Cadence에서 변수를 정의하는 방법을 이해하려면 코드 조각을 확인하세요.


자원 NFT

스마트 계약에 다음 코드를 추가하세요.


 import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ // above code… pub resource NFT: NonFungibleToken.INFT{ pub let id: UInt64 pub var name: String pub var image: String init(_id:UInt64, _name:String, _image:String){ self.id = _id self.name = _name self.image = _image } } // init()... }


이전에 본 것처럼 계약은 pub contract Collectibles: NonFungibleToken 으로 표시되는 NFT 표준 인터페이스를 구현합니다. 마찬가지로 리소스는 다양한 리소스 인터페이스를 구현할 수도 있습니다.


따라서 NFT 리소스에 NonFungibleToken.INFT 인터페이스를 추가해 리소스 내에 id라는 공용 속성이 있어야 합니다.

NFT 리소스에서 사용할 변수는 다음과 같습니다.


  • id: NFT의 ID를 유지합니다.
  • name: NFT의 이름입니다.
  • image: NFT의 이미지 URL입니다.


변수를 정의한 후 init() 함수에서 변수를 초기화해야 합니다.


앞으로 나아가서 Collection Resource 라는 또 다른 리소스를 만들어 보겠습니다.

수집 자원

먼저 Collection Resources 작동 방식을 이해해야 합니다.


노트북에 음악 파일과 여러 장의 사진을 저장해야 한다면 어떻게 하시겠습니까?


일반적으로 로컬 드라이브(예: D-Drive)로 이동하여 music 폴더와 photos 폴더를 만듭니다. 그런 다음 음악과 사진 파일을 복사하여 대상 폴더에 붙여넣습니다.

마찬가지로 이는 Flow의 디지털 수집품이 작동하는 방식입니다.


노트북을 Flow Blockchain Account 으로, D-Drive를 Account Storage 로, 폴더를 Collection 으로 상상해 보세요.


따라서 NFT를 구매하기 위해 프로젝트와 상호 작용할 때 프로젝트는 D-Drive에 폴더를 생성하는 것과 유사하게 account storagecollection 생성합니다. 10개의 서로 다른 NFT 프로젝트와 상호 작용하면 계정에 10개의 서로 다른 컬렉션이 생성됩니다.


마치 나만의 디지털 보물을 저장하고 정리할 수 있는 개인 공간을 갖는 것과 같습니다!


 import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ //Above code NFT Resource… // Collection Resource pub resource Collection{ } // Below code… }


collection NFT Resources 보유하는 ownedNFTs 변수가 있습니다.


 pub resource Collection { pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } }


리소스 인터페이스

Flow의 resource 인터페이스는 다른 프로그래밍 언어의 인터페이스와 유사합니다. 이는 리소스 위에 위치하며 이를 구현하는 리소스가 인터페이스에 정의된 필수 기능을 가지고 있는지 확인합니다.


또한 전체 리소스에 대한 액세스를 제한하는 데 사용될 수 있으며 리소스 자체보다 액세스 수정자 측면에서 더 제한적일 수 있습니다.


NonFungibleToken 표준에는 INFT , Provider , ReceiverCollectionPublic 과 같은 여러 리소스 인터페이스가 있습니다.


이러한 각 인터페이스에는 이를 사용하는 리소스에서 구현해야 하는 특정 기능과 필드가 있습니다.


이 계약에서는 NonFungibleToken: Provider , ReceiverCollectionPublic 사용합니다. 이러한 인터페이스는 deposit , withdraw , borrowNFTgetIDs 와 같은 기능을 정의합니다. 진행하면서 이들 각각에 대해 자세히 설명하겠습니다.


또한 이러한 함수에서 방출할 일부 이벤트를 추가하고 튜토리얼에서 나중에 사용할 일부 변수를 선언할 것입니다.


 pub contract Collectibles:NonFungibleToken{ // rest of the code… pub event ContractInitialized() pub event Withdraw(id: UInt64, from: Address?) pub event Deposit(id: UInt64, to: Address?) pub let CollectionStoragePath: StoragePath pub let CollectionPublicPath: PublicPath pub resource interface CollectionPublic{ pub fun deposit(token: @NonFungibleToken.NFT) pub fun getIDs(): [UInt64] pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT } pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } } }


철회하다


이제 인터페이스에 필요한 withdraw() 함수를 만들어 보겠습니다.


 pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } init()... }


이 기능을 사용하면 NFT 리소스를 컬렉션 밖으로 이동할 수 있습니다. 그 경우:


  • 실패 : 패닉이 발생하고 오류가 발생합니다.


  • 성공 : 철회 이벤트를 내보내고 호출자에게 리소스를 반환합니다.


그러면 호출자는 이 리소스를 사용하여 계정 저장소에 저장할 수 있습니다.


보증금

이제 NonFungibleToken.Receiver 에 필요한 deposit() 함수를 사용할 차례입니다.


 pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } init()... }


대여 및 GetID


이제 NonFungibleToken.CollectionPublic: borrowNFT()getID() 에 중점을 두겠습니다.


 pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ // other code pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT { if self.ownedNFTs[id] != nil { return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)! } panic("NFT not found in collection.") } pub fun getIDs(): [UInt64]{ return self.ownedNFTs.keys } init()... }


오물 소각로

컬렉션 리소스에 마지막으로 필요한 것은 소멸자입니다.


 destroy (){ destroy self.ownedNFTs }


Collection 리소스에는 다른 리소스(NFT 리소스)가 포함되어 있으므로 소멸자를 지정해야 합니다. 소멸자는 객체가 소멸될 때 실행됩니다. 이렇게 하면 상위 리소스가 파괴될 때 리소스가 "노숙자"로 남지 않게 됩니다. NFT 리소스에는 다른 리소스가 포함되어 있지 않으므로 소멸자가 필요하지 않습니다.


전체 컬렉션 리소스 소스 코드를 살펴보겠습니다.


 import NonFungibleToken from "./NonFungibleToken.cdc" pub contract Collectibles: NonFungibleToken{ pub var totalSupply: UInt64 pub resource NFT: NonFungibleToken.INFT{ pub let id: UInt64 pub var name: String pub var image: String init(_id:UInt64, _name:String, _image:String){ self.id = _id self.name = _name self.image = _image } } pub resource interface CollectionPublic{ pub fun deposit(token: @NonFungibleToken.NFT) pub fun getIDs(): [UInt64] pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT } pub event ContractInitialized() pub event Withdraw(id: UInt64, from: Address?) pub event Deposit(id: UInt64, to: Address?) pub let CollectionStoragePath: StoragePath pub let CollectionPublicPath: PublicPath pub resource Collection: CollectionPublic, NonFungibleToken.Provider, NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic{ pub var ownedNFTs: @{UInt64: NonFungibleToken.NFT} init(){ self.ownedNFTs <- {} } destroy (){ destroy self.ownedNFTs } pub fun withdraw(withdrawID: UInt64): @NonFungibleToken.NFT { let token <- self.ownedNFTs.remove(key: withdrawID) ?? panic("missing NFT") emit Withdraw(id: token.id, from: self.owner?.address) return <- token } pub fun deposit(token: @NonFungibleToken.NFT) { let id = token.id let oldToken <- self.ownedNFTs[id] <-token destroy oldToken emit Deposit(id: id, to: self.owner?.address) } pub fun borrowNFT(id: UInt64): &NonFungibleToken.NFT { if self.ownedNFTs[id] != nil { return (&self.ownedNFTs[id] as &NonFungibleToken.NFT?)! } panic("NFT not found in collection.") } pub fun getIDs(): [UInt64]{ return self.ownedNFTs.keys } } init(){ self.CollectionPublicPath = /public/NFTCollection self.CollectionStoragePath = /storage/NFTCollection self.totalSupply = 0 emit ContractInitialized() } }


이제 모든 리소스를 완료했습니다. 다음으로 전역 함수를 살펴보겠습니다.

글로벌 기능

글로벌 기능은 스마트 계약의 글로벌 수준에서 정의되는 기능입니다. 즉, 리소스의 일부가 아닙니다. 이는 대중이 액세스하고 호출할 수 있으며 스마트 계약의 핵심 기능을 대중에게 공개합니다.


  1. createEmptyCollection : 이 함수는 빈 Collectibles.Collection 호출자 계정 저장소로 초기화합니다.


  2. checkCollection : 이 편리한 기능은 귀하의 계정에 이미 collection 리소스가 있는지 여부를 확인하는 데 도움이 됩니다.


  3. mintNFT : 이 기능은 누구나 NFT를 생성할 수 있게 해주기 때문에 정말 멋지네요.


 // pub resource Collection… pub fun createEmptyCollection(): @Collection{ return <- create Collection() } pub fun checkCollection(_addr: Address): Bool{ return getAccount(_addr) .capabilities.get<&{Collectibles.CollectionPublic}> (Collectibles.CollectionPublicPath)! .check() } pub fun mintNFT(name:String, image:String): @NFT{ Collectibles.totalSupply = Collectibles.totalSupply + 1 let nftId = Collectibles.totalSupply var newNFT <- create NFT(_id:nftId, _name:name, _image:image) return <- newNFT } init()...


스마트 계약 마무리

이제 마침내 모든 것이 준비되었으므로 스마트 계약 작성이 완료되었습니다. 여기에서 최종 코드를 살펴보세요.


이제 사용자가 Flow 블록체인에 배포된 스마트 계약과 어떻게 상호 작용하는지 살펴보겠습니다.


Flow 블록체인과 상호작용하는 두 단계는 다음과 같습니다.


  1. 트랜잭션을 실행하여 상태를 변경합니다.
  2. 스크립트를 실행하여 블록체인을 쿼리합니다.

트랜잭션을 실행하여 상태 변경

트랜잭션은 Flow 상태를 업데이트하기 위해 스마트 계약과 상호 작용하는 일련의 지침을 포함하는 암호화된 서명 데이터입니다. 간단히 말해서 이는 블록체인의 데이터를 변경하는 함수 호출과 같습니다. 거래에는 일반적으로 약간의 비용이 포함되며, 이는 사용 중인 블록체인에 따라 달라질 수 있습니다.


트랜잭션에는 prepare , pre , executepost 단계와 같은 여러 선택적 단계가 포함됩니다.


이에 대한 자세한 내용은 거래에 대한 Cadence 참조 문서에서 확인할 수 있습니다 . 각 단계에는 목적이 있습니다. 가장 중요한 두 단계는 prepareexecute 입니다.


Prepare Phase : 이 단계는 서명자의 계정(AuthAccount 유형에서 허용) 내부의 데이터 및 정보에 액세스하는 데 사용됩니다.


Execute Phase : 이 단계는 작업을 실행하는 데 사용됩니다.


이제 프로젝트에 대한 트랜잭션을 생성해 보겠습니다.


프로젝트 폴더에 트랜잭션을 생성하려면 아래 단계를 따르세요.

1단계: 파일을 생성합니다.

먼저 프로젝트 폴더로 이동하여 cadence 폴더를 엽니다. 그 안에 transaction 폴더를 열고 Create_Collection.cdcmint_nft.cdc 라는 이름으로 새 파일을 만듭니다.

2단계: 수집 거래 생성 코드를 추가합니다.

 import Collectibles from "../contracts/Collectibles.cdc" transaction { prepare(signer: AuthAccount) { if signer.borrow<&Collectibles.Collection>(from: Collectibles.CollectionStoragePath) == nil { let collection <- Collectibles.createEmptyCollection() signer.save(<-collection, to: Collectibles.CollectionStoragePath) let cap = signer.capabilities.storage.issue<&{Collectibles.CollectionPublic}>(Collectibles.CollectionStoragePath) signer.capabilities.publish( cap, at: Collectibles.CollectionPublicPath) } } }


이 코드를 한 줄씩 분석해 보겠습니다.


  1. 이 거래는 수집품 스마트 계약과 상호 작용합니다. 그런 다음 지정된 스토리지 경로 Collectibles.CollectionStoragePath 에서 컬렉션 리소스에 대한 참조를 빌려 보낸 사람(서명자)의 계정에 컬렉션 리소스가 저장되어 있는지 확인합니다. 참조가 nil이면 서명자에게 아직 컬렉션이 없다는 의미입니다.


  2. 서명자에게 컬렉션이 없으면 createEmptyCollection() 함수를 호출하여 빈 컬렉션을 만듭니다.


  3. 빈 컬렉션을 생성한 후 지정된 저장소 경로 Collectibles.CollectionStoragePath 아래 서명자의 계정에 배치합니다.


이렇게 하면 link() 사용하여 서명자의 계정과 새로 생성된 컬렉션 간의 링크가 설정됩니다.

3단계: Mint NFT 거래 코드를 추가하세요.

 import NonFungibleToken from "../contracts/NonFungibleToken.cdc" import Collectibles from "../contracts/Collectibles.cdc" transaction(name:String, image:String){ let receiverCollectionRef: &{NonFungibleToken.CollectionPublic} prepare(signer:AuthAccount){ self.receiverCollectionRef = signer.borrow<&Collectibles.Collection>(from: Collectibles.CollectionStoragePath) ?? panic("could not borrow Collection reference") } execute{ let nft <- Collectibles.mintNFT(name:name, image:image) self.receiverCollectionRef.deposit(token: <-nft) } }


이 코드를 한 줄씩 분석해 보겠습니다.

  1. 먼저 NonFungibleTokenCollectibles contract 가져옵니다.


  2. transaction(name: String, image: String) 이 줄은 새 트랜잭션을 정의합니다. 두 개의 인수(name 및 image)를 사용하며 둘 다 String 유형입니다. 이러한 인수는 발행되는 NFT의 이름과 이미지를 전달하는 데 사용됩니다.


  3. let receiverCollectionRef: &{NonFungibleToken.CollectionPublic} 이 줄은 새로운 변수 receiverCollectionRef. NonFungibleToken.CollectionPublic 유형의 NFT 공개 컬렉션에 대한 참조입니다. 이 참조는 새로 발행된 NFT를 입금할 컬렉션과 상호 작용하는 데 사용됩니다.


  4. prepare(signer: AuthAccount) 이 줄은 트랜잭션 전에 실행되는 준비 블록을 시작합니다. AuthAccount 유형의 인수 서명자를 사용합니다. AuthAccount 거래 서명자의 계정을 나타냅니다.


  5. 준비 블록 내부에 있는 서명자의 저장소에서 Collectibles.Collection 에 대한 참조를 차용합니다. 빌림 함수를 사용하여 컬렉션에 대한 참조에 액세스하고 이를 receiverCollectionRef 변수에 저장합니다.


    참조를 찾을 수 없는 경우(예를 들어 서명자의 저장소에 컬렉션이 없는 경우) "컬렉션 참조를 빌릴 수 없습니다."라는 오류 메시지가 표시됩니다.


  6. execute 블록에는 트랜잭션의 주요 실행 논리가 포함되어 있습니다. 이 블록 내부의 코드는 prepare 블록이 성공적으로 완료된 후에 실행됩니다.


  7. nft <- Collectibles.mintNFT(_name: name, image: image) execute 블록 내에서 이 줄은 제공된 name 및 image 인수를 사용하여 Collectibles 계약에서 mintNFT 함수를 호출합니다. 이 기능은 주어진 이름과 이미지로 새로운 NFT를 생성할 것으로 예상됩니다. <- 기호는 NFT가 이동 가능한 객체(자원)로 수신되고 있음을 나타냅니다.


  8. self.receiverCollectionRef.deposit(token: <-nft) 이 줄은 새로 발행된 NFT를 지정된 컬렉션에 입금합니다. receiverCollectionRef 의 예금 기능을 사용하여 NFT 소유권을 거래 실행 계정에서 컬렉션으로 이전합니다. 여기서 <- 기호는 NFT가 deposit 과정에서 자원으로 이동되고 있음을 나타냅니다.

스크립트를 실행하여 블록체인 쿼리

우리는 스크립트를 사용하여 블록체인의 데이터를 보거나 읽습니다. 스크립트는 무료이며 서명이 필요하지 않습니다.

프로젝트 폴더에 스크립트를 생성하려면 아래 단계를 따르세요.

1단계: 파일을 생성합니다.

먼저 프로젝트 폴더로 이동하여 cadence 폴더를 엽니다. 그 안에 script 폴더를 열고 view_nft.cdc 라는 이름의 새 파일을 만듭니다.

2단계: NFT 스크립트 보기

 import NonFungibleToken from "../contracts/NonFungibleToken.cdc" import Collectibles from "../contracts/Collectibles.cdc" pub fun main(user: Address, id: UInt64): &NonFungibleToken.NFT? { let collectionCap= getAccount(user).capabilities .get<&{Collectibles.CollectionPublic}>(/public/NFTCollection) ?? panic("This public capability does not exist.") let collectionRef = collectionCap.borrow()! return collectionRef.borrowNFT(id: id) }


이 코드를 한 줄씩 분석해 보겠습니다.


  1. 먼저 NonFungibleTokenCollectibles 계약을 가져옵니다.


  2. pub fun main(acctAddress: Address, id: UInt64): &NonFungibleToken.NFT? 이 줄은 main이라는 공용 함수인 스크립트의 진입점을 정의합니다. 이 함수는 두 가지 매개변수를 사용합니다.


  • acctAddress : Flow 블록체인의 계정 주소를 나타내는 Address 유형 매개변수입니다.


  • id : 컬렉션 내 NFT의 고유 식별자를 나타내는 UInt64 유형 매개변수입니다.


  1. 그런 다음 getCapability 사용하여 지정된 acctAddress 에 대한 Collectibles.Collection 기능을 가져옵니다. 기능은 해당 기능과 데이터에 대한 액세스를 허용하는 리소스에 대한 참조입니다. 이 경우 Collectibles.Collection 리소스 유형에 대한 기능을 가져옵니다.


  2. 그런 다음 borrowNFT 함수를 사용하여 collectionRef 에서 NFT를 빌립니다. borrowNFT 함수는 컬렉션 내 NFT의 고유 식별자인 id 매개 변수를 사용합니다. 기능의 borrow 기능을 사용하면 리소스 데이터를 읽을 수 있습니다.


  3. 마지막으로 함수에서 NFT를 반환합니다.

3단계: 테스트넷 배포

이제 스마트 계약을 Flow 테스트넷에 배포할 차례입니다.


1. Flow 계정을 설정하세요.


Flow 계정을 생성하려면 터미널에서 다음 명령을 실행하세요.


 flow keys generate


공개키와 개인키를 꼭 적어두세요.


다음으로 가보겠습니다. 흐름 수도꼭지 , 키를 기반으로 새 주소를 만들고 일부 테스트 토큰으로 계정에 자금을 조달하세요. 계정을 만들려면 다음 단계를 완료하세요.


  1. 지정된 입력 필드에 공개 키를 붙여넣습니다.


  2. 서명 및 해시 알고리즘을 기본값으로 유지합니다.


  3. 보안 문자를 완료하세요.


  4. 계정 만들기를 클릭하세요.


계정을 설정한 후 1,000개의 테스트 Flow 토큰이 포함된 새 Flow 주소에 대한 대화 상자를 받습니다. 앞으로 사용할 수 있도록 주소를 복사하세요 .


2. 프로젝트를 구성합니다.


이제 프로젝트를 구성해 보겠습니다. 처음에 프로젝트를 설정할 때 flow.json 파일이 생성되었습니다.


이는 Flow CLI의 구성 파일이며 Flow CLI가 수행할 수 있는 작업에 대한 구성을 정의합니다. 이것을 Ethereum의 hardhat.config.js 와 대략 동일하다고 생각하십시오.


이제 코드 편집기를 열고 아래 코드를 복사하여 flow.json 파일에 붙여넣으세요.


 { "contracts": { "Collectibles": "./cadence/contracts/Collectibles.cdc", "NonFungibleToken": { "source": "./cadence/contracts/NonFungibleToken.cdc", "aliases": { "testnet": "0x631e88ae7f1d7c20" } } }, "networks": { "testnet": "access.devnet.nodes.onflow.org:9000" }, "accounts": { "testnet-account": { "address": "ENTER YOUR ADDRESS FROM FAUCET HERE", "key": "ENTER YOUR GENERATED PRIVATE KEY HERE" } }, "deployments": { "testnet": { "testnet-account": [ "Collectibles" ] } } }


  1. 복사 및 붙여 넣기.

생성된 개인 키를 코드의 해당 위치(키: "여기에 생성된 개인 키를 입력하세요")에 붙여넣습니다.


  1. 실행하다.

이제 테스트넷에서 코드를 실행해 보세요. 터미널로 이동하여 다음 코드를 실행합니다.


 flow project deploy --network testnet


5. 확인을 기다립니다.


거래를 제출하면 거래 ID를 받게 됩니다. 스마트 계약이 성공적으로 배포되었음을 나타내는 트랜잭션이 테스트넷에서 확인될 때까지 기다립니다.


여기에서 배포된 계약을 확인하세요.


GitHub 에서 전체 코드를 확인하세요.

최종 생각과 축하합니다!

축하해요! 이제 Flow 블록체인에 수집품 포털을 구축하고 이를 테스트넷에 배포했습니다. 무엇 향후 계획? 이제 이 시리즈의 2부에서 다룰 프런트엔드 구축 작업을 수행할 수 있습니다.


정말 좋은 하루 보내세요!


여기에도 게시됨