NFTマーケットOpenSeaのメタデータ標準
NFTマーケットOpenSeaのメタデータ標準
OpenSeaのメタデータの標準をOpenSeaの説明ページより勉強したいと思います。
ERC721またはERC1155NFTにリッチメタデータを追加する方法
説明概要の最初で重要なことを言ってますが、
アセットメタデータを提供することで、OpenSeaなどのアプリケーションはデジタルアセットの豊富なデータを取得し、アプリ内で簡単に表示できます。特定のスマートコントラクトのデジタルアセットは通常、一意の識別子(ERC721のtoken_idなど)のみで表されるため、メタデータを使用すると、これらのアセットに名前、説明、画像などの追加のプロパティを設定できます。
OpenSea How to add rich metadata to your ERC721 or ERC1155 NFTs
メタデータを提供することでアプリはアプリ内でデジタルアセットデータを取得して表示するとなっております。なので直接画像をアップロードするのではなくてメタデータをアップロードするということが基本ということのようです。なぜ?というのはERC721の構成の内容なのでそちらをご確認ください。ここではOpenSeaのメタデータの標準、機能の仕方を確認していきたいです。
tokenURIの実装
OpenSeaがERC721およびERC1155アセットのオフチェーンメタデータを取得するには、コントラクトがメタデータを見つけることができるURIを返す必要があります。このURIを見つけるには、ERC721ではtokenURIメソッドを使用し、ERC1155ではuriメソッドを使用します。まず、CreatureコントラクトのtokenURIメソッドを詳しく見てみましょう。
/**
* @dev Returns an URI for a given token ID
*/
function tokenURI(uint256 _tokenId) public view returns (string) {
return Strings.strConcat(
baseTokenURI(),
Strings.uint2str(_tokenId)
);
}
ERC721のtokenURI関数またはERC1155コントラクトのuri関数は、https://opensea-creatures-api.herokuapp.com/api/creature/3などのHTTPまたはIPFSURLを返す必要があります。照会されると、このURLは、トークンのメタデータを含むデータのJSONブロブを返す必要があります。ここで、OpenSeaクリーチャーリポジトリでメタデータを提供するための単純なPythonサーバーの例を見ることができます。
メタデータ構造
OpenSeaは、公式のERC721メタデータ標準またはEnjinメタデータの提案に従って構造化されたメタデータをサポートしていると説明されています。ですのでより詳細な内容を元から確認したい場合はそれらの説明ページを見ることが必要でしょう。
さらに、オーディオ、ビデオ、3Dモデルなど、マルチメディア添付ファイルを可能にする他のいくつかのプロパティに加えて、アイテムのインタラクティブな特性をサポートし、OpenSeaマーケットプレイスのすべての並べ替えおよびフィルタリング機能を提供していると記述されています。
OpenSeaクリーチャーの1つのメタデータの例を確認します。
{
"description": "Friendly OpenSea Creature that enjoys long swims in the ocean.",
"external_url": "https://openseacreatures.io/3",
"image": "https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png",
"name": "Dave Starbelly",
"attributes": [ ... ],
}
これらの各プロパティの仕組みは次のとおりと説明されています。
image | これは、アイテムの画像へのURLです。ほぼすべてのタイプの画像(OpenSeaによってPNGにキャッシュされるSVGを含む)にすることができ、IPFSのURLまたはパスにすることができます。 350 x350の画像を使用することをお勧めします。 |
---|---|
image_data | オンザフライで画像を生成する場合は、生のSVG画像データ(推奨されません)。これは、画像パラメータを含めない場合にのみ使用してください。 |
external_url | これは、OpenSeaのアセットの画像の下に表示されるURLであり、ユーザーがOpenSea以外の自分のサイトでアイテムを表示できるようにします。 |
description | 人間が読める形式のアイテムの説明。マークダウンがサポートされています。 |
name | アイテムの名前 |
attributes | これらはアイテムの属性であり、アイテムのOpenSeaページに表示されます。 (下記参照) |
background_color | OpenSeaのアイテムの背景色。 #が前に付いていない6文字の16進数である必要があります。 |
animation_url | アイテムのマルチメディア添付ファイルへのURL。ファイル拡張子GLTF、GLB、WEBM、MP4、M4V、OGV、およびOGGが、音声のみの拡張子MP3、WAV、およびOGAとともにサポートされています。 Animation_urlはHTMLページもサポートしているため、JavaScriptキャンバスやWebGLなどを使用して豊富なエクスペリエンスとインタラクティブなNFTを構築できます。 HTMLページ内のスクリプトと相対パスがサポートされるようになりました。ただし、ブラウザ拡張機能へのアクセスはサポートされていません。 |
youtube_url | YouTubeのURL |
これから見るに画像だけではなくいろいろなものがほかにもポピュラーになりそうな物がありそうですね。
属性(Attributes)
アイテムをもう少し魅力的にするために、各アセットの下に表示されるカスタムの「属性」をメタデータに追加することもできます。たとえば、OpenSeaクリーチャーの1つの属性は次のとおりと説明されています。クリーチャーの一つはリンクから見ることができます、クリーチャーのNFTの一つということですね(テスト環境上)で下記が表示されている部分のフォーカス。
これらの属性を生成するために、次の属性の配列がメタデータに含める必要があるようです。
...
{
"attributes": [
{
"trait_type": "Base",
"value": "Starfish"
},
{
"trait_type": "Eyes",
"value": "Big"
},
{
"trait_type": "Mouth",
"value": "Surprised"
},
{
"trait_type": "Level",
"value": 5
},
{
"trait_type": "Stamina",
"value": 1.4
},
{
"trait_type": "Personality",
"value": "Sad"
},
{
"display_type": "boost_number",
"trait_type": "Aqua Power",
"value": 40
},
{
"display_type": "boost_percentage",
"trait_type": "Stamina Increase",
"value": 10
},
{
"display_type": "number",
"trait_type": "Generation",
"value": 2
}
]
}
ここで、trait_typeはトレイトの名前、valueはトレイトの値、display_typeはどのように表示するかを示すフィールドです。文字列特性の場合、display_typeについて心配する必要はありません、とのこと。
数値特性
数値特性の場合、OpenSeaは現在、number、boost_percentage、boost_number(boost_percentageに似ていますが、パーセント記号は表示されません)の3つの異なるオプションをサポートしています。数値である値を渡し、display_typeを設定しない場合、その特性は[ランキング]セクションに表示されます。
オプションのmax_valueを追加すると、数値特性の可能な値の上限が設定されます。デフォルトでは、OpenSeaが契約のアセットでこれまでに確認した最大値になります。 max_valueを設定する場合は、より高い値を渡さないように注意してください。
日付特性
OpenSeaは、日付display_typeもサポートしています。このタイプの特性は、「ランキング」と「統計」の近くの右側の列に表示されます。値としてUNIXタイムスタンプを渡します、となっていますがこちらを利用したものをはっきりとは見ていない、認識できていない。
{
"display_type": "date",
"trait_type": "birthday",
"value": 1546360800
}
特定のトレイトにtrait_typeを設定したくない場合は、トレイトに値だけを含めることができ、それが汎用プロパティとして設定されます。例えば、
{
"value": "Happy"
}
すると下記のように表示されるようです。
上記にも書いてあるようにEnjinメタデータスタイルもサポートするとのこと。
{
"properties": {
"base": "starfish",
"rich_property": {
"name": "eyes",
"value": "big",
"display_value": "Big",
}
...
}
}
メタデータをチェーンに保存しないことをお勧めします、となってます。
ただしユースケースにとって重要であると判断した場合は、support @ opensea.ioまでご連絡すればよいようです。
属性ガイドライン
属性を考え出すときのいくつかの重要な注意!
OpenSeaが適切に表示できるように、文字列属性を文字列として(引用符を覚えておいてください)、数値プロパティを浮動小数点数または整数として含める必要があります。文字列のプロパティは、人間が読める形式の文字列である必要があります。
メタデータAPIのデプロイ
メタデータAPIは、適切と思われる方法でデプロイできます。IPFS、クラウドストレージ、または独自のサーバーでホストできます。はじめに、PythonとNodeJSの両方でサンプルAPIサーバーを作成されているようです。
メタデータサーバーを構築してHerokuにデプロイするためのチュートリアルをまもなく作成します。それまでの間、このテーマに関するHerokuのリソースを確認してくださいとなってます。
IPFSおよびArweaveURI
OpenSeaは、decentralizedでのNFTメタデータの保存をサポートしているため、中央の関係者がNFTメタデータを変更することはできません。
IPFSを使用してメタデータをホストする場合、URLはipfs:// の形式である必要があります。たとえば、ipfs:// QmTy8w65yBXgyfG2ZBg5TrfB2hPjrDQH3RCQFJGkARStJbです。
IPFSに保存する場合は、データを簡単に保存できるようにPinataをお勧めします。これがChainlinkによるチュートリアルです。
ファイル保存がArweaveの場合は ar://<hash>
. For example, ar://jK9sR4OrYvODj7PD3czIAyNJalub0-vdV_JAg1NqQ-o
.
メタデータの凍結
スマートコントラクトからこのイベントを発行することで、NFTのメタデータが誰によっても変更できない(つまり、「凍結」されている)ことをOpenSeaに示すことができます。
イベントPermanentURI(string _value、uint256 indexed _id);
スマートコントラクト全体を凍結としてマークしたい場合は、お問い合わせください。と。
結論
全体として訳ばかりとなりましたが最初のデータを経由していくことから認識することは大事な一歩となるのではないでしょうか、実際底の部分が私は抜けていました。