ウォレットを作成しよう
👛 HD ウォレットについて
このセクションでは、HDウォレットと呼ばれる種類のウォレットを構築します。HDとは階層的決定性(Hierarchy Deterministic)の略です。
これは簡単に言うと、1つのシードからマスタキーとなる秘密鍵を生成し、そこから木構造のような階層的に複数の派生秘密鍵と派生公開鍵及びアドレスを生成します。
最初の秘密鍵は、シードと呼ばれるランダムな文字列から作ります。その後は作った秘密鍵をシードとして新たな秘密鍵を階層的に作ることができます。
シードは覚えにくい文字列ですので、シードから「シードフレーズ」や「リカバリーフレーズ」などと呼ばれる、12個から24個の単語に変換して記録しておく方法が使われています。
参考: 暗号資産におけるウォレットとは ② 〜HD ウォレット編〜
⏬ BIP39 ライブラリを追加する
ここからは、components/GenerateWallet/index.js
ファイルを更新してGenerateWalletコンポーネントを作成していきます。
フレーズを 生成するには、決定論的なキーのフレーズ生成の標準を設定したBIP39仕様
を満たす外部ライブラリを活用する必要があります。
JavaScriptには BIP39
と呼ばれるライブラリがあるのでこれを利用していきましょう。
BIP39
ライブラリは、フレーズを生成し、それをSolanaウォレットキーの生成に必要なシードに変換するために必要な機能を提供してくれます。
BIP39
ライブラリをnpm install
する
npm install bip39@^3.1.0
- importする
ライブラリのインストールが完了したら、 ファイルの先頭でライブラリを読み込みましょう。
import * as bip39 from "bip39";
🏭 ニーモニックフレーズを生成する
BIP39
にはニーモニックフレーズを生成するためのメソッドgenerateMnemonic
があります。これを呼び出し、変数に格納してみましょう。
const generatedMnemonic = bip39.generateMnemonic();
これにより、ユーザーがメモして安全に保管できるように、ニーモニックフレーズを設定し、表示することができます。フレーズそれ自体で、その所持者はそのフレーズに一致するアカウントにアクセスすることが可能になります。
🔐 キーペアとシード
ブロックチェーン上のアカウントに接続する前に、このニーモニックフレーズをブロックチェーンが理解できる形に変換する必要があります。ニーモニックフレーズは、長くて古風な数字を、より人間に近い形に変換する抽象的なものなのです。
@solana/web3.js
ライブラリがキーペアオブジェクトを生成するためにこのフレーズを使用できるように、フレーズをバイトに変換する必要があります。キーペアは、データを暗号化できる公開キーとデータを復号化できる秘密キーからなるウォレットアカウントとなります。
@solana/web3.js
ドキュメントを確認すると、Keypair
クラスが "An account keypair used for signing transactions." として定義されていることがわかります。これはまさに、ニーモニックフレーズを使用して生成する必要があるものです。
またドキュメントを読むと、 Keypair
クラスには、32バイトのシードからKeypair
を生成するfromSeed
メソッドがあることがわかります。そして、シードはUint8Array
である必要があります。つまり、ニーモニックフレーズをUint8Array
に変換する方法が必要だということです。
BIP39
ライブラリに戻ると、mnemonicToSeedSync(mnemonic)
というメソッドがあり、16進数のリストのようなBuffer
オブジェクトが返されます。このメソッドを実行し、生成したニーモニックを渡すことで、テストすることができます。
const seed = bip39.mnemonicToSeedSync(generatedMnemonic);
console.log(seed);
// > Uint8Array(64)
ゴールまでもう少しです!🥭
Keypair
クラスは32バイトのUint8Array
を必要としますが、現在は64バイトのUint8Array
を取得しています。シードをsliceして、最初の32バイトだけを保持するようにしましょう。
const seed = bip39.mnemonicToSeedSync(generatedMnemonic).slice(0, 32);
console.log(seed);
// > Uint8Array(32)
正しい形式のシードがあれば、Keypair
のfromSeed
メソッドを使って、アカウントのキーペアを生成することができます。
const newAccount = Keypair.fromSeed(new Uint8Array(seed));
console.log("newAccount", newAccount.publicKey.toString());
// > ランダムな文字列