- Go back to TOP(インデックスページへ)
- Adding an NFT Your Account
- Performing a Basic Transfer
- Enhancing the NFT Experience
このチュートリアルでは、非代替性トークン(NFT)のデプロイ、保存、転送を行います。(補足: ここのコードは初心者向けにかなりイレギュラーな構成になっているため、参考程度に留めて次のチュートリアルに進んでください。次以降は実際に参考になるコードになっています。)
💡 TIP
このチュートリアルのスターターコードをFlow Playgroundで開きます。
https://play.flow.com/dde1e2a4-aae6-4eda-86fd-f0b0b3f53f7e
チュートリアルでは、このコードとやり取りするためにさまざまな操作を行うよう求められます。
ⓘ ACTION
ユーザーにアクションを要求する指示は、常にこのような吹き出しボックス内に記載されています。ハイライトされたアクションは、コードを実行するために必要なすべてですが、言語の設計を理解するには、残りの部分を読むことも必要です。
NFTはブロックチェーン技術の不可欠な要素です。NFTは、ユニークな資産の所有権を表すデジタル資産です。NFTは分割できないため、NFTの一部を取引することはできません。NFTの例としては、CryptoKitties、Top Shot Moments、とても楽しいコンサートのチケット、または馬などが考えられます。
ほとんどのスマートコントラクト言語のような中央台帳で表現するのではなく、Cadenceでは、各NFTをユーザーがアカウントに保存するリソースオブジェクトとして表現します。
これにより、NFTは型システムによって強制されるリソース所有権のルールから利益を得ることができます。リソースは単一の所有者しか持つことができず、複製することはできず、また、偶発的または悪意のあるプログラミングエラーによって失われることもありません。これらの保護により、所有者はNFTが安全であり、真の価値を持つ資産を表すことができることを確実に知ることができます。
現実世界におけるNFTは、資産の取引を可能にし、資産の所有者が誰であるかを証明します。Flowでは、NFTは相互運用可能であるため、アカウント内のNFTを異なるスマートコントラクトやアプリのコンテキストで使用することができます。Flow上のすべてのNFTは、Flow上のNFTの基本的なプロパティセットを定義するFlow NFT Standardを実装しています。このチュートリアルでは、重要な言語概念を説明するためにNFTの基本的な作成方法を教えますが、簡潔さと学習を目的としてNFT標準(NFT Standard)は使用しません。
NFTチュートリアルを完了した読者は、NFTガイドとNFT標準GitHubリポジトリを参照し、完全な実用NFTがどのように作成されるかを学んでください。
NFTを快適に使いこなせるようになるために、このチュートリアルでは以下のことを学びます。
- 基本的なNFTスマートコントラクトと型定義をデプロイする。
- NFTオブジェクトを作成し、アカウントのストレージに保存する。
- アカウントに複数のNFTを保存するためのNFTコレクションオブジェクトを作成する。
-
NFTMinter
を作成し、それを使用してNFTを発行する。 - 他の人がトークンを送信できるように、コレクションに機能(Capability)を作成する。
- 同じ方法で別のアカウントを設定します。
- NFT を 1 つのアカウントから別のアカウントに転送します。
- スクリプトを使用して、各アカウントのコレクションに保存されている NFT を確認します。
⚠️ WARNING
このチュートリアルでは、実際に動作する非代替性トークンを実装していますが、教育目的で簡略化されているため、実際のプロジェクトで使用すべきものではないことに注意してください。標準インターフェイスと実装例については、Flow Fungible Token Standardを参照してください。
このチュートリアルを進める前に、「Getting Started」、「Hello, World!」、「Resources」、および「Capabilities」の手順に従って、Playgroundツールの使用方法とCadenceの基本を習得することを強くお勧めします。このチュートリアルでは、それらのチュートリアルで紹介された概念を基に構築していきます。
(中略)
Adding an NFT Your Account
まずは、アカウントにNFTを追加する基本的なNFTスマートコントラクトについて見ていきましょう。このスマートコントラクトでは、以下の処理を行います。
- NFTリソースタイプを使用してスマートコントラクトを作成します。
- NFTリソースにIDフィールド、メタデータフィールド、イニシャライザー(init関数)を宣言します。
- アカウントにNFTを保存するスマートコントラクトの初期化子(init関数)を作成します。
このスマートコントラクトでは、アカウントにNFTを保存するために、アカウントストレージAPIを使用します。
ⓘ ACTION
まず、このリンクからNon-Fungible Tokenのコントラクト、トランザクション、スクリプトが事前に読み込まれたプレイグラウンド(playground)を開いてください。
https://play.flow.com/dde1e2a4-aae6-4eda-86fd-f0b0b3f53f7e
ⓘ ACTION
アカウント0x06
を選択してBasicNFT.cdc
を表示します。BasicNFT.cdc
には次のコードが含まれています。
access(all) contract BasicNFT {
// Declare the NFT resource type
access(all) resource NFT {
// The unique ID that differentiates each NFT
access(all) let id: UInt64
// String mapping to hold metadata
access(all) var metadata: {String: String}
// Initialize both fields in the initializer
init(initID: UInt64) {
self.id = initID
self.metadata = {}
}
}
// Function to create a new NFT
access(all) fun createNFT(id: UInt64): @NFT {
return <-create NFT(initID: id)
}
// Create a single new NFT and save it to account storage
init() {
self.account.storage.save(<-create NFT(initID: 1), to: /storage/BasicNFTPath)
}
}
上記のスマートコントラクトは、NFTとは整数のIDとメタデータ用のフィールドを持つリソース(resource)です。
各NFTリソースは一意のIDを持つ必要があるため、スマートコントラクトが許可しない限り、結合や複製ができません。
この設計のもう一つのユニークな特徴は、各NFTが独自のメタデータを含むことができることです。この例では、単純な文字列(String
)から文字列(String
)へのマッピングを使用していますが、複雑なファイル形式やその他のデータを保存できるよりリッチなバージョンを(あなたが)想像してもいいです。
NFTは他のNFTを所有することもできます!この機能は、後のチュートリアルで説明します。
Initializers
init() {
// ...
スマートコントラクト、リソース、構造体などのすべての複合型には、オブジェクトが最初に作成されたときにのみ実行されるオプションのイニシャライザー(init関数)を指定することができます。Cadenceでは、複合型のすべてのフィールドは明示的に初期化する必要があるため、オブジェクトにフィールドがある場合は、それらを初期化するためにこの関数を使用する必要があります。
また、スマートコントラクトは組み込みのself.accountフィールドを使用して、デプロイ先のアカウントのストレージに対して読み取りおよび書き込みアクセス権限も有しています。これは、アカウント参照(&Account
)であり、アカウントのストレージ、機能(Capability)、キー、およびスマートコントラクトなど、アカウントのあらゆる側面へのアクセスと管理が許可されています。
スマートコントラクトのイニシャライザー(init関数)では、新しいNFTオブジェクトを作成し、それをアカウントストレージに移動します。
// put it in storage
self.account.storage.save(<-create NFT(initID: 1), to: /storage/BasicNFTPath)
ここでは、スマートコントラクトがデプロイされたアカウントのストレージオブジェクトにアクセスし、そのsave
メソッドを呼び出します。また、同じ行でNFTを作成し、save
メソッドの最初の引数として渡します。これはオブジェクトが保存される/storage/
ドメインに保存します。
ⓘ ACTION
エディタの右上にあるデプロイボタンをクリックして、BasicNFT
をデプロイします。
これで、アカウントにNFTが作成されたはずです。確認のため、トランザクションを実行してみましょう。
ⓘ ACTION
NFT Exists
トランザクションを開き、アカウント0x06
を唯一の署名者として選択し、トランザクションを送信(send)します。
NFT Exists
トランザクションは次のようになります。
import BasicNFT from 0x06
// This transaction checks if an NFT exists in the storage of the given account
// by trying to borrow from it. If the borrow succeeds (returns a non-nil value), the token exists!
transaction {
prepare(acct: auth(BorrowValue) &Account) {
if acct.storage.borrow<&BasicNFT.NFT>(from: /storage/BasicNFTPath) != nil {
log("The token exists!")
} else {
log("No token found!")
}
}
}
ここでは、ストレージ内のNFTから直接、参照を借用(borrow)しようとしています。オブジェクトが存在すれば、borrowは成功し、オプショナルの参照はnil
にはなりません。しかし、borrrowに失敗した場合は、オプションはnil
になります。
"The token exists!
"と表示されるはずです。
素晴らしい!これで、アカウントに初めてのNFTが追加されました。別のアカウントに移動してみましょう!
Performing a Basic Transfer
これらの強力なアセットがアカウントにある場合、おそらく他のアカウントに移動させたいと思うでしょう。Cadenceではオブジェクトを転送する方法はいくつかありますが、まず最も簡単な方法をご紹介します。
また、この機会に、ご自身でコードを書いてみるといいでしょう!
ⓘ ACTION
Basic Transfer
トランザクションを開きます。
Basic Transfer
は次のようになっているはずです。
import BasicNFT from 0x06
/// Basic transaction for two accounts to authorize
/// to transfer an NFT
transaction {
prepare(
signer1: auth(LoadValue) &Account,
signer2: auth(SaveValue) &Account
) {
// Fill in code here to load the NFT from signer1
// and save it into signer2's storage
}
}
私たちは、署名者2人の空のトランザクションを提供しました。
トランザクションが開いている間、トランザクションに署名する1つ以上のアカウントを選択できます。これは、Flowでは複数のアカウントが同じトランザクションに署名でき、プライベートストレージにアクセスできるためです。複数のアカウントが署名者として選択された場合、これは「Basice Transfer」トランザクションで示されているように、複数の署名者が表示されるようにトランザクションの署名に反映させる必要があります。
必要なのは、signer1
のストレージからNFTをload()
し、signer2
のストレージにsave()
することだけです。これらの操作は以前にも使用したことがあるはずなので、理解するのはそれほど難しくないでしょう。これらのアカウント方法の例については、以前のチュートリアルに戻ってご覧ください。(補足: この方法は原始的であるため実際には利用しません。マーケットプレイスのような、より洗練したやり方が他にある為です。また、複数のアカウントをトランザクションの署名者にすることはかなり高度であり、普通のWebアプリのフロントエンドでは不可能だからです。)
また、少し下にスクロールすると、正しいコードもご覧いただけます。
こちらが、あるアカウントからNFTを読み込み、別のアカウントに保存するための正しいコードです。
import BasicNFT from 0x06
/// Basic transaction for two accounts to authorize
/// to transfer an NFT
transaction {
prepare(
signer1: auth(LoadValue) &Account,
signer2: auth(SaveValue) &Account
) {
// Load the NFT from signer1's account
let nft <- signer1.storage.load<@BasicNFT.NFT>(from: /storage/BasicNFTPath)
?? panic("Could not load NFT from the first signer's storage")
// Save the NFT to signer2's account
signer2.storage.save(<-nft, to: /storage/BasicNFTPath)
}
}
ⓘ ACTION
署名者として、Account0x06
とAccount0x07
の両方を選択します。Account0x06
が最初の署名者であることを確認します。
「Send」ボタンをクリックしてトランザクションを送信します。
これで、NFTはアカウント0x07
のストレージに保存されるはずです。0x07
を署名者として「NFT Exists」トランザクションを再度実行し、アカウント内に存在していることを確認してください。
Enhancing the NFT Experience
ここまでで、NFTがCadenceのリソースでどのように表現できるかについて、おおよその見当はついたことでしょう。ここで、もし各NFTに異なるパスを記憶させ、マルチシグネチャのトランザクションを転送に使用することをユーザーに要求していたら、開発者およびユーザーにとって非常に使いにくいものになっていたことに、お気づきかもしれません。
そこでCadenceの真価が発揮されます。次のチュートリアルに進み、他のリソースを所有する機能(Capability)やリソース(Resource)を利用して、NFTの使いやすさと安全性を向上させる方法を確認しましょう。
翻訳元->https://cadence-lang.org/docs/tutorial/non-fungible-tokens-1