VR x NFTマーケットプレイス SnowXの技術的説明
SnowX CTOのMichitomoです。先月、VR上で3DのNFTアートを売買するアプリSnowXをSideQuestにリリースしました。SnowXの詳細については公式サイト等をご覧ください。
VRでNFTを売買するアプリ例が少なく、実装方針を探りながらの実装でした。Unity x VR x NFTのSnowXがどういうアーキテクチャで動いているのか、またどのように開発したのを説明します。
SnowXでできること
SnowXはVR上で3DのNFTを購入するためのMeta Quest 2用アプリです。SnowXではVRでNFT化された3Dを、VRヘッドセットの中で購入することができます。
Web: NFTの作成(Mint)
SnowXは1点もののアート作品を中心に取り扱っています。現状、8割前後のアートはTilt BrushとそのオープンソースフォークのOpen Brushで制作されたものです。アーティストはアートをGLB形式で書き出します。
SnowXのMintは専用のWebページで、一般的なERC-721のMintの仕組みと同様
コレクション(=ERC-721のコントラクト)作成
3Dファイルとサムネイルを含むMetadataのアップロード
上記1で作成したコントラクトにTokenを追加
の流れで行います。
Web: NFTの販売
SnowXではマーケットプレイスのスマートコントラクトを用意しており、アーティストはMintと同じページで価格を設定し、販売状態にすることができます。
一般的なNFTマーケットプレイスと同様、ここで販売状態にしたNFTはSnowX上でのみの販売設定となります。他のマーケットプレイスで販売したい場合、アーティストはOpenSea等他のマーケットプレイスで別途価格設定を行った上で販売することができます。
VR: NFTの閲覧
3DアートはNFTとしてのMintが完了次第、SnowXのVRアプリ上で表示されるようになります。閲覧・購入はVRアプリからのみ可能です。
ユーザはVRアプリを起動し、閲覧したいコレクションを選択すると、VR空間内の廊下にアートが並び、展示場の空間内を移動する形で、アートを閲覧することができます。
前述した通り、多くのアートはTilt Brush系のアプリで制作されています。SnowXではTilt Brushのアーティストが作成時に使っているアートの移動・拡大縮小等の操作を再現しており、ユーザはアーティストと同じ感覚でアートが閲覧できるようにしています。
VR: NFTの購入
Meta Quest 2上のVRとスマートフォンのウォレットと接続を行い、SnowXのVRアプリ内からNFTの購入が可能です。
NFTを取り扱うことについてのSnowXの技術的理解
NFTを閲覧するとはどういうことか
NFTは下記のような形でブロックチェーン上に記録されています。
Ethereumチェーン → Metadata(JSON) → 画像等ファイル
したがって、これらをユーザに意味のある形で表示するためには
スマートコントラクトの実行結果
MetadataのJSON
画像等のファイル
を意味のある形に整形し、表示する必要があります。
OpenSeaのような、あらゆる取り扱うWebサイトでNFTを閲覧する場合、以下のような順序で取り扱っていると思われます。
ブロックチェーンを監視し、NFT(ERC-721, ERC-1155)の一覧を作成する
NFTのスマートコントラクトを実行し、トークンごとのMetadataの所在を確認する
Metadataが外部URLとして保存されている場合、取得する
Metadataに記録されているアートの実体が外部URLとして保存されている場合、取得する。
上記の収集結果をチェーン外のデータベース等に保存し、表示ページを生成する。
一方で、そのサイトでMintされたNFTのみを表示するようなマーケットプレイスの場合、以下のような順序でファイルを取り扱っていると考えられます。
アーティストがNFT(ERC-721等)をMintする
Mintと同時に、作成されたNFTに関するデータをチェーン外のデータベース等に保存する
SnowXは将来的にSnowXでMintされたNFT以外も取り扱いやすくするよう、上記のそれぞれを組み合わせたアプローチを採用しています。具体的には、
Mint時
アーティストがNFT(ERC-721等)をMintする
MintされたNFTの一覧をブロックチェーン上に記録する
VRアプリ起動時のバックエンド処理
NFT一覧を取得する
それぞれのNFTについてMetadataを取得する
MetadataとアートのURLを整形し、VRクライアントに渡す
と言ったような処理を行なっています。詳細については、後半で詳述します。
NFTを売買するとはどういうことか
所有者の情報はNFTのスマートコントラクトそのもの(ERC-721など)とTokenそれぞれについて記録されていますが、一般的に、後者のTokenそれぞれがNFTと呼ばれています。
スマートコントラクトのownerOf(tokenId)関数を実行し、返却された値に記録されているアドレスがNFTの所有者として認識されます。従って、ownerOf関数の実行結果のアドレスの変更がNFTの所有権を移転と同義です。ownerOfの実装や、ownerの変更は共にERC-721等のインタフェースに定義されています。
一方で、所有権の移転に伴う代金の取り扱いはERC-721では行われず、別のコントラクトで行われます。ERC-721ではapproveというインタフェースが用意されており、他のスマートコントラクトに所有権の移転権限を委任できます。従って、売買用のスマートコントラクトを用意し、「代金が支払われたら、所有権を移転する」といったプログラムを用意しておく形になります。
SnowXの仕組み
ここからはそれぞれのステップで、SnowXがどのように実装されているかを説明します。
Mint
前述した通り、SnowXではMint用のWebページを用意しています。Mintは以下の順序で行います。
コレクション(=ERC-721のコントラクト)作成
3Dファイルとサムネイルを含むMetadataのアップロード
上記1で作成したコントラクトにTokenを追加
それぞれのステップについてより詳細な説明をします。
コントラクト作成
Mintページでコントラクトを作成する(=SnowXのコントラクト作成コントラクト, SnowXTokenFactory.solを実行する)と、以下の処理が行われます。
SnowXのERC-721コントラクトSnowXToken.solを元に、新しいERC-721コントラクトをデプロイ
SnowXのNFT用URL(https://nfts.snowx.com/[contract-address])をbaseURIに設定
コントラクトにロ イヤリティーのパーセンテージを記録(EIP-2981)
SnowXのコントラクトに、デプロイしたコントラクトのアドレスを作成済みコントラクトとして記録
これにより、SnowXTokenFactoryのgetCollections()などを呼ぶことで、SnowXでMintされたNFTの一覧がチェーン上から取得可能になります。
コレクション用メタデータ作成
NFTのコレクションそのもののカバー画像や、コレクションの作成者の名前や画像等を記録する方法はERC-721等では定義されていないのですが、この種のデータはNFTをブラウジングするUIを作る際にはあった方が良い要素で、OpenSeaなども別途オフチェーンのデータとして記録しているようです。
SnowXでは
コレクションそのもののタイトル
コレクションを作成したアーティスト名
アーティストのアイコン画像
コレクションのカバー画像
をオフチェーンデータとして、https://nfts.snowx.com/[contract-address]/metadataに記録しています。
トークンの追加
コレクションにトークンを追加し、トークン用のmetadataのURIを作成することで、NFTとして成立するようになります。
SnowXTokenのmint()を実行することで、連番のトークンが順次発行されます。当初はERC721Enumerableを採用していたのですが、ガス代が高いため、内部的にMint済みトークンのカウンター変数を持つ方式としています。
MintするとOpenSeaなどのロボット型マーケットプレイスがトークンのメタデータを収集しにくるため、Mintが完了する前にメタデータを用意しておきます。
SnowXのメタデータは下記の要素を記録しています。
dame(アートの名前)
description(アートの説明文)
image(アートのサムネイル画像のURL)
animation_url(3DファイルGLBのURL)
animation_urlを3Dファイルとすることについては賛否あるようですが、現状OpenSeaで表示するためにはこれ以外の方法が思いつかないため、現状のSnowXは上記の実装となっています。
販売
SnowXでのNFTの販売は定額で、以下のフローで販売価格の設定を行います。
SnowXのマーケットプレイスコントラクトに、所有権の譲渡権限を付与 = approve()の実行
SnowXのマーケットプレイスコントラクトに、トークンの販売価格を記録
なお、現時点では二次売買についてはあまり考慮していない設計になっています。
閲覧
VRアプリQuest 2で動作するUnity製のアプリです。以下の2つが特殊性のある点になります。
NFTを表示するため、チェーン上のデータを読み込む必要がある。
NFT購入のため、支払いのトランザクションを作る
前者はReadのリクエスト数が多くなるため、効率化のためVRデバイス上からではなく、サーバサイドでバックエンドのプログラムがチェーンからのリスト生成を行ったうえで、キャッシュする仕組みとしています。
VRアプリでNFTを閲覧する際、以下の流れで表示するNFTの一覧を生成します。
SnowXのコントラクト作成コントラクト(SnowXTokenFactory)からSnowXで作成されたNFTコレクションのアドレスの一覧を取得する getCollections()
それぞれのコレクションについて、Mint済みのアートの数を取得する
Mint済みのあーとそれぞれについて、アートのメタデータのURLを取得する
メタデータそれぞれをダウンロードし、アートの詳細情報を取得する
取得した情報をJSONに整形し、クライアントに渡す
したがって、チェーンに対してはSnowXが生成したコレクション数 + SnowXでMintされているアート数 + 1のReadリクエストが生じる形になります。
現状、生成のバックエンドはAWS Lambdaで実行し、生成したJSONを一定期間DynamoDBに保存しています。また、Ethereum側バックエンドにはInfuraを採用しています。
購入
VR内からNFT購入する仕組みは、VRアプリでは現状まだ他に実装されていない仕組みだと思います。EthereumをはじめとするEVMネットワークでトランザクションを起こすには、ウォレットそのものをアプリ内に実装する(例:STEPN)か、ウォレットと連携する仕組みを実装する必要があります。
ウォレットをSnowXに組み込む方法を採用した場合、NFTを購入しようとするユーザは既存のウォレットの秘密鍵をSnowXに入力するか、SnowX内で新しいウォレットを生成するかのいずれかになります。SnowXは既存のNFTコレクターをメインユーザにしようとしていたため、大切な秘密鍵を新しいアプリに入力させる、またはコレクションを入れるウォレットが別れてしまうようなアプローチは難しいと考えました。
現時点でのSnowXはWalletConnectを採用しています。WalletConnectは、トランザクションを必要とするアプリケーションと、MetaMaskをはじめとする既存のウォレットを連携する仕組みです。具体的なトランザクションは以下のような流れになります。
ユーザはSnowXでNFTの購入を決める
ユーザはSnowXで購入ボタンを押す
SnowXはWalletConnectのセッションIDを発行し、QRコードの表示またはURLをメールで送付する
ユーザはスマホでQRコードをスキャンするか、URLを開く
ユーザのスマホでWalletConnectが起動し、SnowXとの連携を承認する
ユーザはSnowXで再度購入ボタンを押す
ユーザのスマホでWalletConnectが起動し、購入と支払いを承認する
VRアプリでWalletConnectを組み込んでいる例は見たことがないですが、VR専用ではないものの、WalletConnectがUnity用のSDKを提供してくれていることもあり、比較的簡単に実装することができます。
https://github.com/WalletConnect/WalletConnectUnity/
また、実際の購入はSnowX独自のマーケットプレイスコントラクトで実装されています。SnowXのマーケットプレイスコントラクトは、以下のような処理を行います。
購入時に送付された金額と、販売価格との整合性を検証する
EIP-2981に基づく、アーティストのロイヤリティを算出する
販売価格からロイヤリティとマーケットプレイス手数料(現状1%)を引いた金額を販売者に送付する
ロイヤリティをアーティストに送付する
マーケットプレイス手数料は、マーケットプレイスコントラクトに残留する
販売を取り下げる
NFTの所有権を購入者に変更する
実際のコードはSnowXMarketPlace.solをご覧いただければと思います。
まとめ
以上、SnowXの技術的な概要について説明しました。VRネイティブのNFT売買アプリは今のところ、他にはない仕組みです。SnowXのアーキテクチャ選定理由や、実装の概要についての資料が、他の類似アプリ実装の際の参考になれば幸いです。
また、SnowXではVR/ARとNFTに興味のあるUnityエンジニアをはじめ、プロダクト開発メンバーを募集しています。ご興味のある方は、TwitterのDMなどで連絡いただければと思います。
この記事が気に入ったらサポートをしてみませんか?