メンバーシップNFTの日付割り当ての仕組みと運用について
こんにちは、NOT A HOTEL で CTO をしている大久保 貴之 (@okbtks) です。
今回は NOT A HOTEL の MEMBERSHIP NFT に日付を割り当てる仕組みと運用について話そうと思います。もともとは公にするつもりのなかったお話なのですが、お客さまからいただいたご質問や、SNS での投稿を拝見しまして、この話を公開しようと考えを改めました。
まず結論を書きます。次の3点によって特定の人に日付の割り当てを優遇するようなことが起こらないような仕組み、運用を行なっています。その結果、たとえ弊社代表の濱渦 (@shinji_hamauzu) であっても意図的に何かをすることは非常に困難になっていると考えています。
購入された順番で日付を割り当てるテーブルを事前に決めています
その日付のテーブルは、対象のNFTが購入される前に事前にブロックチェーン上に情報を書き込み、後から必要に応じて第三者が検証できるようにしています
この日付のテーブルを知る人間は2名しかいません
このことについて、次の順番でお話ししようと思います。
NOT A HOTEL の NFT について
なぜ今回のようなことを考えるのか
日付割り当ての仕組み
日付割り当てのテーブルをオンチェーンに
社内での情報の取り扱い方、システムでの取り扱い方
その他、考えていることなど
おわりに
今回いちばんお伝えしたいことは、NOT A HOTEL ではお客さまのことを一番に考えてサービスづくりに取り組んでいるということです。細かく書きすぎている部分もありますが、気を楽にして流し読みしていただければと思います。
あと web3 に限らず広く深く仲間を絶賛募集中ですので、こちらの採用情報も見ていただきたいです!
NOT A HOTEL NFT について
NOT A HOTEL の NFT は大きく2種類、会員権としての機能を持つ NFT 「MEMBERSHIP NFT」と、ホテルに滞在できる権利の NFT 「THE KEY NFT」があります。
これらについては次の動画を見ていただくのが一番だと思います。
より詳しい情報は こちらの note をご参照ください。キーアイディアは非常にシンプルなのですが、販売から実際の運用まで色々と考えることが多く、たくさんの発明・アイディアが詰まっているプロダクトになりました。
なぜ今回のようなことを考えるのか
NOT A HOTEL の MEMBERSHIP NFT に割り当てられる日付はランダムで購入時に選ぶことができません。当然ながら、運営が恣意的に操作できてしまうのではという疑問や不安が生じるかと思います。運営上の決まりを作っていても、できることをやってしまうヒトが出てくる可能性もあります。
私たちはこれを仕組みで解決できないか、公に可能な範囲で説明できるようにするにはどうすれば良いかについて考え続けています。
web3 の良いところの1つは誰もが検証可能なことだと思います。一方で私たちのサービスではすべての情報をオンチェーンに載せることは難しく、オフチェーンで扱う情報がどうしても多くなります。 すべての情報をオンチェーンに載せない限り、裏側でも正しい行動をとっているのか、不適切な行動をとっていないのかを証明することが非常に難しいのです。
一般的には第三者機関を入れて〜という話になると思うのですが、せっかく web3 に取り組むのだから、ここをなんとか web3 的な考え方で解決できないかと考えた結果、今回のような仕組み、運用となりました。
テーブル自体を公開することが目的ではなく、必要になった時にそれができるように事前に仕組み化、運用を行うことで、先に述べた課題に対するリスクを小さくできると考えています。
余談
当たり前のことではあるのですが、NFTの企画段階から販売をして実際のホテル利用の運用を始めたこれまでの間に、社内外の関係者から冗談であっても日付に関すること、コンプライアンスに反するような発言やアプローチを受けたことが 1度もありません。僕はこの会社に関わる人たちのこのような当たり前を当たり前にしている姿勢がとても好きです。
日付割り当ての仕組み
NOT A HOTEL の MEMBERSHIP NFT の token ID は、mint された順番(NFTが発行された順番)で決まります。そして MEMBERSHIP NFT の日付は事前に準備した token ID x 日付のテーブル(下図)に基づいて、reveal 時に割り振られます。
私たちが事業を進めていくにあたり、事前に決めた日付テーブルに修正を加える必要が出てくるとします。この場合、すでに mint された分の日付は変更せずに、まだ mint されていない部分の日付を変更するようにしています。
そしてこのテーブルの情報は次節で説明するように、mint される前に事前にオンチェーンに流すことで、事前に決めていたことを説明できるようにしています。
余談
事前にオンチェーンに日付割り当ての情報を流すため、事業の状況に応じて施策や方針を柔軟に変更することが難しくなります。
私たちがはじめて NFT を世の中に送り出す時、MEMBERSHIP NFT の種類、S と X の数をどのように設定するべきかの判断が難しい状況でした。結果、下図のようなテーブルを準備し、数量を比較的柔軟に変更できるけれどお客さまの公平性は損なわないようなことを考えました。
先のテーブル(上図)における黄色の背景のSと緑色の背景のXがそれぞれ交換可能なものにしています(下図)。Sの在庫を減らすことでXの在庫を確保することができ、またその逆も可能となっています。
日付割り当てのテーブルをオンチェーンに
まず前提として、解決したい課題は事前に日付の順番を決めていたということを説明できるようにするということで、日付の順番自体を事前に公開したいわけではありません。
そのため、次のような仕組みを考えました。
日付の順番を一定区間ごとに区切り、salt をつけた文字列としてハッシュ化する
その区間を表す key とともにオンチェーンに流し、key からハッシュ値を引けるようにする
検証時は key と salt の情報を公開することで、既知となっている reveal 済み NFT の日付および token ID 情報からハッシュ値が正しいことを確認できるようにする
まず事前に決めた日付テーブルを一定日数ごとに分割してオンチェーンに流してます。例えば日付テーブルのように12日ずつ分割しておくと、後からテーブルの構成を変えたい、となった場合も今すでに発行されている部分はそのままに、これから発行される分の日付割り当てを変更することが可能になります。一方で細かく分割しすぎると管理が煩雑になったり、ガス代が多くかかるなども出てきます。今回の運用ではそもそも多く変更することは想定しないという前提のもと、12日を1セットとして分割するようにしました。
具体的には次のような日付列に salt を追加した文字列をハッシュ化し、それをオンチェーンに流しています。
% echo "01/12,12/31,...,12/23,12/01,08/28,6vhto" | shasum -a 256
1b2c4c01fbe0640df668e5d0231f22d8bcdea91f77696b7cdc170f061dd990f2
オンチェーンに流すにあたり、非常にシンプルなコントラクトを用意しています。アップグレードを行っていない現時点(2023年1月4日現在)でのコントラクトIDは次の通りです。
オンチェーンに流す場合、このコントラクトに対して、上で生成したハッシュ値と対となる key の文字列を指定します。
// addHash(_name,_dateHash)
addHash("22S01Dev","1b2c4c01fbe0640df668e5d0231f22d8bcdea91f77696b7cdc170f061dd990f2")
次のメソッドを使って実際のハッシュ値が取り出せます。
// getHash(_name)
getHash("22S01Dev")
> 1b2c4c01fbe0640df668e5d0231f22d8bcdea91f77696b7cdc170f061dd990f2
この取り出したハッシュ値と、実際に mint され日付割り当てされている情報と salt からハッシュ化したものが同じかどうかで検証が可能となります。また addHash を用いたトランザクションの情報を見ることでオンチェーンに流した日時も一緒に確認することが可能です。
第三者が検証するときに弊社から提供する情報としてはハッシュ化する時に使用した salt とそれに対応する key (_name) になります。
下図のように Etherscan というサービスを使えば上のメソッドの実行方法などを知らなくても、日付割り当てテーブルの情報が書き込まれた時間やハッシュ値、対象の NFT が mint された時間、割り当てられている日付などを確認することができます。
※ 今回説明に用いた key (_name) およびデータ(ハッシュ値)は実際のオンチェーンには存在しません。
※ 現時点では salt と key の情報を第三者へ提供する予定はありません。
余談
ガス代の問題であれば他のネットワークでも良いのではという疑問を持たれる方もいると思いますが、現状はメンテを含む社内運用のしやすさやお客さまの分かりやすさなどを優先して、1つのネットワーク、Ethereum のネットワークに統一しています。一方でオンチェーンへの情報の載せ方はもう少し工夫できそうです。
社内での情報の取り扱い方、システムでの取り扱い方
社内で日付の情報をいかに扱うかはとても重要です。私たちのサービスには非常に多くの方が関わるのですが、これから説明することにより、私とあと1名の者しか日付テーブルを知らなくて良い状況、知ることができない仕組みを作っています。極論、1人しか日付テーブルを知らない状況も作れるのですが、それはそれで別のリスクが生じるので最小限2名が知り運用する体制にしています。
やりたいこと、解くべき課題は「お客さまが reveal されるまで、もしくはお客さまの手元に MEMBERSHIP NFT が届くまで、社内および関係者がどの token ID が何月何日になるのかを知ることができない状況を作ること」です。
その一方で運用上、事前に token ID から何月何日になるのかわかる仕組みをシステム側に用意する必要があります。事前にNFTの画像(日付が刻印されている)を用意する必要があったり、現実的に運用が可能な範囲で情報を適切に切り離すことを考えることには試行錯誤が必要でした。
結果、日付と token ID 及び MEMBERSHIP NFT の種別を紐づけるテーブルの代わりに、下図のような日付とハッシュ値のテーブルを用意し、そちらを運用に用いることにしました。ここでのハッシュ値がメンバーシップの情報(種類や token ID)に対応するものです。ハッシュ値の生成ロジックにシークレットキーを含めます。このようにすることで次の3点を知らない限り、reveal 前に token ID から日付を割り出すことが困難になります。
日付とハッシュ値のテーブル:一部のエンジニアには見えても良い
ハッシュ化するためのロジック:多くのエンジニアに見えても良い
ハッシュ化するために必要なシークレットキー:慎重に管理が必要
エンジニアであれば 2. を見ることができる人は複数いますが、本番環境において 1. を見ることができる人は限られます。3. に関してはさらに絞られます。万が一に一部、もしくは全てが漏れた場合も、既存の仕組みに影響なくそれぞれを更新して運用することが可能です。そもそもの仕組みとして、NFT が発行された順番で日付が割り当てられるため、仮に日付テーブルを事前に知っていたとしても、決めうちで日付を選ぶことは容易ではないと考えています。
その他、考えていることなど
今回説明したこと以外にも色々とお話ししたいことがあったのですが、長くなりすぎたので別の機会にします。最初に 紹介した note の よくある質問 の内容とかにも興味深いものが多いと思います。お時間許しましたらご覧いただけると嬉しいです。
技術的な話としては、伊達さんの こちらの note もぜひ読んでいただきたいです。
これまでの記事で説明していないこととしては、コントラクトの実装で行なっている工夫の話や、署名周りに KMS を使うことで秘密鍵を社内のメンバーに共有する必要がない仕組みで運用していることなどは興味深いかもしれません。NOT A HOTEL としての web3 との向き合い方、wallet の考え方なども今後お話しする機会があればと考えています。何よりも実際にプロダクトとして新たに触れていただける日が来ることを楽しみにしています。
おわりに
ここまでお読みいただきありがとうございました。実運用にあたり今回説明をあえて省いた部分や書けなかった工夫している部分がまだまだたくさんありますが、大枠の考え方や運用の仕方については説明することができたのではと思います。
NOT A HOTEL は今回の NFT に限らず、何か1つのことをやるだけでも多くの方が非常にたくさんのことを深く考え抜いて進めている会社です。そしてその根本にある原動力は、メンバーひとりひとりが持つお客さまに最高の体験を提供したい、サービスやプロダクトを提供したいという想いだと思います。
やりたいこと、つくりたいものがまだまだ沢山たくさんあります。それらを一緒に考え抜きながら一つずつ実現させていく仲間を、エンジニア・PdMに限らず大募集中です。たくさんの職種を募集しています。募集にない職種での応募も大歓迎です。
個人的な想いとしてはエンジニア・PdMの方は特に熱烈大募集中です!少しでも気になりましたら気軽に下記リンクよりご応募ください!
また NOT A HOTELのメンバーと気軽にコミュニケーションをとることもできます。少しでも気になるトピックがある方は、ぜひこちらからカジュアル面談のお申し込みをお願いします!
長くなりましたが、引き続き NOT A HOTEL をよろしくお願いします!!