Previous << 6. Fungible Token Tutorial
Next >> 8. Marketplace
このチュートリアルでは、以前のチュートリアルで学んだ可換トークン(FT)と非可換トークン(NFT)の両方のスマートコントラクトを使用するマーケットプレイスを作成します。このページでは、マーケットプレイス・チュートリアルを完了するために、アカウントをセットアップするための一連のトランザクションを実行する必要があります。次のページには、チュートリアルの主な内容が記載されています。
チュートリアルを終えたら、NFTStorefrontリポジトリをチェックして、テストネットまたはメインネットですぐに利用できる、本番稼働可能なマーケットプレイスの例を確認してください。
ⓘ Action
このチュートリアルのスターターコードをFlow Playgroundで開きます:
https://play.flow.com/7355d51c-066b-46be-adab-a3da6c28b645
このチュートリアルでは、このコードと対話するためにさまざまな操作を行うよう求められます。
Marketplace チュートリアルをすでに完了している場合は、Composable Resources: Kitty Hats に進んでください。
このガイドでは、Marketplace チュートリアルを完了するために必要な状態にプレイグラウンドを素早く設定する方法を説明します。Marketplace チュートリアルでは、fungible トークンと non-fungible トークンスマートコントラクトを使用して、fungible トークンで NFT を購入および販売できるようにします。
ⓘ Action
これらのセットアップ手順のコードの一部には、意図的にエラーが組み込まれています。Cadenceについて十分に理解し、これらのチュートリアルを自力で修正できる必要があります。すべてのエラーは、以前のチュートリアルで学んだ概念に関連しています
-
ExampleToken
コントラクトを開きます。これはfungible tokenチュートリアルと同じコントラクトです。 -
ExampleToken
コードをアカウント0x06
にデプロイします。 -
ExampleNFT
コントラクト(Contract 2)に切り替えます - NFTコードをデプロイする署名者として選択し、アカウント
0x07
にデプロイします。 - 「Setup 6」でトランザクションを実行します。これは
SetupAccount6Transaction.cdc
ファイルです。アカウント0x06
のストレージをセットアップする唯一の署名者として、アカウント0x06
を使用します。
/* SetupAccount6Transaction.cdc */
import ExampleToken from 0x06
import ExampleNFT from 0x07
/* This transaction sets up account 0x06 for the marketplace tutorial
by publishing a Vault reference and creating an empty NFT Collection. */
transaction {
prepare(acct: auth(SaveValue) &Account) {
/* Create a public Receiver capability to the Vault */
let receiverCap = acct.capabilities.storage.issue<&{ExampleToken.Receiver}>(
/storage/CadenceFungibleTokenTutorialVault
)
acct.capabilities.publish(receiverCap, at: /public/CadenceFungibleTokenTutorialReceiver)
/* store the empty NFT Collection in account storage */
acct.storage.save(<-ExampleNFT.createEmptyCollection(nftType: nil), to: ExampleNFT.CollectionStoragePath)
log("Collection created for account 2")
/* create a public capability for the Collection */
let cap = acct.capabilities.storage.issue<&ExampleNFT.Collection>(ExampleNFT.CollectionStoragePath)
acct.capabilities.publish(cap, at: ExampleNFT.CollectionStoragePath)
}
}
7 . 2つ目のトランザクション「Setup 7」を実行します。これはSetupAccount7Transaction.cdc
ファイルです。アカウント0x07
の唯一の署名者として、アカウント0x07
のストレージを設定します。
/* SetupAccount7Transaction.cdc */
import ExampleToken from 0x06
import ExampleNFT from 0x07
/* This transaction adds an empty Vault to account 0x07
and mints an NFT with id=1 that is deposited into
the NFT collection on account 0x06. */
transaction {
/* Private reference to this account's minter resource */
let minterRef: &ExampleNFT.NFTMinter
prepare(acct: auth(BorrowValue, SaveValue, StorageCapabilities, PublishCapability) &Account) {
/* create a new vault instance */
let vaultA <- ExampleToken.createEmptyVault()
/* Store the vault in the account storage */
acct.storage.save(<-vaultA, to: ExampleToken.VaultStoragePath)
/* Create a public Receiver capability to the Vault */
let receiverCap = acct.capabilities.storage.issue<&ExampleToken.Vault>(
ExampleToken.VaultStoragePath
)
acct.capabilities.publish(receiverCap, at: ExampleToken.VaultPublicPath)
}
execute {
/* Get the recipient's public account object */
let recipient = getAccount(0x06)
/* Get the Collection reference for the receiver
getting the public capability and borrowing a reference from it */
let receiverRef = recipient.capabilities
.borrow<&ExampleNFT.Collection>(ExampleNFT.CollectionPublicPath)
?? panic("Could not borrow a collection reference to 0x06's ExampleNFT.Collection"
.concat(" from the path ")
.concat(ExampleNFT.CollectionPublicPath.toString())
.concat(". Make sure account 0x06 has set up its account ")
.concat("with an ExampleNFT Collection."))
/* Mint an NFT and deposit it into account 0x06's collection */
receiverRef.deposit(token: <-ExampleNFT.mintNFT())
}
}
8 . 「Setup 6」でトランザクションを実行します。これはSetupAccount6TransactionMinting.cdc
ファイルです。アカウント0x06
を唯一の署名者として使用し、アカウント6と7のfungibleトークンを発行します。
/* SetupAccount6TransactionMinting.cdc */
import ExampleToken from 0x06
import ExampleNFT from 0x07
/* This transaction mints tokens for both accounts using
the minter stored on account 0x06. */
transaction {
/* Public Vault Receiver References for both accounts */
let acct6Capability: Capability<&{ExampleToken.Receiver}>
let acct7Capability: Capability<&{ExampleToken.Receiver}>
/* Private minter references for this account to mint tokens */
let minterRef: &ExampleToken.VaultMinter
prepare(acct: auth(SaveValue, StorageCapabilities, BorrowValue) &Account) {
/* Get the public object for account 0x07 */
let account7 = getAccount(0x07)
/* Retrieve public Vault Receiver references for both accounts */
self.acct6Capability = acct.capabilities.get<&{ExampleToken.Receiver}>(/public/CadenceFungibleTokenTutorialReceiver)
self.acct7Capability = account7.capabilities.get<&{ExampleToken.Receiver}>(/public/CadenceFungibleTokenTutorialReceiver)
/* Get the stored Minter reference for account 0x06 */
self.minterRef = acct.storage.borrow<&ExampleToken.VaultMinter>(from: /storage/CadenceFungibleTokenTutorialMinter)
?? panic("Could not borrow owner's vault minter reference")
}
execute {
/* Mint tokens for both accounts */
self.minterRef.mintTokens(amount: 20.0, recipient: self.acct7Capability)
self.minterRef.mintTokens(amount: 10.0, recipient: self.acct6Capability)
}
}
9 . Script1にあるCheckSetupScript.cdc
ファイルを実行して、すべてのセットアップが完了していることを確認します。
/* CheckSetupScript.cdc */
import ExampleToken from 0x06
import ExampleNFT from 0x07
/** Allows the script to return the ownership info
of all the accounts */
access(all) struct OwnerInfo {
access(all) let acct6Balance: UFix64
access(all) let acct7Balance: UFix64
access(all) let acct6IDs: [UInt64]
access(all) let acct7IDs: [UInt64]
init(balance1: UFix64, balance2: UFix64, acct6IDs: [UInt64], acct7IDs: [UInt64]) {
self.acct6Balance = balance1
self.acct7Balance = balance2
self.acct6IDs = acct6IDs
self.acct7IDs = acct7IDs
}
}
/* This script checks that the accounts are set up correctly for the marketplace tutorial.
Account 0x06: Vault Balance = 40, NFT.id = 1
Account 0x07: Vault Balance = 20, No NFTs */
access(all) fun main(): OwnerInfo {
/* Get the accounts' public account objects */
let acct6 = getAccount(0x06)
let acct7 = getAccount(0x07)
/* Get references to the account's receivers
by getting their public capability
and borrowing a reference from the capability */
let acct6ReceiverRef = acct6.capabilities.get<&{ExampleToken.Balance}>
(/public/CadenceFungibleTokenTutorialReceiver)
.borrow()
?? panic("Could not borrow a balance reference to "
.concat("0x06's ExampleToken.Vault")
.concat(". Make sure 0x06 has set up its account ")
.concat("with an ExampleToken Vault and valid capability."))
let acct7ReceiverRef = acct7.capabilities.get<&{ExampleToken.Balance}>
(/public/CadenceFungibleTokenTutorialReceiver)
.borrow()
?? panic("Could not borrow a balance reference to "
.concat("0x07's ExampleToken.Vault")
.concat(". Make sure 0x07 has set up its account ")
.concat("with an ExampleToken Vault and valid capability."))
let returnArray: [UFix64] = []
/* verify that the balances are correct */
if acct6ReceiverRef.balance != 40.0 || acct7ReceiverRef.balance != 20.0 {
panic("Wrong balances!")
}
/* Find the public Receiver capability for their Collections */
let acct6Capability = acct6.capabilities.get<&{ExampleNFT.NFTReceiver}>(ExampleNFT.CollectionPublicPath)
let acct7Capability = acct7.capabilities.get<&{ExampleNFT.NFTReceiver}>(ExampleNFT.CollectionPublicPath)
/* borrow references from the capabilities */
let nft1Ref = acct6Capability.borrow()
?? panic("Could not borrow a collection reference to 0x06's ExampleNFT.Collection"
.concat(" from the path ")
.concat(ExampleNFT.CollectionPublicPath.toString())
.concat(". Make sure account 0x06 has set up its account ")
.concat("with an ExampleNFT Collection."))
let nft2Ref = acct7Capability.borrow()
?? panic("Could not borrow a collection reference to 0x07's ExampleNFT.Collection"
.concat(" from the path ")
.concat(ExampleNFT.CollectionPublicPath.toString())
.concat(". Make sure account 0x07 has set up its account ")
.concat("with an ExampleNFT Collection."))
/* verify that the collections are correct */
if nft1Ref.getIDs()[0] != 1 || nft2Ref.getIDs().length != 0 {
panic("Wrong Collections!")
}
/* Return the struct that shows the account ownership info */
return OwnerInfo(balance1: acct6ReceiverRef.balance,
balance2: acct7ReceiverRef.balance,
acct6IDs: nft1Ref.getIDs(),
acct7IDs: nft2Ref.getIDs())
}
10 . Scriptがpanicを起こすことはなく、次のような出力が表示されるはずです。
"Account 6 Balance"
40.00000000
"Account 7 Balance"
20.00000000
"Account 6 NFTs"
[1]
"Account 7 NFTs"
[]
これでプレイグラウンドが正しい状態になりましたので、次のチュートリアルに進むことができます。
マーケットプレイスのチュートリアルでは、新しいプレイグラウンドセッションを開く必要はありません。このまま続けてください。
翻訳元
Previous << 6. Fungible Token Tutorial
Flow BlockchainのCadence version1.0ドキュメント (7. Marketplace Setup)