[ERC2386] Ethereum 2のHDウォレット保存形式の仕組みを理解しよう！

# はじめに

『DApps開発入門』という本や色々記事を書いているかるでねです。

https://amzn.asia/d/gxvJ0Pw

今回は、Ethereum 2.0における階層的決定性（HD）ウォレットの情報を安全かつ互換性のある形式で保存・管理するための「walletstore」の仕組みを提案している**ERC2386**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-2386

他にも様々なEIPについてまとめています。

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

# 概要

**ERC2386**は、Ethereum 2.0における階層的決定性（HD: Hierarchical Deterministic）ウォレットの定義情報を保存・取得するためのJSON形式を標準化する提案をしています。

これにより、異なるウォレットソフトウェア間でのウォレット情報の互換性と移行のしやすさが向上します。

:::note info
Ethereum 2.0とは、Ethereumネットワークの次世代バージョンとして計画された大規模なアップグレードの総称です。
正式には「The Merge（ザ・マージ）」と呼ばれています。

### 背景

もともとEthereumはProof of Workという仕組みで動作していましたが、これはマイニングによる高い電力消費やスケーラビリティの制限といった問題がありました。

### Ethereum 2.0の主な特徴

#### Proof of Stake（PoS）への移行

PoWからPoSへの移行です。
PoSでは、ETH（イーサ）をステーキングすることでネットワークの運営（ブロック提案や検証）に参加できます。
大幅な電力消費の削減とネットワークの安全性・効率性の向上が実現されました。

#### The Beacon Chain（ビーコンチェーン）

Ethereum 2.0の最初のフェーズでは、PoSネットワークの基盤となる「ビーコンチェーン」が2020年にローンチされました。
これはEthereumの新しい「コンセンサスレイヤー」であり、PoSによるバリデーター管理やランダム性の提供などを担っていました。

#### The Merge（ザ・マージ）

2022年9月に実施されたThe Merge（統合）によって、Ethereumの従来の実行環境（旧PoWチェーン）とビーコンチェーンが統合され、完全にPoSに移行しました。
これにより、「Ethereum 2.0」への移行は技術的には完了したと言えます。
:::

Ethereumでは、**EIP2335**という秘密鍵を定義する「キーストア（keystore）」の概念がすでに存在します。

**ERC2386**では、これに加えて「ウォレットストア（walletstore）」という新たな概念を導入します。

ウォレットストアとは、HDウォレットの定義と、それに含まれる鍵の生成方法（例えば、どのような派生パスを使うか）を記述した情報のまとまりです。

# 動機

HDウォレットは、1つのシード（秘密の乱数値）から複数の鍵を派生させる仕組みを持ちます。
このとき、以下の課題があります。

* 鍵を新たに作成するにはシードへのアクセスが必要ですが、このシードは秘密鍵と同等の厳重な保護が求められます。
* 鍵の派生に使用するパス情報（たとえばm/44'/60'/0'/0/0など）は、一意性を保ち重複を避けるためにも保存しておく必要があります。

これらの情報（シード、パス、メタデータ）を標準的な形式で保存・管理できるようにすることで、以下の利点が得られます。

* 異なるウォレットアプリケーション間でのデータ移行が容易になる
* 鍵の重複作成や誤った派生のリスクが減少する
* ウォレット作成や管理の一貫性とセキュリティが向上する

このように、ウォレットストアを標準化することは、安全性と利便性の両立を図る上で重要です。

# 仕様

### `uuid`

`uuid`は、RFC4122に準拠したランダムに生成されたタイプ4 UUIDで、ウォレットを一意に識別するための識別子として使用されます。
必須項目で、文字列型である必要があります。

### `name`

`name`は、ユーザーがウォレットを識別しやすくするためのUTF-8文字列です。
先頭にアンダースコア（`_`）を付けてはいけないです。
必須項目で、文字列型である必要があります。

### `version`

`version`は、walletstoreのバージョン番号を表します。
現在の仕様では「1」である必要があります。
必須項目で、数値型である必要があります。

### `type`

`type`はウォレットの種類を表します。
階層的決定性ウォレットを示す場合、値は `"hierarchical deterministic"` である必要があります。
必須項目で、文字列型である必要があります。

### `crypto`

`crypto`は秘密情報の安全な保存に使用される構造です。
HDウォレットの場合は、個々の秘密鍵を派生させる「シード（seed）」を格納します。
この構造は**EIP2335**で定義された形式に従います。
オブジェクト型で、内部に `kdf`（鍵導出関数）、`checksum`（整合性検証）、`cipher`（暗号化方式）を含むモジュール構造を持ちます。
必須項目です。

### `nextaccount`

`nextaccount`は、新しい秘密鍵を作成する際に使用されるインデックス値です。
パス `m/12381/60/<index>/0` における `<index>` に相当し、**EIP2334**に準拠します。
整数である必要があります。
ウォレットの種類に応じて必要になるため、多くのHDウォレットでは必須項目です。

### JSONスキーマ定義

ルートオブジェクト `Walletstore` は、以下のプロパティを持ちます。

* `uuid`（UUID形式の文字列）
* `name`（文字列）
* `version`（整数）
* `type`（文字列）
* `crypto`（暗号情報を含むオブジェクト）
* `nextaccount`（整数）

`crypto` は次の3要素から構成されます。

* `kdf`（鍵導出関数モジュール）
* `checksum`（チェックサム検証モジュール）
* `cipher`（暗号化モジュール）

* 各モジュール（`Module`）には以下が含まれます。

* `function`: 関数名（文字列）
* `params`: パラメータ（オブジェクト）
* `message`: メッセージ（文字列）

`Walletstore` オブジェクトは以下の6つの要素が必須です。

* `uuid`
* `name`
* `version`
* `type`
* `crypto`
* `nextaccount`

この構造により、Ethereum 2のHDウォレットに必要な情報を一貫して安全に保存・移行・利用することが可能になります。

# 補足

「walletstore」の標準化は、既に存在する「keystore（秘密鍵ストレージ）」の標準と同様に、ウォレット間の互換性を高めるために重要です。

**ERC2386**に従うことで、異なるウォレットソフトウェア間でのウォレットや鍵の移行・交換が容易になり、ユーザーにとってはより柔軟で安全な鍵管理体験が提供されます。
特にHDウォレットのように複数の鍵を扱う仕組みにおいては、鍵の派生ルールやシードの保存形式を統一することが重要です。

# テストケース

**ERC2386**には、正しい実装を検証するためのテストベクトルが用意されています。
以下は、ウォレットストアに保存された内容の具体例です。

#### テスト条件

* パスワード: `'testpassword'`
* シード（秘密情報）: `0x147addc7ec981eb2715a22603813271cce540e0b7f577126011eb06249d9227c`

#### JSON形式のwalletstore

```json
{
  "crypto": {
    "checksum": {
      "function": "sha256",
      "message": "8bdadea203eeaf8f23c96137af176ded4b098773410634727bd81c4e8f7f1021",
      "params": {}
    },
    "cipher": {
      "function": "aes-128-ctr",
      "message": "7f8211b88dfb8694bac7de3fa32f5f84d0a30f15563358133cda3b287e0f3f4a",
      "params": {
        "iv": "9476702ab99beff3e8012eff49ffb60d"
      }
    },
    "kdf": {
      "function": "pbkdf2",
      "message": "",
      "params": {
        "c": 16,
        "dklen": 32,
        "prf": "hmac-sha256",
        "salt": "dd35b0c08ebb672fe18832120a55cb8098f428306bf5820f5486b514f61eb712"
      }
    }
  },
  "name": "Test wallet 2",
  "nextaccount": 0,
  "type": "hierarchical deterministic",
  "uuid": "b74559b8-ed56-4841-b25c-dba1b7c9d9d5",
  "version": 1
}
```

* `crypto`: シードを暗号化した情報を格納します。
  * `kdf`: パスワードから鍵を導出する設定（ここではPBKDF2方式）
  * `cipher`: AES-128-CTRによる暗号化と初期化ベクトル（iv）
  * `checksum`: 暗号文が改ざんされていないか確認するためのSHA-256チェックサム
* `name`: ユーザーが設定したウォレット名（"Test wallet 2"）
* `nextaccount`: 次に使用されるHDウォレットインデックス（ここでは0）
* `type`: HDウォレットを表す文字列（"hierarchical deterministic"）
* `uuid`: ウォレットの識別子として使われるUUID
* `version`: このwalletstoreフォーマットのバージョン（1）

このテストケースを用いることで、walletstore実装の正当性や互換性を確認できます。
開発者はこの形式に従ってウォレットの保存・読み出し機能を実装することで、他のウォレットソフトとのシームレスな統合が可能になります。

# 参考実装

階層的決定性ウォレット（HDウォレット）のwalletstore仕様に準拠した実装は、Go言語で提供されています。

以下のリポジトリで確認できます。

* [https://github.com/wealdtech/go-eth2-wallet-hd](https://github.com/wealdtech/go-eth2-wallet-hd)

このライブラリでは、Ethereum 2.0の鍵管理要件（**EIP2333**, **EIP2334**, **EIP2335**など）に基づいた、HDウォレットの生成・管理が可能です。
開発者はこの実装を利用することで、walletstore仕様に準拠したアプリケーションやツールを構築できます。

# セキュリティ

## シードの重要性と暗号化

HDウォレットでは、すべての鍵が共通のシード（seed）から導出されます。
このため、walletstore内に保存されているシードの暗号が解読されると、同じパスから生成された全ての秘密鍵が漏洩するリスクがあります。

つまり、HDウォレットにおいては、個々の鍵の安全性ではなくシード全体の安全性が極めて重要です。

## 運用設計における選択肢

HDウォレットは柔軟な運用設計が可能で、以下のような選択肢があります。

* **walletstoreのみを使用**
    * シードから毎回鍵を導出する運用です。
    * この方法では、復号が1回で済むため、より強固なパスフレーズを使用しても利便性を損ないません。
* **keystoreのみを使用**
    * シードから事前に個別のkeystoreを生成し、それを使用する方法です。
    * この場合、仮に1つのkeystoreが流出しても他の鍵には影響しません。

## 高セキュリティな運用例

安全性を最大限に高めたい場合、以下のような構成が推奨されます。

* **オフライン環境でwalletstoreを管理・鍵を生成**
* **生成されたkeystoreファイルのみをオンライン環境に転送し署名に使用**

この運用により、シードがネットワークに接続されることなく保護され、攻撃対象が個別のkeystoreに限定されるため、リスクが大幅に軽減されます。

# 引用

Jim McDonald <Jim@mcdee.net>, "ERC-2386: Ethereum 2 Hierarchical Deterministic Walletstore [DRAFT]," Ethereum Improvement Proposals, no. 2386, November 2019. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2386.

# 最後に

今回は「Ethereum 2.0における階層的決定性（HD）ウォレットの情報を安全かつ互換性のある形式で保存・管理するための「walletstore」の仕組みを提案している**ERC2386**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4