5章 ウォレット
広義のウォレット
UI を持ったアプリケーション
鍵とアドレスの管理、
残高の追跡、
トランザクションの作成と署名、
…ができたりする
狭義のウォレット
鍵を管理するシステム
この章では「秘密鍵を保存するコンテナ」「鍵を管理するシステム」としてウォレットを解説していく
5.1 ウォレット技術の概要
>ウォレット設計における重要な検討事項は、利便性とプライバシーのバランスをとることです。
>イーサリアムに関するよくある間違いは、「イーサリアムのウォレットはイーサやトークンを保管している」というものです。非常に厳密に言えば、実際にはウォレットは鍵しか保管していません。イーサや他のトークンは、イーサリアムブロックチェーンに記録されているのです。
非決定性ウォレット (nondeterministic wallet)
Just a Bunch of Keys (鍵束)
決定性ウォレット (deterministic wallet)
シードと呼ばれるひとつのマスター鍵から生成される
ウォレット内の鍵は互いに関連している
シードがあれば鍵を再生成できる
決定性ウォレットのシード、単語のリストにエンコードして保存する
5.1.1 非決定性(ランダム)ウォレット
>最初のイーサリアムウォレットはイーサリアムの先行販売のために作られ、それぞれのウォレットのファイルにはランダムに生成された単一の秘密鍵が格納されていました。このような「古いスタイル」の非決定性ウォレットは多くの点で不備や欠点があり、決定性ウォレットで置き換えられつつあります。
使い捨てっぽさ
ばんばんアドレスを生成する
管理が面倒
キーストアファイル
JSON 形式
KDF を使用
ブルートフォース攻撃、辞書攻撃、レインボーテーブル攻撃に耐性がある
ハッシュ関数を 262,144 回適用
>非決定性ウォレットの使用は、単なるテスト以外の用途では推奨できません。
5.1.2 決定性(シード)ウォレット
シード (seeded)
インデックス番号やチェーンコードと組み合わせて秘密鍵を生成する
シードがあれば生成したすべての鍵を復元できる
だからシードが超大事、これを厳重に管理する
5.1.3 階層的決定性(HD)ウォレット(BIP-32/BIP-44)
階層的決定性 (Hierarchical Deterministic : HD) ウォレット
ツリー構造で管理することで使い分けしやすい
5.1.4 シードとニーモニックコード(BIP-39)
ニーモニック (mnemonic)
正しい順序でまとめると秘密鍵を一意に再生成できる一連の単語
>wolf juice proud gown wool unfair wall cliff insect more detail hub
こんな感じ
紙にメモしたときにどこか 1 文字くらい間違えていても人間が復元できる
5.2 ウォレットのベストプラクティス
>ほとんどのブロックチェーンプラットフォームとそれらの暗号通貨のデファクトスタンダードになっています。
プラットフォームをこえてを標準的になっているの、おもしろい
5.2.1 ニーモニックコードワード(BIP-39)
ただし
BIP-39 はニーモニック標準の実装方式のひとつでしかない
5.2.1.1 ニーモニックワードの生成
1. 128 から 256 ビットの暗号論的にランダムな文字列 S を作成する
2. SHA-256 で S のハッシュ値をとり、そのハッシュ値の先頭 (S のビット長 ÷ 32) ビットから S のチェックサムを生成する
3. このチェックサムをランダムな文字列の最後に追加する
4. 文字列とチェックサムの連結を 11 ビットずつに分割する
5. 各 11 ビットの値を、あらかじめ定義された 2,048 語を持つ辞書の中の単語にマッピングする
6. 順序を維持しながら、一連の単語からニーモニックコードを作成する
5.2.1.2 ニーモニックからシードの生成
7. 鍵ストレッチ関数 PBKDF2 の最初の引数は、手順 6 で生成したニーモニックである
8. 鍵ストレッチ関数 PBKDF2 の 2 つ目の引数はソルトである。このソルトは、文字列定数「mnemonic」とユーザーが提供するオプションのパスフレーズの連結で構成される
9. PBKDF2 は、HMAC-SHA512 アルゴリズムで 2,048 ラウンドのハッシュ化を行い、ニーモニック とソルトのパラメータを拡張し、最終出力として 512 ビットの値を生成する。その 512 ビットの値がシードとなる
5.2.1.3 BIP-39のオプションのパスフレーズ
シードの導出にオプションのパスフレーズを使用できる
文字列を与えれば、それを用いてシードが生成される
便利だけど、パスフレーズを忘れてしまったり持ち主が死んでしまったりすると誰もアクセスできなくなる
5.2.1.4 ニーモニックコードとの連携
BIP-39 を提案した SatoshiLabs チームによって作られたリファレンス実装 (Python 実装)
ノードとブラウザ向け軽量 JavaScript イーサリアムウォレット (BIP-39 準拠)
ビットコイン BIP-39 の JavaScript 実装
決定性鍵生成のためのニーモニックコード
5.2.2 シードからのHDウォレット生成
拡張鍵 (extended keys)
強化鍵 (hardened keys)
5.2.3 HDウォレット(BIP-32)とPath(BIP-43/44)
5.2.3.1 拡張公開鍵と拡張秘密鍵
拡張秘密鍵 (extended private key)
xprv
プレフィクス
拡張公開鍵 (extended public key)
xpub
プレフィクス
>HD ウォレットには、秘密鍵を使わずに親の公開鍵から子の公開鍵を生成できるという、とても有用な特徴があります。このことから、子の公開鍵を生成する方法が 2 種類あることがわかります。子の秘密鍵から直接生成するか、または親の公開鍵から生成するかです。
>この仕組みにより、拡張公開鍵のコピーを持っているものの秘密鍵は一切持たないサーバーやアプリケーションにおいて、非常に安全に公開鍵のみがデプロイできます。
>この方法の応用として一般的なのは、e コマースを提供する Web サーバーに拡張公開鍵をインストールすることです。この Web サーバーは、公開鍵の導出関数を使って、すべてのトランザクションのために新しいイーサリアムアドレスを生成することができます(たとえば顧客のショッピングカートごとに)。
>もう 1 つの一般的な応用としては、コールドストレージもしくはハードウェアウォレットを用いることです。この応用においては、拡張秘密鍵はハードウェアウォレットに保管されますが、拡張公開鍵はオンラインで保管することができます。
5.2.3.2 強化子公開鍵の導出
>親チェーンコードとともに、1 つの子秘密鍵が漏洩してしまえば、すべての子の秘密鍵が明らかになってしまいます。さらに悪いことに、親チェーンコードとともに子秘密鍵を使うことで、親秘密鍵を推測することもできてしまいます。
>このリスクに対処するため、HD ウォレットは、親の公開鍵と子のチェーンコードの関係を「破壊」する強化導出(hardend derivation)と呼ばれる鍵導出関数を代わりに使用します。
5.2.3.3 通常の導出および強化導出のインデックス
>通常(非強化)の鍵導出関数によって導出された鍵と強化導出関数によって導出された鍵とを簡単に区別するために、このインデックス番号は 2つの範囲に分割されています。
0 〜 (2^31 - 1)
通常導出
2^31 〜 (2^32 - 1)
強化導出
5.2.3.4 HD ウォレット鍵識別子(path)
URL におけるパス表現のように、HD ウォレットのパスってのもあるとのこと
5.2.3.5 HD ウォレットのツリー構造をたどる
>HD ウォレットのツリー構造はとても柔軟性があります。しかし、その柔軟性の裏返しとして、際限のない複雑さが挙げられます。それぞれの親拡張鍵は 40 億個の子鍵を持つことができます。そのうちの 20 億個は普通の子鍵で、そのほかの 20 億個は強化導出された子鍵です。
べらぼうに多い!
>BIP-44 では、構造を次の 5 つの定義済みの階層構造で構成しています。
m /purpose'/ coin_type' / account'/ change / address_index
イーサリアム m/44'/60'
〜
イーサリアムクラシック m/44'/61'
〜
ビットコイン m/44'/0'
〜
すべての通貨のテストネット m/44'/1'
〜
5.3 まとめ
終盤、だいぶ理解に苦しんだ…!
次章!