Live Like A CatのNFTコントラクトを解説する。
こんにちは。けいすけです。
フリーランスエンジニアとして活動しています。
最近ではNFT関係のコントラクトを書いていて、LLACやピクQN!のコントラクトを制作しました。
https://opensea.io/collection/live-like-a-cat-nekonoyouniikiru
https://opensea.io/collection/pixqn
ぼく自身は2022年の1月からNFTに参入しました。そして、ひたすらNFTのコントラクトを作り続けて、2022年で52個のコントラクトを作り続けていました。
その中でも12月28日にリリースしたLLAC(Live Like A Cat)は2022年を締めくくるにふさわしい集大成となりましたので、このコードをまとめておきたいと思います。
LLACはプロジェクト自体もまさにドリームチームで、イケハヤさん、うむこさん、しゅうへいさんが中心になっていて、リリース直後の時価総額も日本ランキング2位につけています。
ということで、これからソースコードや機能の解説をしていくのですが、エンジニア以外からしたら「なんのこっちゃ?」という記事が続きます。
何となくこんなことをしてるんだなー、と思っていただければ幸いです。
ちなみにLLACのソースコードはこちらです。
MITライセンスなので、だれでも自由に利用できます。
https://etherscan.io/address/0x597d757f8502f1fe8e7dd6fc7fe884a51c5ae2b9#code
メインの規格はERC721PSI
ERC721PSIソースコードはコチラです。
普通は、NFTを発行する場合はERC721という規格を採用します。そして最近ではERC721を改良してガス代を節約できるERC721Aという規格を採用する場合も多いです。
ですがLLACではERC721PSIを使いました。
多くのプロジェクトはERC721Aを採用しますが、その理由は1度に大量にミントした場合にガス代が格安になるというところにあります。
LLACは初期セールスでは全てを売らないで、運営分として大量に保有した状態でリリースしました。この運営保有分は後々リリースしていきますが、初期の段階で大量にミントする必要があります。
このように、2つのウォレットに分けて運営が約14700枚保有しています。大量にミントするのですからERC721Aがいいような気がするのですが、実はそうでもないところがあります。一度に数百枚〜数千枚というオーダーで大量にミントした場合、その後のトランスファーに大量のガス代がかかるというデメリットがあるのです。
これは一度に10枚程度しかミントしないユーザーでは体感できないレベルのガス代増なのですが、LLACの様に1万枚を超える運営保有分がある場合には無視できないデメリットになってきます。
そこで、LLACで採用したERC721PSIでは、この問題を解消していて、一度に大量にミントした場合にも、その後のトランスファーでガス代が増えにくいという特徴があります。
ユーザー目線で考えて見ると、LLACはユーザーは一度に数枚、多くて10枚程度しかミントしませんので、ERC721AでもERC721PSIでもあまり変わりません。ですが、広く薄くメリットがあることには変わりありませんので、この点も有利なところになります。
盗難防止策としてERC721RestrictApprove
ソースコードはコチラです
RestrictApproveについては、ちょうど良い投稿があったので引用させていただきます。AoPanda Partyでも採用されています。
ものすごーくざっくり説明すると、setAprovalForAllというNFTの全権委任を騙してさせてNFTを盗むという手口を防止することができます。
これで全ての詐欺を防止できるわけではないので、引き続き自衛と注意喚起は必要です。ですが、この機能によって「一度にたくさん盗まれる」という事例は極端に減りました。
LLACでもリリースから1週間経ちましたが、大規模な盗難は確認されていません。残念ながら数点盗難されてしまったので、引き続き注意して行きましょう。
ミント関数はモリモリ
NFTを発行するミント部分ですが、ぼくはいつも機能モリモリで作ります。主な機能としては
マークルツリーによるAL管理
マッピングによるAL管理
ALナシによるパブリックセールも可能
ミント数のカウントのありなしを切り替え可能
バーニン(1体ミント1体バーンによってNFTを取り替える機能)搭載
ミントと同時に別コントラクトでのミントも可能(同時にSBT)をミントする
ソースコードはこんな感じです。人によっては見にくいと思いますというか多くの人は見にくいと思うはずです(笑)
ミント関数がこんなに長いプロジェクトって見たこと無いです💦
このソースコードが見にくいのは自分でも感じてはいます。しかし、いろんな所でエンジニアをしていると、それだけ色々なセールに対応しなければなりません。
対応できるパターンが多ければ多いほどいいに決まっています。
実際に12月30日にリリースしたNounishCNPのフリーミントでは、全てALを持っている人だけのミントの予定だったのですが、途中で不測の事態が起こり、完全に誰でも参加できるパブリックセールに切り替えました。これは運営のうどんさんのナイス判断によるものです。
あと長期的な運営も見据えてバーニンも入れています。ちなみにLLACでバーニンをするかどうかは決まっていません。
「取りあえず入れておくか・・・もしかしたら使うかも知れないし。」という理由で搭載しています。
地味に活躍するairdrop機能
NFTプロジェクトには必ずエアドロ関数は仕込んでおいた方が良いです。
デプロイ後に「○○さんに△枚ミントしたいんですが・・・」
という事はよくあります。
デプロイ後にいろんな方に急遽ミントする事はよくあるので、そのためにも必ずエアドロ関数を入れておきましょう。
それと、大量の運営保有をミントする場合には、ガスリミットの関係でコントラクトではミント仕切れない場合があります。
その時にもエアドロは使えますので、ソースコードにエアドロは入れておきましょう。
ソースコードはこんな感じです。
いざと言うときの外だしミント&バーン
普段はあまり使わない機能ですが、たまに使ったりします。あと保険的に残してあります。
この様にexternalでミント関数を作っておきます。もちろん、誰でもミントできるとキケンなのでAccesCtontrolでミントできるアドレスを限定しています。
そうすると、元々のミント関数では対応できなくなった場合に、外部にミントだけのコントラクトを作ることで対応する事ができます。
例えば、長期的に販売するNFTで、途中から別の販売方法をしたい場合ですね。こういったことはたまにあります。
それとバーン関数も外からたたける様になっています。こうすることで外だしバーニンが可能になります。バーニンは長期運用必須ですので、毎回ALの渡し方やセール方法を変えていくことがおおいので、柔軟性を持たせることは大切です。
ソースコードはこんな感じです。
また、別の使い方として、LLACではNFTをミントすると同時にSBTもミントされるという仕様にしました。
具体的には、ミント関数の中のここで、externalMintを呼び出しています。
ちなみに、LLACではSBTも同時にミントしていますが、LLACのコントラクトとSBTのコントラクトは同じなんですよね。コンストラクタが違う位です。
むだが多いと言われればその通りなのですが、NFTとSBTの部品の共通化と考えれば管理コストも低いのでこのようにしています。
ソースコードはこちらなのでぜひ比べてみてください。
https://etherscan.io/address/0x597d757f8502f1fe8e7dd6fc7fe884a51c5ae2b9#code
https://etherscan.io/address/0x6eED0Ff2afbe92B6d0990Cd63cA10Ce5F425dBf1#code
将来的なオンチェーンデータを想定したtokenURI
NFTと言えば永続性とか、改竄不可能というイメージがありますが、現在のNFTは画像データをレンタルサーバーなどのストレージやIPFSに保存することが一般的です。
これはブロックチェーンの容量が小さく、数MBもする画像はオンチェーンに乗せられないからです。
以前24KBの画像をオンチェーンに乗せた事がありましたがガス代だけで5万円ほどかかりました💦
と言うことなのですが、将来的にチェーンの容量が大きくなった時を見据えて、tokenURLをインターフェースで外に出せるようにしてあります。
それからSBT等に使うために、同じ画像のtokenURIをreturnできるようにもしてあります。これらはスイッチで切り替える方式ですね。こうすることで1つのソースコードでSBTにもオンチェーンにも両方対応できるようになっています。
ソースコードはこんな感じです。
サーバーが遅かったというLLACの失敗
LLACのリリースで1つ失敗というか反省点がありまして。それはサーバーが弱かったと言うことです。
画像データを置いていたサーバーがリクエストに耐えられなくて、なかなか画像が表示されませんでした。(リクエストしすぎだとレンタルサーバーに怒られてしまいました。ごめんなさい)
画像の表示を楽しみに待ってくださったのにごめんなさい。どう見てもぼくのミスです。
ということで、途中からデータをAWSに切り替えました。これで一気に画像が表示されるようになりました。
ちなみにLLACは22,222枚の画像で約20GBほどあります。
ではミント時に20GBのリクエストがサーバーにくるのか?と言えばそうではなく、実際には100〜200GBほどのリクエストが来ていると考えられます。
というのも、世界中の取引所やNFT取引ツールから一気にリクエストが来るわけです。
画像の容量の数倍のリクエストが一気にきます。しかもLLACは超大人気プロジェクトです。と言うことで最初に用意したサーバーは耐えられませんでした💦
ごめんなさい。完全にぼくのミスです。
明確な線引きはできませんし、これはぼくの経験的な数値ですが、画像の容量が5GB程度ならファイルサーバーはあまり気にしなくて大丈夫です。
ですが画像の容量が10GBを越えてくるとAWSのような頑丈なサーバーにしておくと良いでしょう。
おしまい!
2023年あけましておめでとうございます。
2022年中にLLACという形で最高のリリースができて本当に嬉しかったです。
2023年もNFTはどんどん進化していくと思います。今では考えもしない使い方が出てくるはずです。
一緒に日本のNFTをもりあげていきましょう。
ツイッターもやっていますので良かったらフォローよろしくお願いします。