mint-rallyメモ
UNCHAINで行われるMintRallyの紹介イベントに向けて、コードや課題を確認しています。
MintRallyはOSSで開発されており、プロジェクトの目的はイベント主催者が抱える維持率の課題を解決することです。そのため、以下の機能がざっくりと実装されています。
- 進化するNFTを付与できるイベントを簡単に開催できる
- 豊富な魅力を備えたNFTを容易に発行できる
- メタトランザクションやZK(repoのERC2771やcircomなどから)
- 最近では、SBTの機能が追加されたことが報告され、現時点で24件の課題が起票されています
コミットできる部分を探していきます。
技術スタックは満たしているので、明日UNCHAINを見て興味持ったらコミットしてみる。
Technology used
frontend: Next.js, TypeScript
contract: Solidity, ERC721Enumerable, Hardhat, circom
image: IPFS, Pinata
circomはPJレベルで触った経験がないので勉強するます。
ドキュメントが充実しているので助かる。環境構築に手こずる人少なそう。
frontend/がatomic designで構成されていて少し感動した。
hardhat/autotasksは以下を一通り回せばキャッチアップできる。
hardhat/contractsが香ばしいので一通りコントラクト見ていく。
UNCHAIN mtg memo
概要
- 何度も参加する動機をつけることでコミュニティを盛り上げるサービス。
- NFTの特徴が参加するたびに進化する=インセンティブ
- NFT保有者に対しての主催者からのエアドロなども
機能
- イベント作成者が開催日毎にNFTをセットする、受け取り時にはパスワードが必要になる。
- Web3Wallet を持っていなくてもメアド認証でNFTを受け取ることができる
ERC2771
- 主催者がガス代代行する(Forwarder)
- OZ Defender Relayerを利用
- イベント作成
- typedSignData?で署名してbroadcast
- OZ APIは120tx/hなのでイベント上限がつく(メアドとOZを複数構成してLBみたいにはできるw)
※Forwarderの鍵ローテーションでKMS設定する内容を理解しておこ
ZKP
- 回路実装はCircomによって実装され、アルゴはPlonk、Powers of Tauの利用サービスはPolygonZKのhelmesが出してる?
- 合言葉はPoseidonハッシュ関数によりハッシュ化された後、Plonkアルゴリズムによってスマコンに保存される
- PoseidonはZKPの回路と相性が良い
1. イベントの作成
合言葉->keccak256->(固定長: byte32)->poseidon
可変長の文字列は扱えない、固定長のみ扱う。
下記ハッシュを利用してproofを生成する。Circuitを利用してwitnessを計算。
- keccak256 hash1
- poseidon hash2
witnessから下記を計算しsolのcalldataに変換
- proof = 問題の答えを知っていることを証明するもの(思考回路みたいな)
- public signals = proofが正しいものかを検証するためのもの(公開されている入力値)
イベント作成発行時にpublicInputCallDataを引数にtxをbroadcast
2. NFT Mint
初回は同じようなハッシュ関数をん2回回す。
NFT ミント作成発行時にproofを引数にtxをbroadcast
イベント作成時に投げたpublicInputCallDataとproofが同じであるかをVerifierContractと検証し、利用したproofはonchain上に保存する。
コードの確認には下記を利用すればOK
ZKはこれ
回路はこれ
pragma circom 2.1.2;
include "../node_modules/circomlib/circuits/poseidon.circom";
include "../node_modules/circomlib/circuits/comparators.circom"; // 一致するかしないかを確認する
template VerifySecretPhrase () {
signal input correctSecretPhraseHash; // signalは変数定義
signal input challengingSecretPhrase[1];
component hash = Poseidon(1); // componentはライブラリ呼び出し、入力値は1
component isEqual = IsEqual();
hash.inputs[0] <== challengingSecretPhrase[0]; // 試そうとしている入力値をハッシュ化
isEqual.in[0] <== hash.out;
isEqual.in[1] <== correctSecretPhraseHash; // 正しいハッシュ値と一致しているのか(1,2個目の入力値が一致しているのか)
isEqual.out === 1; // 一致していれば1を返す
}
component main {public [correctSecretPhraseHash]} = VerifySecretPhrase(); // publicとは公開入力値の正しいハッシュ値
circomで使用済みproofを保存するコード。
- 使用している場合はusedProofsに格納する。
- NFT発行時に利用されているかを確認する。
proofってナンスかなんかで管理されてて毎回違うproofになるんですか?
⇨計算するたびに異なるproofが出力される。proof自体がwitnnessに依存するので、witnnessが異なれば変わる。ZKはGroth16も使われる、アルゴによってはproofAからproofBも作成できるみたい。
Plonkを採用した背景
⇨Groth16は足し算掛け算が早い、Plonkはハッシュ化が早い。ガス代や処理速度にも関連するため回路特性を考慮して利用している
Plonk2もあるがcircomに対応しているか微妙
AA
⇨メタトラと同じようなもの。AAはセッションキーあたりが強みになる。mint-rallyも移行できれば良いが、AAへの移行は結構難しい。
How to Update Meta Transactions to Account Abstraction?
ZKを取り込む人へのアドバイス
⇨艦隊のボードゲーム(撃ち合い)をオンチェーンで行うことで勉強できる。
質問なのですが、メールアドレスログインの場合もmetamaskログインの場合も同じ動きをしているのでしょうか?メールアドレスログインの場合、メタトランザクションの署名はどのようにやっているのか気になりました。
⇨これ使ってる。UIは比較的シンプルなのでweb3authを利用しない。
これ使えると良い
OSS