CNPR(CryptoNinja Partners Rookies)は、「初心者応援」がコンセプトのNFTコレクションで、CNPの2次創作のNFTです。 ファウンダーはANISUさんで、リーダーにしんももさん、ジェネのエンジニアになおこママさんが参加しています。 僕が最初に参加したNFTプロジェクトで、フロントエンド、スマートコントラクト、バックエンドの開発を担当しました。 また、忍者DAOのエンジニアサーバーで、多くの人にアドバイスをいただきました。 イケハヤさんがCNPRについて解説してくださっているので、詳しく知りたい方はこちらを聞いてみてください。
- MY ROLE
- Front End Engineer
- Smart Contract Developer
- Back End Engineer
- STACK
- Solidity
- Hardhat
- Next.js
- TypeScript
- Tailwind CSS
- Mantine
- ethers.js / wagmi
- AWS Lambda / AWS API Gateway
- Alchemy
CHAPTER 1
実装した機能
スマートコントラクト
- フロントから送られたECDSAの署名をオンチェーンで再検証し正しい署名かどうか判定
- 持っているNFTをバーンして新しいNFTを取得する機能
- SBTの実装
- メタデータを将来オンチェーンに移行できるようする
バックエンド
- 実地するセールの種類、ミント数、ウォレットアドレスを含めたECDSAの署名の作成
- 接続したウォレットアドレスからスマートコントラクトに送るデータを取得するAPIの構築
フロントエンド
- 初心者でもわかりやすいようにミントサイトを構築
今回のプロジェクトは、NFTを購入するのに審査を受ける必要があり、1回の販売で全て売り切るのではなく、何回もセールを実地して、継続的にNFTを販売する必要がありました。 現在だと、1回のセールで全て売らない販売方法は一般的ですが、当時は、継続して販売していくやり方を採用しているプロジェクトは、少なくとも国内ではなかったです。
継続して販売するための選択肢として、マークルツリーとECDSAののどっちを採用するか迷いましたが、ガス代の負担をなるべく減らすためにECDSAを採用しました。 ちなみに僕がCNPRをリリースした時は、ホワイトリストを実装するのにmappingを採用しているところが多く、マークルツリーを使っているプロジェクトは数例しかありませんでした。
なので、当時は、マークルツリーについてもしっかりと理解できておらず、ECDSAを採用しましたが、今なら管理のしやすさや安全性を考えて、マークルツリーを使うと思います。
CHAPTER 2
スポットライト
ECDSAを使ったホワイトリストの実装
ガス代の負担をできるだけ下げるために、ECDSAを採用しましたが、問題点として、国内でECDSAを採用したプロジェクトのほとんどが、立て続けにハッキングの被害に遭っていたことです。 その中で、ECDSAを採用したので、どうすればハッキングされないのか、正しい実装方法を学ぶ必要がありました。
リサーチをしてみたところ、海外のプロジェクトでECDSAを採用し、うまくいったプロジェクトがオフチェーン署名の正しい実装方法について解説している記事を見つけました。それを参考にして、スマートコントラクトとバックエンドのAPIを作り、ECDSAを使ったホワイトリストを実装し、バックエンドのセキュリティ対策は、Classmethodさんの記事を参考にしました。
また、ECDSAの楕円曲線はすごく難しく、何をしたらハッキングのリスクになるのか、理解するのにかなり時間がかかりました。
メタデータを将来オンチェーンに移行できるようする
現在のほとんどのNFTプロジェクトは、メタデータをAWSのS3やipfsまたはArweaveなどに保存しているので、仮にプロジェクトが終了した場合、画像などのデータが消えてしまうリスクがあります。
それを避けるためには、フルオンチェーンにするしかないのですが、現在のイーサリアムだとSVGを使い、かなり無茶をしないとオンチェーンにデータを保存できないので、手間とガス代が結構かかります。そこで、将来オンチェーンにデータを書き込むのがもっと簡単になった時、オンチェーンへ移行できるように、メタデータの切り替えをできるようにしました。
function tokenURI(uint256 _tokenId)
public
view
virtual
override
returns (string memory)
{
require(_exists(_tokenId), "URI query for nonexistent token");
if (isOnchain) {
return descriptor.tokenURI(_tokenId);
}
return
string(abi.encodePacked(ERC721A.tokenURI(_tokenId), baseExtension));
}
初心者でもわかりやすいようにミントサイトを構築
当時のNFTプロジェクトのほとんどは、ミントサイトを作るのにHashLipsが採用されることことが多かったのですが、かなり使いづらくて、CNPRは初心者向けなので、もっとわかりやすものを作る必要があると思い、ゼロから作りました。スマートコントラクトとミントサイトの両方を作らないといけなくて、どちらも初めての経験だったので結構大変でした。
ここでミントサイトを独自で作ったことによって、色々なNFTプロジェクトにお声をかけていただいたので、作ってよかったです。
まだ開発途中ですが、CNPRのNFTを購入するページが大体できました😊 実際に購入するときは、動画のようにボタンを押していけば買えます! 画面収録をしているせいでかなり重くなっていますが、実際に買うときはもっとサクサク動くと思います。 引き続き頑張りますー☺️ #CNPR
CHAPTER 3
ユーザーからのコメント
#CNPR のmintサイトすごくいい! 特にいいと思ったのが以下。 ・トランザクションの説明含め、すべての表示が日本語。 ・トランザクション待ち中に詰まった場合の対処法が表示される。 ・mint完了時にちょっとしたギミックがある。
お疲れ様です!! 最近だと一番わかり易いUIで感動しました!
すごく分かりやすくて最高でした🌈🌈
CNRRエンジニアのryujiさんは、フロントエンドエンジニアなのでユーザビリティを考えたWEB画面を作ってくれます。 フロントエンドエンジニアを欲しているプロジェクトはぜひryujiさんにご相談ください。
無事CNPRをリリースできてよかったです🥳 また、ミントサイトが良かったとお声をいただきありがとうございます😊 このプロジェクトを手伝ってくださった方、ご購入していただいた皆さんに感謝です🙇♂️ 引き続き開発を頑張りますので、これからもCNPRを夜露死苦です✨ #CNPR
無事にミントできました! ミントサイトはとっても分かりやすかったです。
#CNPR mint成功!! mintサイト、シンプルでわかりやすかった👏 初心者向けというのが、凄く伝わってくる ではでは、これから確認してきますー
#CNPR ミントできました🔥 2期生の皆さんどうぞよろしくお願いいたします🙇 ミントサイトは すごく初心者にも 分かりやすいし、手が凝ってました。 さすがです!!🎊
#CNPR ミントできたー! ガス代も上がらずに 時間もかからずに 無事にミントできました〜! どんな子がきてくれたかな〜🤗
✨#CNPR ミントできました!✨ 皆さんおめでとうございます🎉🎉 僕も手に入れました(●´ω`●) ブラックルナちゃんがでましたよ!! 玉ねぎミタマも可愛い😍 めちゃ嬉しいです😂ワクワクが止まらない😆😆
CHAPTER 4
学んだこと
今回のプロジェクトは、フロントエンド、バックエンド、スマートコントラクトの開発を全て一人で担当しました。 これらの経験のおかげで、NFTをどのように作りユーザーに購入してもらうのか全て知ることができ、スキルもかなり向上しました。 また、スマートコントラクトは、一度デプロイしたら全世界にコードが公開されるので、脆弱なコントラクトの場合ハッキングされてしまします。 今まで、エンジニアをしていてこういう経験がなく、プロジェクトも多くの人に注目されていたので、スキルもそうですがメンタルもかなり鍛えられました。