メインコンテンツへスキップ

WebSocketを利用する

AlchemyWebSocketsクエリJavaScript
初級
Elan Halpern
Alchemy ドキュメント(opens in a new tab)
2020年12月1日
10 分の読書 minute read

このガイドでは、初級者向けに、WebSocket と Alchemy を使ってイーサリアムブロックチェーンにリクエストを送信する方法を学びます。

(opens in a new tab)WebSocket と HTTP の比較

HTTP とは異なり、WebSocket では特定の情報が必要な場合にリクエストを継続的に実行する必要はありません。 WebSocket では、正しく設定されていれば、ネットワーク接続が継続され、変更をリッスンすることができます。

どのネットワーク接続でも同様ですが、WebSocket が中断なしに永続的にオープンであると想定すべきではありませんが、手動で切断された接続に適切に対処し、再接続するのは手間がかかる場合があります。 WebSocket のもう一つの欠点は、応答にはエラーメッセージのみが含まれ、HTTP ステータスコードを取得できないという点です。

Alchemy Web3(opens in a new tab)を利用することで、WebSocket の接続失敗に自動的に対応し、設定なしでリトライさせることができます。

さっそく試してましょう

WebSocket をテストする最も簡単な方法は、wscat(opens in a new tab)などの WebSocket リクエストを行うためのコマンドラインツールをインストールすることです。 wscat を使って、次のようにリクエストを送ります:

注意:Alchemy アカウントをお持ちの場合は、 demoをあなたの API キーに置き換えてください。 こちら(opens in a new tab)で、Alchemy の無料アカウントを作成できます。

1$ wscat -c wss://eth-mainnet.ws.alchemyapi.io/ws/demo
2
3> {"jsonrpc": "2.0", "id": 0, "method": "eth_gasPrice"}
4
5< {"jsonrpc": "2.0", "result": "0xb2d05e00", "id": 0}
6

WebSocket の使用方法

まず、アプリに WebSocket の URL を入力して WebSocket を開きます。 アプリの WebSocket URL を確認するには、ダッシュボード(opens in a new tab)の App ページを開き、「View Key」をクリックしてください。 アプリの WebSocket 用 URL は HTTP リクエスト用の URL とは異なっており、両方とも「View Key」で確認できる点に注意してください。

AlchemyのダッシュボードでWebSocket URLを確認できる場所

Alchemy API レファレンス(opens in a new tab)に記載されている API は、いずれも WebSocket 経由で使用可能です。 これには、HTTP POST リクエストの本文として送信する場合と同じペイロードを使用しますが、このペイロードを WebSocket 経由で送信します。

Web3 での WebSocket 使用方法

Web3 のようなクライアント向けライブラリを使用する場合、WebSocket への移行は簡単です。 Web3 クライアントのインスタンスを作成する際に、HTTP URL ではなく WebSocket URL を渡すだけでよいです。 以下の例をご覧ください:

1const web3 = new Web3("wss://eth-mainnet.ws.alchemyapi.io/ws/your-api-key")
2
3web3.eth.getBlockNumber().then(console.log) // -> 7946893
コピー

API を講読する

WebSocket 経由で接続する場合、eth_subscribeおよびeth_unsubscribeという 2 つの追加メソッドを使用できます。 これらのメソッドを使用することで、特定のイベントをリッスンし、すぐに通知を受け取ることができるようになります。

eth_subscribe

特定のイベントを対象とする新規のサブスクリプションを作成しましょう。 eth_subscribeの詳細については、こちら(opens in a new tab)をご覧ください。

パラメータ

  1. サブスクリプションの種類
  2. オプションのパラメータ

最初の引数では、リッスンするイベントのタイプを指定します。 2 番目の引数では、最初の引数に依存したオプションを追加します。 以下では、説明タイプ、タイプ別のオプション、およびイベントのペイロードについて説明します。

戻り値

サブスクリプション ID:この ID は、受信したすべてのイベントに付与されるもので、eth_unsubscribeを使用してサブスクリプションを取り消すする際にも使用します。

サブスクリプション関連のイベント

サブスクリプションが有効である場合、以下のフィールドを含むオブジェクトであるイベントが送信されます:

  • jsonrpc: 常に「2.0」です。
  • method: 常に「eth_subscription」です。
  • params:以下のフィールドを含むオブジェクトです:
    • subscription:このサブスクリプションを作成したeth_subscriptionの呼び出しが返したサブスクリプション ID です。
    • result:サブスクリプションのタイプによって内容が異なるオブジェクトです。

サブスクリプションのタイプ

  1. alchemy_newFullPendingTransactions

保留状態に追加されたすべてのトランザクションにつき、トランザクション情報を返します。 このサブスクリプションタイプは保留中のトランザクションを講読するため、Web3 の標準的な呼び出しであるweb3.eth.subscribe("pendingTransactions")と似ていますが、トランザクションのハッシュだけでなくトランザクションの完全な情報を発行するという点が異なります。

例:

1> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["alchemy_newFullPendingTransactions"]}
2
3< {"id":1,"result":"0x9a52eeddc2b289f985c0e23a7d8427c8","jsonrpc":"2.0"}
4< {
5 "jsonrpc":"2.0",
6 "method":"eth_subscription",
7 "params":{
8 "result":{
9 "blockHash":null,
10 "blockNumber":null,
11 "from":"0xa36452fc31f6f482ad823cd1cf5515177d57667f",
12 "gas":"0x1adb0",
13 "gasPrice":"0x7735c4d40",
14 "hash":"0x50bff0736c713458c92dd1848d12f3354149be1363123dae35e94e0f2a9d56bf",
15"input":"0xa9059cbb0000000000000000000000000d0707963952f2fba59dd06f2b425ace40b492fe0000000000000000000000000000000000000000000015b1111266cfca100000",
16 "nonce":"0x0",
17 "to":"0xea38eaa3c86c8f9b751533ba2e562deb9acded40",
18 "transactionIndex":null,
19 "value":"0x0",
20 "v":"0x26",
21 "r":"0x195c2c1ed126088e12d290aa93541677d3e3b1d10f137e11f86b1b9227f01e3b",
22 "s":"0x60fc4edbf1527832a2a36dbc1e63ed6193a6eee654472fbebbf88ef1750b5344"},
23 "subscription":"0x9a52eeddc2b289f985c0e23a7d8427c8"
24 }
25 }
26
すべて表示
コピー
  1. newHeads

ブロックチェーンの再編成時も含む、ブロックチェーンに新たなヘッダーが追加された際に常にイベントを発行します。

このサブスクリプションでは、ブロックチェーンの再編成が実行された場合に、新たなチェーンに対するすべてのヘッダーを含むイベントが発行されます。 特に、同じ高さを持つ複数のヘッダーが発行される場合があるため、このような状況が発生した場合は、より後ろのヘッダーを再編成後の適切なヘッダーと見なす必要があります。

例:

1> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["newHeads"]}
2
3< {"jsonrpc":"2.0","id":2,"result":"0x9ce59a13059e417087c02d3236a0b1cc"}
4< {
5 "jsonrpc": "2.0",
6 "method": "eth_subscription",
7 "params": {
8 "result": {
9 "extraData": "0xd983010305844765746887676f312e342e328777696e646f7773",
10 "gasLimit": "0x47e7c4",
11 "gasUsed": "0x38658",
12 "logsBloom":
13"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
14 "nonce": "0x084149998194cc5f",
15 "number": "0x1348c9",
16 "parentHash": "0x7736fab79e05dc611604d22470dadad26f56fe494421b5b333de816ce1f25701",
17 "receiptRoot": "0x2fab35823ad00c7bb388595cb46652fe7886e00660a01e867824d3dceb1c8d36",
18 "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
19 "stateRoot": "0xb3346685172db67de536d8765c43c31009d0eb3bd9c501c9be3229203f15f378",
20 "timestamp": "0x56ffeff8",
21 "transactionsRoot": "0x0167ffa60e3ebc0b080cdb95f7c0087dd6c0e61413140e39d94d3468d7c9689f"
22 },
23 "subscription": "0x9ce59a13059e417087c02d3236a0b1cc"
24 }
25}
26
すべて表示
コピー
  1. ログ類

新たに追加されたブロックのうち、指定したフィルター条件に合致した部分のログを発行します。

チェーンの再構成が発生した場合、removedのプロパティをtrueに設定すれば、古いチェーン上のブロックに含まれたログも再度発行されます。 さらに新しいチェーン上のブロックに含まれるログも発行されるため、再編成時には、同一のトランザクションのログが複数回表示される場合があります。

パラメータ

  1. 以下のフィールドを持つオブジェクトです:
    • address(オプション):アドレスを表す文字列あるいは、そのような文字列の配列です。
      • これらのアドレスのいずれかで作成したログのみが発行されます。
    • topics:トピック指定子の配列です。
      • トピック指定子は、null、トピックを表す文字列、または文字列の配列のいずれかです。
      • 配列においてnullではない各位置は、当該の位置において与えられたトピックのひとつを持つユーザーだけにログを発行します。

トピック仕様の例:

  • []:すべてのトピックを許可します。
  • [A]:最初の位置が A である(その後の位置については条件なし)。
  • [null, B]:最初の位置は条件なしで、かつ 2 番目の位置が B である(その後の位置については条件なし)。
  • [A, B]:最初の位置が A であり、2 番目の位置が B (その後の位置については条件なし) 。
  • [[A, B], [A, B]]: 最初の位置が (A または B)、かつ 2 番目の位置が (A または B) (その後の位置については条件なし)

例:

1> {"jsonrpc": "2.0", "id": 1, "method": "eth_subscribe", "params": ["logs", {"address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd", "topics": ["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"]}]}
2
3< {"jsonrpc":"2.0","id":2,"result":"0x4a8a4c0517381924f9838102c5a4dcb7"}
4< {
5 "jsonrpc": "2.0",
6 "method": "eth_subscription",
7 "params": {
8 "subscription": "0x4a8a4c0517381924f9838102c5a4dcb7",
9 "result": {
10 "address": "0x8320fe7702b96808f7bbc0d4a888ed1468216cfd",
11 "blockHash": "0x61cdb2a09ab99abf791d474f20c2ea89bf8de2923a2d42bb49944c8c993cbf04",
12 "blockNumber": "0x29e87",
13 "data": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000003",
14 "logIndex":"0x0",
15 "topics":["0xd78a0cb8bb633d06981248b816e7bd33c2a35a6089241d099fa519e361cab902"],
16 "transactionHash": "0xe044554a0a55067caafd07f8020ab9f2af60bdfe337e395ecd84b4877a3d1ab4",
17 "transactionIndex": "0x0"
18 }
19 }
20}
21
すべて表示
コピー

eth_unsubscribe

新たにイベントが送信されないように、既存のサブスクリプションを取り消します。

パラメータ

  1. 以前にeth_subscribe呼び出しで返されたサブスクリプションの ID です。

戻り値

サブスクリプションのキャンセルに成功した場合にtrue、または渡された ID のサブスクリプションが存在しない場合にfalseが返ります。

例:

リクエスト

1curl https://eth-mainnet.alchemyapi.io/v2/your-api-key
2-X POST
3-H "Content-Type: application/json"
4-d '{"id": 1, "method": "eth_unsubscribe", "params": ["0x9cef478923ff08bf67fde6c64013158d"]}'
5
6

結果

1{
2 "jsonrpc": "2.0",
3 "id": 1,
4 "result": true
5}
コピー

無料でAlchemy に登録し(opens in a new tab)ドキュメント(opens in a new tab)を確認しましょう。またTwitter(opens in a new tab)をフォローして最新のニュースをチェックしてください。

最終編集者: @HiroyukiNaito(opens in a new tab), 2023年8月15日

このチュートリアルは役に立ちましたか?