このチュートリアルでは、以前のチュートリアルで学んだ可換トークン(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"
[]
これでプレイグラウンドが正しい状態になりましたので、次のチュートリアルに進むことができます。
マーケットプレイスのチュートリアルでは、新しいプレイグラウンドセッションを開く必要はありません。このまま続けてください。
翻訳元->https://cadence-lang.org/docs/tutorial/marketplace-setup