GitHubのコントリビューションによって動的に変わるNFTを作ってみた
はじめに
本記事では、GitHubのコントリビューションに応じて見た目が変化するNFTについて技術的な背景も含めて紹介します。
いわゆるDynamic NFTですが、既存サービスとNFTの接続点として非常に可能性を感じています。Dynamic NFTでは、ブロックチェーンの外にあるオフチェーンデータをイベントにしてオンチェーンのパラメータを変更することができます。
ゲーム内での活動によってレベルアップし、見た目が変化するような演出は既存サービスでは当たり前に行われていますが、同じような仕様をオンチェーンのNFTでも実現できるようになります。
詳細な仕組みや具体的な応用事例の紹介は以下の記事が詳しいです。
今回はエンジニアとは切っても切れないGitHubへのコントリビューション(=オフチェーンデータ)によって動的に変化するNFTを作ってみました。
GitHubコントリビューションNFTの開発
仕様
- 対象のNFTは誰でもフリーミント可能
- NFTのメタデータには、GitHubへのコントリビューションを表す草画像を使用
- GitHubへのコミットのイベントを検知して、草画像のカラーテーマがランダムで更新される
簡単な概念モデルを作成しました。
スタック
- OpenZeppelin, Foundry, Hardhat
- Next.js, wagmi, Tailwind CSS
開発ステップ
NFTを作成
ERC721トークンで実装しました。
メタデータとしてGitHubの草画像をSVG形式で作成しています。
GitHub API v4で取得したコントリビューションの情報をもとに、スマートコントラクト上でSVGを構築し、そのままオンチェーン上に保存しています。
このあたりのSVG構築のソースは、Nounsを参考にさせてもらいました。
GraphQLで提供されているGitHub API v4では、userに紐づくcontributionCalendarが生えているので、GitHubのページをクロールしてsvgを持ってくる必要は無くてひと安心でした。
GitHub APIを呼んでいるサーバーは、Next.jsのAPI Routesに実装してあります。
草情報は週ごとのコミット数によって0-4のレベルが割り振られたデータがカレンダー形式で返却されますが、SVG構築がしやすいよう連長圧縮をかけています。
(Nounsのソースでも使われていてそのまま流用したほうが実装コストが低いと判断しました。必ずしも圧縮後のサイズが小さくなるわけでは無いです)
テーマカラーもこの部分でランダムに決定していて、オリジナルのグリーンだけではない草画像がコミットのたびに作成されます。
テーマカラーに含まれる具体的なカラーコードはこちらを参考にしました。
草画像の完成イメージはこんな感じです。
ただコミットのイベント検知を再現する部分はGitHubとの連携が必要になり、この記事のトピックからずれてくるため、疑似的にイベントを検知できるようコントラクト上で発火させたい関数をpublicにしています。
コントリビューションを検知してオンチェーンパラメータを更新
肝心のメタデータ更新はChainlinkのオラクルを使って再現しています。
コミットイベントをあったときにcommitGitHub
が呼ばれ、オラクルがAPIレスポンスを持ってfulfill
をコールバックします。
余談ですが、独自のノードを立てているわけでは無いので流れはシンプルですが、外部との接続が絡むとローカルテストが複雑になるのはあるあるかと思います。
その際、ローカルから他ネットワークにフォークしてコントラクト関数を実行できるFork Testingが便利でした。
今回はGoeliテストネットにデプロイしたのですが、テストネットで使えるオラクルをいくつか公式から提供してくれていたので、こちらを利用しました。
ドキュメントを見た感じ、これらのオラクルでは対応しているレスポンスが、
- 単一の値(型はuint256, int256, bool, string, bytesそれぞれあります)
- uint256の複数の値
となっているので、これ以外のレスポンスをとるAPIと接続する際は独自ノードを作成する必要があります。
今回はオラクルを体験してみるという目的でシンプルな構成にしたかったので、用意されているノードをありがたく使わせてもらいました。
tokenIdが絡むためどうしてもステートフルになり、コールバック関数の中で草画像データとtokenIdの2種類のデータが必要で、危うく独自ノードの道に進みかけましたが、Chainlinkにリクエストを送る際に作成されるrequestId
に紐づける形でtokenIdを保存する案が浮上して事なきを得ました。
まとめ
GitHubの草画像を使ったDynamic NFTを作成しました。
コントラクトとAPIの実装は何とか完了したのですが、フロントエンドの実装も絶賛進めているので完成したタイミングでまた更新します!
参考
Discussion