こんにちは、フルオンチェーンNFTクリエイターのnawooです。
先日、dom氏(@dhof)が Twitter上で、新作NFTとなる「ROSES」を発表しました。
ROSES
— dom (@dhof) September 13, 2022
procedurally generated in 3d + served fully on-chain
supply 1024 (32 reserved)
NOT CURRENTLY MINTABLE. minting — like rendering — is modular & upgradable. will share details once determined
browse the first 32 https://t.co/cEmisHnJ3d
technical details coming shortly pic.twitter.com/x83melUxAJ
上のGIFアニメーションを確認していただくと『3Dのバラが回転している』ことが分かりますが、なんと驚くべきことにこちらはEthereumでの「フルオンチェーンNFT」となっています!
しかも、トークンごとに「バラの形」「色」が異なる『ジェネラティブアート』になっているのです。
では一体、dom氏はどうやってフルオンチェーンで3Dを実現しているのか。
その謎に迫るべく筆者はこの度、本NFTの元となるコントラクトコードを読んでみました。
ということで本記事では、先日dom氏が作成したフルオンチェーンNFT「ROSES」についてご紹介することで、本プロジェクトの概要ならびにコントラクトの中身、フルオンチェーンNFTの新時代を切り拓く可能性などを理解していただくことを目的とします。
でははじめに、この記事の構成について説明します。
まずは、本記事の題材となっている『ROSES』について、執筆時点で公開されている情報をもとに概要を述べてまいります。
続いて、tokenURI関数ならびに実際のHTMLの内容を確認していくことで、「ROSES」がフルオンチェーンで3Dを実現していることを確認してまいります。
最後に、STEP2で解説した「複雑なHTML」をどうやってコントラクトで作成しているかについて、解説してまいります。
本記事が、「ROSES」の概要や注目ポイント、斬新なフルオンチェーンNFTの作成方法などについて理解したいと思われている方にとって、少しでもお役に立てれば幸いです。
※本記事は一般的な情報提供を目的としたものであり、法的または投資上のアドバイスとして解釈されることを意図したものではなく、また解釈されるべきではありません。ゆえに、特定のFT/NFTの購入を推奨するものではございませんので、あくまで勉強の一環としてご活用ください。
イーサリアムnaviの活動をサポートしたい方は、「定期購読プラン」をご利用ください。
前書き|「ROSES」とは
「ROSES」作成者のdom氏の発表によると、執筆時点においては『技術的な詳細は近日中に公開予定』となっており、現時点でNFTに関する詳細は未公表といった状況です。
それを踏まえて、本記事ではEtherscanで公開されているスマートコントラクトの情報をもとに、本NFTプロジェクトがどのように「3D×フルオンチェーン」を実現しているのかなどについて、私見を含めて解説してまいります。
- Ethereumチェーン上の3Dアニメーション×フルオンチェーンNFT
- NFTの最大発行数は1024個
- 執筆時点ではmint不可能な状態であり、なおかつ詳細も不明
- tokenId=1のNFTは、コントラクトのデプロイ時にdom氏によってあらかじめmintされている
- さらに現在発行されているtokenId=2〜32のNFTは、
reserve
関数からmintされている reserve
関数は、dom氏が自分用に31枚をmintするための関数の模様
次章からは、このROSESがどのようにEthereumチェーン上で、「フルオンチェーン×3D」を実現しているのかについて、確認していきましょう。
「ROSES」がフルオンチェーンNFTであることを確認
続いて本章では、tokenURI関数ならびに実際のHTMLの内容を確認していくことで、本記事の題材となっている『ROSES』がフルオンチェーンで3Dを実現していることを確認してまいります。
tokenURIについて
フルオンチェーンNFTでは、tokenURI
関数でdataURL化したメタデータを返します。
一般的には、メタデータのimage
にdataURL化したSVGファイルを指定することが多いです。
例えば、Mt.Chickenのメタデータは以下のようになっています。
{
"name": "MtChicken #1",
"description": "Mt. Chicken is a NFT ...",
"image": "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0..."
}
name
,description
,image
の3つが設定されていて、image
にはSVGファイルが指定されていることが分かります。
フルオンチェーンNFTなので、dataURL形式で書かれたメタデータ(JSON)が返ってきますが、上写真の通り非常に長い文字列になっていますね。
ちなみにこちらをDLしてみると、なんと271KBもありました!
続いて、dataURL(先ほどの非常に長い文字列)をデコードして整形してみると、メタデータは以下のようになっていました。
{
"animation_url": "data:text/html,%3Cscript%20src%3D%27data%3Atext%2Fjavascript ~ t%3E",
"name": "Rose 1",
}
ご覧の通り、ROSESのメタデータではimage
ではなく、animation_url
が設定されていることがお分かりでしょう。
さらに、dataURLのmediaTypeはtext/html
になっているので、SVGではなくHTMLが書かれていることが分かります。
OpenSeaは、animation_url
でHTMLを指定したNFTにも対応しているので、dataURLでHTMLを返すことによって『SVGではなくHTMLを使ったフルオンチェーンNFT』が実現できるというカラクリです。
そして、単なるHTMLだけでなく、JavaScirptを使ったHTMLにも対応しています。
- three.jsという、3D描画用のJavaScriptライブラリを使っている
- 3Dのバラを作成するJavaScriptコードを作成し、HTMLに埋め込んでいる
- HTMLをdataURL化して、
animation_url
で返している
HTMLの内容について
続いて本節では、実際のHTMLの内容を確認していきます。
下記は、animation_url
をデコードして整形したものですが、5つの<script>
と1つの<style>
が出てきます。
<!-- script 1 -->
などのコメントは、筆者が追加したものです。
<!-- script 1 -->
<script src="data:text/javascript;base64,Y29uc3QgYmFzZT (中略) Cn0="></script>
<!-- script 2 -->
<script src="data:text/javascript;base64,IWZ1bmN0aW9uKG (中略) fSk="></script>
<!-- script 3 -->
<script>
var data = base64ToBytes("H4sIAK/YHGMAA+x9eXfbOLLv/+9 (中略) 3AkA");
var unzipped = fflate.gunzipSync(data);
var text = fflate.strFromU8(unzipped);
var b64 = btoa(text);
var script = document.createElement("script");
script.setAttribute("src", "data:text/javascript;base64," + b64);
document.head.appendChild(script);
</script>
<!-- script 4 -->
<script>
var tokenId = 1;
</script>
<!-- style -->
<style>
* {
margin: 0;
padding: 0;
}
canvas {
width: 100%;
height: 100%;
}
</style>
<!-- script 5 -->
<script>
window.onload = () => {
const o = (o) => (
void 0 !== o && (l = o % 2147483647) <= 0 && (l += 2147483646),
((l = (16807 * l) % 2147483647) - 1) / 2147483646
);
o(tokenId);
const t = 2 * Math.PI,
i = window.innerWidth,
n = window.innerHeight;
// 中略
};
</script>
各パートを簡単に説明すると、次のようになっています。
場所 | 内容 |
---|---|
script 1 | Base64を扱うためのJavaScriptライブラリ「base64.js」を、dataURL化したもの |
script 2 | gzipを扱うためのJavaScriptライブラリ「fflate」を、dataURL化したもの |
script 3 | three.js本体、およびthree.jsを読み込むためのscriptタグを生成するJavaScriptコード |
script 4 | tokenId変数を定義するJavaScriptコード |
style | スタイルシートの設定 |
script 5 | three.jsを使って3Dのバラを作成するJavaScriptコード |
次節では、この複雑なHTMLをどうやってコントラクトで作成しているかについて、一緒に見ていきましょう。
関連するコントラクトについて解説
ROSESのコントラクトは「Roses.sol」ですが、そこから呼び出されるコントラクトが多数あるので、以下の画像ならびにテーブルを用いて整理しておきます。
コントラクト | アドレス | 内容 |
---|---|---|
Roses.sol | 0x3e743377417cd7ca70dcc9bf08fac55664ed3181 | 本体 |
HelloWorldsRenderer.sol | 0x168219161C8F88DE76027173227a569544FF03c1 | tokenURIを作成する |
DataChunkCompiler.sol | 0xeC8EF4c339508224E063e43e30E2dCBe19D9c087 | HTMLのパーツを作成する |
FFlateDataChunk1.sol | 0xa942F946A35545F50792DA1Ea1ADf0c3b619b921 | データコントラクト (fflate 1 of 2) |
FFlateDataChunk2.sol | 0xF10EeDb5ACE715d78e0f89eCd1Dfc3E5874f6e3c | データコントラクト (fflate 2 of 2) |
ThreeDataChunk1.sol | 0xA32bb79b33B29e483d0949C99EC0C439b29e2B33 | データコントラクト (three.js 1 of 9) |
ThreeDataChunk2.sol | 0x0d104Dea962b090bC46c67a12e800ff16eeffB75 | データコントラクト (three.js 2 of 9) |
ThreeDataChunk3.sol | 0x1D11a1c75e439A50734AEF3469aed9ca4fFe39fc | データコントラクト (three.js 3 of 9) |
ThreeDataChunk4.sol | 0x6bAb43D4F3587f9f3ca1152C63E52BF7F8de2Dc1 | データコントラクト (three.js 4 of 9) |
ThreeDataChunk5.sol | 0x57beAe62670Ff6cCf8311411a2A2aAb453413987 | データコントラクト (three.js 5 of 9) |
ThreeDataChunk6.sol | 0xF3A95B30E1Fc2EdCea41fF93270249b6Ab979730 | データコントラクト (three.js 6 of 9) |
ThreeDataChunk7.sol | 0x52a31D845f4bdC1D47Ee21dB7C25Bde2423A91Ae | データコントラクト (three.js 7 of 9) |
ThreeDataChunk8.sol | 0x6CcCc7eA426E14F1E07528296c7d226677fd2fF6 | データコントラクト (three.js 8 of 9) |
ThreeDataChunk9.sol | 0xc230862406bBe44f499943Ae4E9E6317a95BC7Ad | データコントラクト (three.js 9 of 9) |
この続き: 3,392文字 / 画像7枚
まとめ
今回は、先日dom氏が作成したフルオンチェーンNFT「ROSES」について紹介・解説しました。
本記事が、「ROSES」の概要や注目ポイント、フルオンチェーンNFTの新時代を切り拓く可能性などについて理解したいと思われている方にとって、少しでもお役に立ったのであれば幸いです。
また励みになりますので、参考になったという方はぜひTwitterでのシェア・コメントなどしていただけると嬉しいです。
🆕記事をアップしました🆕
— イーサリアムnavi🧭 (@ethereumnavi) September 30, 2022
今回のテーマは、先日dom氏が作成したフルオンチェーンNFT「ROSES」について✍️
ROSESは、トークンごとにバラの形や色が異なるジェネラティブアートNFT🌹
『3D×フルオンチェーン』のNFTをどのように実現したのか、詳しく解説しています⛓https://t.co/wnaFMAK8Db@dhof
さて、ざっと見ていきましたが、いかがでしたか?
Lootのコントラクトと比べると、かなり複雑になっていますね。
「フルオンチェーンNFTでHTMLを使う」というアイデアは他でも見たことがありましたが、まさかthree.jsを動かしてしまうとは、本当に驚きました。
サイズが大きいファイルをgzip圧縮しておいて、JavaScriptで展開するという点も、なかなかすごいアイデアですよね。
flowchart explaining the rough process
— dom (@dhof) September 13, 2022
data contracts/sstore2 are well understood at this point so will skip that
main unlock is using compressed data, then decompressing and loading at runtime via an injected helper script in the data uri
“on-chain npm” etc should be possible pic.twitter.com/h8GQnczvLN
npmというのは、Node.jsのモジュール管理ツールのことです。
Node.jsで開発する際に、例えばnpm install three
とするだけで、three.jsを扱えるようになります。
今回dom氏は、three.jsを9つに分割してデータコントラクトとしてデプロイしましたが、このコントラクトは誰でも使うことができます。
つまり、自分でthree.jsを使ったフルオンチェーンNFTを作ってみようと思い立った際には、dom氏のデプロイしたコントラクトから three.jsを読み込めば良いのです。
もちろんthree.jsに限らず、誰かがJavaScriptライブラリをデータコントラクトとしてデプロイすれば、それを誰もが使えるようになります。
よって、まさにnpmのように、on-chainで誰でも簡単にJavaScriptのライブラリを扱えるようになるわけです。
今回、筆者はROSESのコードを見ていて、今後フルオンチェーンNFTは大きく変わるかもしれないと感じました。
Solidityという制約の多い言語と厳しいガスリミットの中で、いかに工夫してフルオンチェーンNFTを作成するか頭を悩ませていたのですが、three.jsやp5.jsのようなリッチなJavaScriptライブラリが使えるとなれば、実現できることは一気に増えます。
また、データコントラクトを使うことで、ファイルサイズなどの制約もかなり緩くなるでしょう。
編集後記
今回はイーサリアムnavi初の試みとして、Solidity開発者の方に依頼して「コントラクト解説記事」を書いていただきました。
Solidityの内容解説を中心とした記事は久方振りではありますが、元々イーサリアムnaviはSolidityの情報発信から始まっており、丁度1年ほど前はdiscord内で「コントラクト輪読会」という勉強会をやっていた時期もあったほどです。
しかし最近は、私自身があまり開発の勉強にまで手が回らなくなってしまったこともあり、勉強会ならびに開発にかかわる新規記事執筆ができていなかったという、非常にもどかしい状況にありました。
そんな中、立ち上げ当初からイーサリアムnaviに携わってくださっていたnawooさんが、「domが最近出したROSEのコントラクトの中身が面白かったから記事を書けます」と言ってくださったことにより、本記事の公開に至った次第です。
dom氏のNFTは、今までにもイーサリアムnaviでも多数取り扱っておりますが、彼の思想や表現する作品には示唆深いメッセージが多数込められていると考えているので、ぜひ本記事に興味を持たれた方は他の関連記事もご覧になってみてください。
さて、今後もイーサリアムnaviの中で私以外の方に専門記事を書いていただく機会があるかと思いますが、できるだけ難解なテーマでも皆様に分かりやすくお届けできるよう、編集スキルを磨いていきたいと考えています。
また、さらなる更新記事数の増加・対象領域の拡大を目指すべく、個人運営から法人運営に切り替えてやっていくことを決断し、現在さまざまな方面で動いている段階です。
イーサリアムnaviを運営するSTILL合同会社では、web3/crypto関連のリサーチ代行、アドバイザー業務、その他(ご依頼・ご提案・ご相談など)に関するお問い合わせを受け付けております。
まずはお気軽に、こちらからご連絡ください。
- 法人プランLP:https://ethereumnavi.com/lp/corporate/
- Twitter:@STILL_Corp
- メールアドレス:info@still-llc.com