見出し画像

【完全保存版】thirdwebでユーザー名からスマートウォレットを作成するプロジェクトを作ろう!


0 はじめに

今回は、こちらのYouTubeを元に、thirdwebを使って、「名前」と「パスワード」からスマートウォレットを作成します。

1 準備をしよう

1 git clone

まずは、git cloneを行います。

git clone https://github.com/thirdweb-example/unilogin.git

2 依存関係のインストール

ディレクトリを移動し、依存関係インストールします。

cd unilogin 
yarn install

3 client IDの設定

次に、「env.local.example」ファイルをコピーし、「env.local」を作成します。

その上で、下のように、「NEXT_PUBLIC_THIRDWEB_CLIENT_ID」を設定します。

なお、クライアントIDについてご不明の場合は、こちらをご参照ください。

4 立ち上げを行う

設定できましたら、下のように立ち上げます。

yarn dev

2 やってみよう

1 スマートウォレットの作成

「localhost:3000」を確認すると、下のように立ち上がりました。

任意のユーザー名パスワードを設定し、ログインします。

なお、すでにテストをしている他の人と被らないようなユーザー名にする必要があります。

このように、処理が進んでいます。

現在は、暗号化されたアドレスIPFSにアップロードしています。

ここでは、スマートウォレットをデプロイし、そのユーザー名を登録しています。

すると、このようになりました。

「0x49…Db」の部分が今回作られたスマートウォレットです。

2 スマートウォレットからのNFTの取得

では、このスマートウォレットERC1155のNFTを取得してみます。

「Claim」を選択します。

すると、このようにClaim中となります。

このように、Claimが成功したようです。

先ほどまで「14399」となっていたClaim数も一つ増えています。

このようにNFTを取得できました。

3 スマートウォレットの確認

次に作成した、スマートウォレットのアドレスを選択してみましょう。

こちらが、今回作成したスマートウォレットです。

ちなみに、「Base Goerli Testnet」というチェーンで作成していたということもここで分かりました。

「Account」を見てみると、下のように、取得したNFTを確認できました。

ちなみに、上の画像を選択すると、「ERC1155」であることも確認できました。

4 スマートウォレットの再入力

では、再度同じユーザー名で入れるかも確認してみましょう。

ユーザー名パスワードを入れ、進みます。

このように、ユーザー名が存在していることが確認されました。

すると、このように、先ほどのスマートウォレットのページに行くことができました。

5 パスワードが違う場合の流れ

では、パスワードが違う場合も確かめてみましょう。

下では、違うパスワードを入れて、進んでみます。

すると、このように、パスワードが異なる旨のエラーが想定通り出ました。

3 構成を理解しよう

では、どのような処理が行われているのかを見てみましょう。

下のように、クライアント側オンチェーンIPFS関連です。

ユーザー名とパスワードの入力

まずはユーザー名パスワードを入力します。

そのユーザー名に対応するアカウントFactoryコントラクトに存在するかを確認し、分岐します。

4 ユーザー名が「Facrtory」コントラクトに存在しない場合

以下、存在しなかった場合の分岐です。

1 ローカルウォレットの作成

まずは、新しいローカルウォレットを作成します。

2 ローカルウォレットの暗号化

次に、このローカルウォレットパスワードを使って暗号化します。


3 暗号化されたローカルウォレットの保存

この暗号化されたローカルウォレットIPFSにアップロードします。

4 スマートウォレットのデプロイ

一方、そのスマートウォレットデプロイします。


この部分での個人の見解を書きます。
誤りがありましたら、修正いたします。

新しく作られるスマートウォレットの「register」メソッドを使い、「Factory」コントラクトに登録します。

そして、スマートウォレット最初の処理が行われた段階で、コントラクトアドレスとなるため、その段階でデプロイされます。

その処理はほぼ同時に行われますが、コントラクトデプロイ直後、その内部の関数を実施という流れになりますので、このように、デプロイと登録を分離して書いているのではと考えました。

5 Factoryコントラクトへの登録

次に、このユーザー名とIPFSにアップロード済みのメタデータのURL登録します。

6 ローカルウォレットとスマートウォレットの接続

これで、スマートウォレットに接続できました。

5 ユーザー名が「Facrtory」コントラクトに存在する場合

次はアカウントが存在する場合の流れです。

1 メタデータのURIの取得

まず、スマートウォレットに保管してある、IPFS内のメタデータのURIを取得します。

2 ローカルウォレットのダウンロード

そのURIを元に、暗号化されているローカルウォレットをダウンロードします。

なお、実際のメタデータはこのようになっていました。

3 ローカルウォレットの復号

暗号化されているローカルウォレットを復号化します。

4 ローカルウォレットのインポート

復号化したウォレットインポートします。

なお、コード上は、インポート時に、暗号化されたウォレットパスワードを渡しています。

5 ローカルウォレットとスマートウォレットの接続

最後に、スマートウォレットローカルウォレットを結びつけています。

なお、スマートウォレットは、チェーンfactoryアドレスクライアントIDなどから生成されます。

6 コードを見てみよう

では、コードも見てみましょう。

まずは、ログイン部分を見てみます。

1 ウォレット接続について

こちらの「connectWallet」関数ウォレット接続を行っています。

まずは、ユーザー名パスワード入力されているかを確認しています。

2 スマートウォレットとの接続について

その上で、「connectToSmartWallet」関数で、スマートウォレットと接続します。

ここは後ほど、重点的に扱います。

スマートウォレット署名者を抽出します。

抽出した署名者「singner」に設定しています。

また、読み取りが完了したので、ローディングも「false」に設定しています。

また、こちらでエラーが発生した場合の処理が書かれています。

3 ウォレットファイルについて

次に、「wallet.ts」ファイルを確認します。

こちらが今回のメインで、次の3つの関数が存在します。

① createSmartWallet(スマートウォレットの作成)

② getWalletAddressForUser(アドレスの取得)

③ connectToSmartWallet(スマートウォレットの接続)

4 スマートウォレットの作成について

まずは、「createSmartWallet」関数です。

その名の通り、スマートウォレットを作成しています。

ウォレットをどのチェーン(chain)で作るかどのコントラクトから作るか(FactoryAddress)を設定しています。

5 設定ファイルについて

なお、チェーンFactoryアドレスなどは、「consants.ts」で設定しています。

下のように「factory」アドレス「openEditionContract」もこちらで設定しています。

なお、「openEditionContract」は今回配布する、ERC1155コントラクトアドレスです。

また、スマートウォレットABIも格納しています。

ABIについてご不明な場合は、こちらもご参照ください。

では、戻ります。

スマートウォレット作成時に、ガスレスにするか否かクライアントIDも設定しています。

6 ウォレットアドレスの取得について

次に、「getWalletAddressForUser」関数を確認します。

まずは、thirdwebSDK「getContract」関数を使って、アカウントに接続しています。

参考までに、こちらが公式のドキュメントです。

https://portal.thirdweb.com/typescript/sdk.thirdwebsdk.smartcontract#return-value

接続ができたので、「factory」コントラクト「accountOfUsername」関数を実行します。

これで、ユーザー名に対するアカウントを取得します。

下のように確認すると、イメージが湧きやすいかもしれません。

https://thirdweb.com/base-goerli/0x2637758c0777d58E3278A6022730e997A83d04bF/explorer

7 スマートウォレットの作成について

では、最後に「connectToSmartWallet」関数を見てみましょう。

こちらは少し長いので、章立てにしました。

1 ステータスの表示について

まずは、こちらの「statusCallback」関数を見てみましょう。

オプションとして、引数に設定しているようです。

実際の使用場面では、下のように、「setLoadingStatus」 を設定し、表示しているようです。

2 ユーザー名の確認について

具体的な処理を見ると、下のように、sdkを作成しています。

また、上で定義した「getWalletAddressForUser」関数で「Factrory」コントラクトからユーザー名ウォレットアドレスを取得しています。

その後、「isContractDeployed」関数を使い、そのアドレスがデプロイ済みかを確認します。

さらに、上で定義した、「createSmartWallet」関数スマートウォレットを取得しています。

その上で、ローカルウォレットインスタンスも生成しています。

3 ユーザー名が存在する場合

以下は、「Factory」コントラクト内のユーザー名に対応するコントラクトウォレットデプロイ済みの場合です。

3ー1 オンチェーンデータへのアクセスについて

まずは、「statusCallback」関数で、ユーザー名が存在し、オンチェーンデータにアクセス中の旨を表示します。

続いて、「スマートウォレット」に接続し、メタデータを取得しています。

また、メタデータ内「encryptedWallet」(暗号化済みのウォレット)を取得しています。

なお、メタデータの取得などについては、この辺りが公式の部分です。

https://portal.thirdweb.com/typescript/sdk.contractmetadata#metadata-1

「encryptedWallet」がない場合は、エラーを出します。

3ー2 ローカルウォレットの復号化について

次に、「import」関数を使って、暗号化済みのウォレットそのパスワードからローカルウォレットを作成します。

下のように、「import」秘密鍵などからローカルウォレットを作成する関数のようです。

3ー3 スマートウォレットとの接続について

次に、スマートウォレットローカルウォレットを接続します。

4 ユーザー名が存在しない場合

では、「Factory」コントラクト内にユーザー名が登録されていない場合も見てみましょう。

4ー1 ローカルウォレットの作成

まずは、下のように、ローカルウォレットを作成します。

「generate」関数は、下のように、ランダムなウォレットを作成するときに用いられます。

4ー2 ローカルウォレットの暗号化について

次に、「export」関数を用いて、暗号化を行います。

「strategy」エクスポート方法を示し、「password」を使って暗号化をしているようです。

なお、「export」については、このように記載されています。

4ー3 スマートウォレットとの接続について

続いて、スマートウォレットローカルウォレット接続しています。

4ー4 IPFSへのアップロードについて

次に、IPFS上に、暗号化したローカルウォレット格納します。

下のように、「ユーザー名」「暗号化ウォレット」IPFSアップロードしています。

なお、IPFSへのアップロードについては、この辺りが公式になります。

https://portal.thirdweb.com/typescript/sdk.storage.upload

4ー5 Factoryコントラクトへの登録について

では、最後に、「Factory」コントラクトへの登録部分を見てみましょう。

「smartWallet.execute」で以下に続くトランザクションを実行します。

そして、「Transaction.fromContractInfo」トランザクションのオブジェクトを作成しています。

以下の部分で、スマートウォレットのアドレス署名者などを渡しています。

また、メソッドは「register」で、引数として、ユーザー名メタデータのURIを渡しています。

せっかくなので、「register」関数も見てみましょう。

下のように、「Factory」コントラクトで登録を行なっています。

また、下のように、内部関数で、メタデータも設定しています。

「contractURI」も見ると、下のようになっていました。

「IPFS」を確認すると、下のように名前暗号化されたウォレットの情報を確認することができました。

今回は以上です。

サポートをしていただけたらすごく嬉しいです😄 いただけたサポートを励みに、これからもコツコツ頑張っていきます😊