Open12
Cadence チュートリアル#3

気づき
・関数の後ろに:で返り値の型を指定してあげるイメージ
・リソースのフィールドに値を持っていたらinit()が必要
pub contract BasicNFT {
pub resource NFT {
pub let id: UInt64
pub var metadata: {String: String}
init(initID: UInt64) {
self.id = initID
self.metadata = {}
}
}
pub fun createNFT(id: UInt64): @NFT {
return <-create NFT(initID: id)
}
init() {
self.account.save<@NFT>(<-create NFT(initID: 1), to: /storage/BasicNFTPath)
}
}

NFTの存在を確認する
気づき
・リソースの存在確認はborrowで確認することができる
・borrowの中の型はリソースなのかな??なんで&なんだろ
import BasicNFT from 0x01
transaction {
prepare(account: AuthAccount){
if account.borrow<&BasicNFT.NFT>(from: /storage/BasicNFTPath) != nil {
log("token exsist")
} else {
log("non token exsist")
}
}
}

拡張型NFTを作成する
渡す側の実行の流れ
①NFTミント準備(NFTMinterリソース生成)
②受け皿の準備(Collectionリソース生成)
③NFTをミントして送り先に送る(トランザクションでNFTリソースの生成関数を叩いてdeposit関数を呼び出す)
渡される側の実行の流れ
①受け皿の準備(Collectionリソースの生成)
②Collectionリソースをストレージに配置
pub contract ExampleNFT {
//NFTのリソース
pub resource NFT { }
//NFTを受け取るためのインターフェイス
pub resource interface NFTReceiver { }
//NFTを受け取るためのコレクション
pub resource Collection: NFTReceiver { }
//受け取る側の実行するための関数
pub fun createEmptyCollection(): @Collection { }
//NFTをミントするためのリソース
pub resource NFTMinter { }
}

resource NFT
pub resource NFT {
pub let id: UInt64
init(initID:UInt64){
self.id = initID
}
}

resource interface NFTReceiver
pub resource interface NFTReceiver {
pub fun deposit(token:@NFT)
pub fun getIDs():[UInt64]
pub fun idExists(id: UInt64):Bool
}

resource Collection
気づき
・辞書型でもリソースが入る場合は外側に@をつける
・代入時に<-!
のように!
を入れると
pub resource Collection: NFTReceiver {
//リソースオブジェクトが入る型の場合は外側に@をつける
pub var ownerNFTs: @{UInt64: NFT}
init () {
self.ownerNFTs <- {}
}
pub fun withdraw(withdrawID:UInt64): @NFT {
let token <- self.ownerNFTs.remove(key:withdrawID)!
return <- token
}
pub fun deposit(token: @NFT) {
self.ownerNFTs[token.id] <-! token
}
pub fun idExists(id:UInt64):Bool {
return self.ownerNFTs[id] != nil
}
pub fun getIDs():[UInt64] {
return self.ownerNFTs.keys
}
destroy (){
destroy self.ownerNFTs
}
}
ちなみにgetIDs()はどんな感じで返ってくるか確認する。
keysっていう変数の行き先を確認したかった。
transaction
import ExampleNFT from 0x02
transaction {
prepare(account:AuthAccount){
let collectionRef = account.borrow<&ExampleNFT.Collection>(from: /storage/NFTCollection)
?? panic("error")
log(collectionRef.getIDs())
}
execute {
}
}
実行結果
16:15:09 New Transaction >> [2, 1, 3]

resource NFTMinter
pub resource NFTMinter {
pub var idCount: UInt64
init(){
self.idCount = 1
}
pub fun mintNFT():@NFT {
var newNFT <- create NFT(initID:self.idCount)
self.idCount = self.idCount + 1 as UInt64
return <- newNFT
}
}

コード全体
pub contract ExampleNFT {
pub resource NFT {
pub let id: UInt64
init(initID:UInt64){
self.id = initID
}
}
pub resource interface NFTReceiver {
pub fun deposit(token:@NFT)
pub fun getIDs():[UInt64]
pub fun idExists(id: UInt64):Bool
}
pub resource Collection: NFTReceiver {
//リソースオブジェクトが入る型の場合は外側に@をつける
pub var ownerNFTs: @{UInt64: NFT}
init () {
self.ownerNFTs <- {}
}
pub fun withdraw(withdrawID:UInt64): @NFT {
let token <- self.ownerNFTs.remove(key:withdrawID)!
return <- token
}
pub fun deposit(token: @NFT) {
self.ownerNFTs[token.id] <-! token
}
pub fun idExists(id:UInt64):Bool {
return self.ownerNFTs[id] != nil
}
pub fun getIDs():[UInt64] {
return self.ownerNFTs.keys
}
destroy (){
destroy self.ownerNFTs
}
}
pub fun createEmptyCollection(): @Collection {
return <- create Collection()
}
pub resource NFTMinter {
pub var idCount: UInt64
init(){
self.idCount = 1
}
pub fun mintNFT():@NFT {
var newNFT <- create NFT(initID:self.idCount)
self.idCount = self.idCount + 1 as UInt64
return <- newNFT
}
}
init(){
self.account.save(<-self.createEmptyCollection(), to: /storage/NFTCollection)
self.account.link<&{NFTReceiver}>(/public/NFTReceiver, target: /storage/NFTCollection)
self.account.save(<-create NFTMinter(), to: /storage/NFTMinter)
}
}

NFTをミントするTransaction
import ExampleNFT from 0x02
transaction {
let receiverRef: &{ExampleNFT.NFTReceiver}
let minterRef: &ExampleNFT.NFTMinter
prepare(account:AuthAccount){
self.receiverRef = account.getCapability<&{ExampleNFT.NFTReceiver}>(/public/NFTReceiver)
.borrow()
?? panic("error")
self.minterRef = account.borrow<&ExampleNFT.NFTMinter>(from: /storage/NFTMinter)
?? panic("error")
}
execute{
let newNFT <- self.minterRef.mintNFT()
self.receiverRef.deposit(token: <-newNFT)
log("mint!!")
}
}

import ExampleNFT from 0x02
transaction {
prepare(account:AuthAccount){
let collection <- ExampleNFT.createEmptyCollection()
account.save(<-collection, to: /storage/NFTCollection)
log("Good Save")
account.link<&{ExampleNFT.NFTReceiver}>(/public/NFTReceiver, target: /storage/NFTCollection)
log("Good Link")
}
}

transfer code
import ExampleNFT from 0x02
transaction {
let tmpToken: @ExampleNFT.NFT
prepare(account:AuthAccount){
let collectionRef = account.borrow<&ExampleNFT.Collection>(from: /storage/Collection)
?? panic("error")
self.tmpToken <- collectionRef.withdraw(withdrawID:1)
}
execute {
let recipient = getAccount(0x01)
let receiverRef = recipient.getCapability<&{ExampleNFT.NFTReceiver}>(/public/NFTReceiver)
.borrow()
?? panic("error")
receiverRef.deposit(token: <-self.tmpToken)
log("ID")
}
}

基本的には公式が作っているNFTをimportして作るのが一般的
NFT code👇