Web3 の再流行に伴い ethers.js と web3.js を比較する

# Web3 の再流行に伴い ethers.js と web3.js を比較する

Web3 が再び注目を集めるにつれて、イーサリアムベースの DApp (分散型アプリケーション) 開発に使用される主要な JavaScript ライブラリである ethers.js と web3.js への関心も高まっています。どちらのライブラリもイーサリアムブロックチェーンとの相互作用を可能にしますが、特に開発アプローチにおいていくつかの重要な違いがあります。このドキュメントでは、2 つのライブラリを比較し、それぞれの特徴、長所、短所、および開発スタイルの違いを探ります。

---

## web3.js

web3.js は、イーサリアムエコシステムの初期に登場した古いライブラリです。広範囲の機能を提供し、ブロックチェーンとの相互作用のためのすべてのメソッドを単一の `web3` オブジェクトから提供します。主にコールバック関数ベースの API スタイルを使用します。

**長所:**

*   長い歴史を持ち、多くのレガシープロジェクトで使用されています。
*   ethers.js よりも幅広い機能を提供します。

**短所:**

*   比較的大きく重いため、パフォーマンスに影響を与える可能性があります。
*   API がやや複雑で、学習曲線が急です。
*   ethers.js に比べて更新が遅いです。
*   **コールバックベースの API により、非同期コードの記述がやや複雑になる可能性があります。**

---

## ethers.js

ethers.js は、最新の JavaScript 標準に準拠し、より優れた開発エクスペリエンスを提供することに重点を置いた、比較的新しいライブラリです。**簡潔で軽量**であり、モジュール化された API を提供します。特に、`Provider` と `Signer` を明確に分離することで、開発の柔軟性とセキュリティを向上させています。Promise ベースの API を使用して、簡潔な非同期コードを記述できます。

**長所:**

*   簡潔で軽量なため、より高速なパフォーマンスを提供します。
*   `Signer` と `Provider` に分離された明確な API 構造を持っています。
    *   `Signer`: 秘密鍵の管理とトランザクションの署名を担当 (セキュリティ強化)。
    *   `Provider`: ブロックチェーンネットワーク接続の管理を担当 (さまざまなネットワークのサポートが容易)。
*   強化されたセキュリティ機能を提供し、秘密鍵の管理にさらに注意を払っています。
*   活発に開発および保守されており、最新の機能が迅速に反映されます。
*   優れたドキュメントを提供します。
*   Promise ベースの API により、非同期コードの記述が簡潔で可読性が高くなります。

**短所:**

*   比較的新しいライブラリであるため、web3.js ほど多くのレガシープロジェクトで使用されていません。

---

## Provider と Signer: ethers.js と web3.js の重要な概念

ブロックチェーン、特にイーサリアムエコシステムにおいて、Provider と Signer は非常に重要な概念です。これらは、DApp がブロックチェーンと相互作用する方法を定義します。ethers.js と web3.js は、これら 2 つの概念を異なる方法で処理し、これが開発アプローチの重要な違いにつながります。

---

## Provider: ブロックチェーンへの読み取り専用接続

Provider は、ブロックチェーンネットワークへの読み取り専用アクセスを提供します。図書館の司書のようなものです。本 (ブロックチェーンデータ) を読んで情報を取得することはできますが、本に内容を追加したり修正したりすることはできません。

**主な機能:**

*   ブロック情報の取得 (ブロック高、タイムスタンプなど)
*   トランザクション情報の取得
*   アカウント残高の確認
*   スマートコントラクトの読み取り専用関数 (view functions) の呼び出し
*   ネットワーク状態の確認

---

## Signer: トランザクションの署名と実行

Signer は、秘密鍵を使用してトランザクションに署名し、ブロックチェーンに送信する機能を提供します。印鑑を持っている人のようなものです。印鑑を押して初めて文書 (トランザクション) が効力を発揮するように、Signer はトランザクションに署名してブロックチェーンに記録できるようにします。

**主な機能:**

*   秘密鍵の管理 (安全な保存とアクセス)
*   トランザクションの作成と署名
*   スマートコントラクトの状態変更関数 (state-changing functions) の呼び出し
*   イーサの送信

---

## ethers.js における Provider と Signer

ethers.js は、Provider と Signer を明確に分離して API を構成します。これにより、開発の柔軟性とセキュリティが大幅に向上します。

**Provider:** `ethers.providers` モジュールを通じてさまざまな Provider を提供します。Infura、Alchemy、Etherscan などのサービスを利用するか、直接 RPC URL を使用して接続できます。

*   例: `const provider = new ethers.providers.InfuraProvider("mainnet", "YOUR_INFURA_PROJECT_ID");`

**Signer:** `ethers.Wallet` クラスを使用して秘密鍵を管理するか、MetaMask などのウォレットと接続して使用できます。

*   例 (秘密鍵の使用): `const wallet = new ethers.Wallet("YOUR_PRIVATE_KEY", provider);`
*   例 (MetaMask の接続): `const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner();`

ethers.js で Provider と Signer を分離することにより、次の利点が得られます。

*   **セキュリティ強化:** 秘密鍵を直接管理せずに、ウォレットを通じて安全に管理できます。
*   **柔軟性向上:** さまざまな Provider を簡単に切り替えて使用できます。
*   **テスト容易:** テスト環境でモック Signer を使用してテストを実行できます。

---

## web3.js における Provider と Signer

web3.js は、Provider と Signer を明確に分離しません。`web3.eth.accounts` を通じてアカウントを管理し、トランザクションに署名しますが、ethers.js ほど明確に分離されていません。

**Provider:** `web3.setProvider()` を使用して Provider を設定します。

*   例: `const web3 = new Web3(new Web3.providers.HttpProvider('YOUR_RPC_URL'));`

**Signer:** `web3.eth.accounts.signTransaction()` を使用してトランザクションに署名します。この過程で、秘密鍵を直接使用する必要がある場合が多く、セキュリティ上の脆弱性が発生する可能性があります。MetaMask などのウォレットを使用することもできますが、ethers.js ほど統合がスムーズではありません。

---

## まとめ比較

| 特徴        | ethers.js                                       | web3.js                                       |
| ----------- | --------------------------------------------- | --------------------------------------------- |
| Provider    | 明確に分離、さまざまな Provider をサポート (Infura、Alchemy など) | `web3.setProvider()` で設定                       |
| Signer      | 明確に分離、Wallet クラス、ウォレット連携が容易         | `web3.eth.accounts` を通じて管理、秘密鍵の直接管理が必要になる場合がある |
| セキュリティ | 秘密鍵の安全な管理、セキュリティ強化                      | 秘密鍵の露出リスクが存在                           |
| 柔軟性      | 高い柔軟性、さまざまな Provider およびウォレットをサポート      | 比較的柔軟性が低い                           |

ethers.js は、Provider と Signer を明確に分離することにより、開発の柔軟性、セキュリティ、および利便性を大幅に向上させました。一方、web3.js はこのような分離が明確ではないため、開発方法がやや複雑でセキュリティ上の脆弱性を持つ可能性があります。したがって、新しい Web3 プロジェクトを開始する場合は、ethers.js を使用することが一般的に推奨されます。

---

## 開発スタイルの違い

| 特徴          | web3.js                                                              | ethers.js                                                                 |
| ------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| API スタイル     | 単一の `web3` オブジェクト、コールバックベース                                                  | `Signer` と `Provider` の分離、Promise ベース                       |
| 非同期処理    | コールバック関数を使用して非同期コードを処理するため、コードの可読性が低下する可能性がある | Promise を使用して非同期コードを簡潔かつ明確に記述可能 (async/await の活用が容易) |
| 秘密鍵管理   | 直接的な秘密鍵管理が必要 (セキュリティの脆弱性が発生する可能性が存在)                        | `Signer` を通じて抽象化された秘密鍵管理 (セキュリティ強化)                             |
| ネットワーク接続 | `web3.setProvider()` を使用して接続を設定                                  | `Provider` を通じてさまざまなネットワークと接続方法をサポート (Infura、Alchemy など)         |