RPCリクエストの仕組み:ブロックチェーンノードのガイド |QuicknodeHyperliquid ノードを運用していますか?Hyperliquid のピアリング機能を使用して、ブロックおよびフルメンプールへのダイレクトパスを有効にします。
詳細はこちら SOC 2 タイプ II 認証取得・ISO 27001
回答>RPCとAPIについて学ぶ>RPCリクエストはどのように機能するのですか? RPCリクエストはどのように機能するのでしょうか?
// Tags
RPCリクエストJSON-RPCブロックチェーンAPI呼び出し
要約: RPC(リモート・プロシージャ・コール)リクエストとは、 アプリケーションがブロックチェーンノードと通信するための仕組みです。 アプリケーションは、呼び出すメソッドと含めるパラメータを指定したJSON形式のメッセージを、RPCエンドポイント(endpoint )に送信します。ノードはリクエストを処理し、ブロックチェーンの状態に基づいて対応するロジックを実行し、結果をJSON形式のレスポンスとして返します。ウォレットの残高確認、トランザクションの送信、スマートコントラクトとのやり取りはすべて、このリクエスト・レスポンスのパターンに従っています。
わかりやすい説明
暗号資産ウォレットで「送信」をタップしたり、ポートフォリオトラッカーでトークンの残高を確認したりする場合、そのアプリケーションはブロックチェーンに直接アクセスすることはできません。その情報を取得するには、ノードに問い合わせる必要があります。この問い合わせに使用される言語はJSON-RPCと呼ばれ、リクエストとレスポンスを単純なJSONオブジェクトとして構成する軽量なプロトコルです。
会話の流れは次のとおりです。アプリケーションは、4つのフィールドを持つリクエストオブジェクトを構築します。そのフィールドとは、JSON-RPCのバージョン(常に「2.0」)、ノードに対して実行すべき操作を指定するメソッド名、その操作のコンテキストを提供するパラメータの配列、およびアプリがレスポンスとリクエストを照合できるようにするための一意のIDです。このオブジェクトを、RPCのendpoint というURLに対してHTTP POSTとして送信します。 ノードはリクエストを受信し、回答を検索または計算した上で、同じIDと、結果フィールド(成功した場合)またはエラーフィールド(問題が発生した場合)を含むレスポンスオブジェクトを返します。
たとえば、ウォレットアドレスのETH残高を確認する場合、アプリケーションは「eth_getBalance」というメソッドと、2つのパラメータ(ウォレットアドレスと「latest」=最新のブロック)を含むリクエストを送信します。ノードは現在の状態を照会し、そのアドレスに関連付けられた残高を特定して、16進数として返します。 その後、アプリケーションはその16進数値を人間が読み取れる数値に変換して表示します。パフォーマンスの高いプロバイダーを使用した場合、この一連の処理には通常、数十ミリ秒かかります。
一般的なRPCメソッドの仕組み
すべてのブロックチェーンには、ノードがサポートしなければならない一連の標準的なRPCメソッドが定義されています。Ethereum やEVM互換チェーンでは、これらのメソッドは「eth_」という名前空間の規則に従います。 読み取り操作は、ブロックチェーンの状態を変更することなく、その状態を照会します。「eth_blockNumber」は最新のブロック高を返します。「eth_getBalance」は、指定されたブロックにおけるアカウントのネイティブトークンの残高を返します。「eth_call」は、読み取り専用のmode でスマートコントラクト関数を実行します。これにより、アプリはガスを消費することなく、トークンの残高、NFTのメタデータ、およびDeFiプロトコルの状態を取得することができます。
書き込み操作では、データをネットワークに送信してブロックに組み込ませます。「eth_sendRawTransaction」は、署名済みのトランザクションをメンプールにブロードキャストし、そこでバリデーターがそれを取得してブロックに組み込みます。「eth_estimateGas」は、トランザクションをシミュレートして消費されるガスの量を予測し、アプリケーションが送信前に適切なガス制限を設定できるよう支援します。
サブスクリプション方式により、WebSocket接続を介したリアルタイム通信が可能になります。 アプリが新しいブロックを検出するために「eth_blockNumber」を使ってノードを繰り返しポーリングする代わりに、「newHeads」というパラメータを指定して「eth_subscribe」を呼び出すことができます。そうすることで、新しいブロックヘッダーが生成されるたびに、ノードからアプリへプッシュされます。これはポーリングよりもはるかに効率的で遅延も少なく、ライブ取引フィード、イベントリスナー、瞬時の残高更新といったリアルタイムDapp体験の基盤となります。
Solana アカウントベースのモデルに最適化された、別のメソッドセットを使用しています。「getBalance」はアカウントのSOL残高を返します。「getTransaction」は署名に基づいて確定済みのトランザクションを取得します。「getAccountInfo」はアカウントに保存されているデータを返しますが、Solana では、これにはトークンの残高とプログラムの状態の両方が含まれます。メソッド名は異なりますが、その根底にあるJSON-RPCのパターンは同一です。つまり、メソッドとパラメータを含むリクエストに対し、結果またはエラーを含むレスポンスが返されます。
リクエストのライフサイクルの内部構造
アプリケーションがRPCリクエストを送信すると、レスポンスを受け取るまでにいくつかの手順が実行されます。まず、HTTPクライアントがendpoint へのTCP接続を確立し、TLSハンドシェイクを行って通信チャネルを暗号化します。その後、JSONペイロードを送信します。 ノードのRPCサーバーはリクエストを解析し、メソッド名とパラメータの妥当性を確認した上で、適切なハンドラーにルーティングします。ハンドラーは、キャッシュされたデータを検索するか、ノードのローカルデータベースにクエリを実行するか、あるいは計算(EVMでのスマートコントラクト呼び出しの実行など)を実行します。結果が準備でき次第、ノードはそれをJSONとしてシリアライズし、同じ接続を介して返信します。
これらの各ステップには時間がかかります。DNS解決、TCPハンドシェイク、TLSネゴシエーション、リクエストのシリアライズ、ノードでの処理、レスポンスのシリアライズ、そしてネットワーク経由の転送――これらすべてが、レスポンスの合計時間に影響を与えます。だからこそ、アプリケーションとRPCノードの地理的な近接性が重要であり、接続プールやHTTP/2の多重化によってスループットが向上し、また、頻繁にリクエストされるデータをユーザー側でキャッシュすることで、不要なラウンドトリップを減らすことができるのです。
バッチリクエストは、JSON-RPC仕様の一機能であり、1回のHTTP呼び出しで複数のリクエストを送信できるようにするものです。5つの異なるウォレットの残高を取得するために5つの別々のリクエストを送信する代わりに、これら5つすべてをJSON配列にまとめて一括で送信します。ノードはそれぞれを処理し、レスポンスの配列を返します。バッチ処理によりHTTPのオーバーヘッドが軽減され、スループットの向上が期待できますが、個々のリクエストがノード側で消費する処理リソースの量は変わりません。
エラー処理とベストプラクティス
RPCの応答には、問題が発生した場合に標準のエラーコードが含まれます。リクエストの形式が不正な場合は、構文エラーが返されます。無効なメソッド名が指定された場合は、メソッドが見つからないというエラーが返されます。レート制限が適用された場合は、通常、HTTPステータス429またはコード-32005を含むJSON-RPCエラーが返されます。これらのエラーコードを理解し、アプリケーション内で適切に処理することは、信頼性の高いブロックチェーンソフトウェアを構築するために不可欠です。
指数関数的なバックオフを用いた再試行ロジックは、一時的な障害に対するベストプラクティスです。ネットワークの一時的な不具合やノードの一時的な過負荷によりリクエストが失敗した場合、アプリケーションは短時間待機してから再試行し、再試行のたびに待機時間を徐々に長くしていく必要があります。これにより、アプリケーションが負荷のかかっているノードに過度な負荷をかけ、問題を悪化させることを防ぐことができます。また、適切なタイムアウトを設定することも同様に重要です。なぜなら、解決されないままハングしたリクエストは、アプリケーションのイベントループをブロックしてしまう可能性があるからです。
その用途に適したRPCメソッドを選択することも重要です。 よくある間違いとして、アプリケーションがブロックヘッダーのみを必要としているにもかかわらず、「eth_getBlockByNumber」を呼び出す際にフルトランザクションフラグをtrueに設定してしまうことが挙げられます。フルトランザクションのレスポンスは、データ量が桁違いに大きくなるため、より多くの帯域幅を消費し、解析にも時間がかかります。同様に、「eth_getLogs」を使用する際にブロック範囲を過度に広く設定すると、ノードとアプリケーションの両方を圧迫するほどの膨大なデータセットが返される可能性があります。ログクエリを小さなブロック範囲ごとに分割して取得することは、標準的な手法です。
HTTPとWebSocketのRPCリクエストにはどのような違いがありますか?
RPCリクエストはいくつかの異なるトランスポートを介して送信されますが、適切なものを選択することは、レイテンシや効率に大きな影響を与えます。HTTPはリクエスト・レスポンスモデルを採用しています。つまり、アプリが接続を確立し、1つのリクエストを送信して1つのレスポンスを受け取ると、そのやり取りは終了します。一方、WebSocketは単一の持続的な接続を維持するため、データが利用可能になった瞬間にノードがアプリにデータをプッシュすることができます。gRPC は、低レイテンシかつ高スループットが求められるワークロード向けに、高性能なバイナリプロトコルを提供します。
輸送 | こんな方に最適 | 接続 | リアルタイムプッシュ |
|---|
HTTP (JSON-RPC) | 1回限りの読み取りおよび書き込み | リクエストに応じて新規作成(プール可能) | いいえ、ポーリングを行う必要があります |
WebSocket | 購読とリアルタイム更新 | 単一の永続接続 | はい、サーバーがデータをプッシュします |
gRPC | 高スループット・低レイテンシのパイプライン | 持続的、多重化 | はい、ストリーミングです |
アプリケーションで読み取り操作がたまにしか行われない場合は、通常のHTTPが最も簡単です。ブロックチェーンのリアルタイムイベントが必要な場合は、繰り返し呼び出しでノードに負荷をかけるよりも、WebSocketによるサブスクリプションの方が適しています。ノードが提供する接続タイプの詳細については、「RPC(endpoint )」を参照してください。また、繰り返しチェックする場合とサブスクリプションを利用する場合のトレードオフについては、「ポーリングとストリーミングの比較」を参照してください。
RPCリクエストが失敗したり、タイムアウトしたりするのはなぜですか?
RPCの失敗のほとんどは、いくつかのパターンに分類されます。リクエスト制限を超過すると、HTTP 429 または JSON-RPC コード -32005 が返されます。そのため、すぐに再試行するのではなく、一旦間隔を空けてから再試行してください。ノードが利用できない場合、ノードが再起動中、同期中、または過負荷の状態にあるときに、502 または 503 が返されます。以下のような、サイズが大きすぎるクエリは、 eth_getLogs 何百万ものブロックにまたがる呼び出しでは、ノードが応答を時間内に組み立てられないためにタイムアウトが発生する可能性があります。理解する RPCのレート制限 そして、プロバイダーを強力な ノードの信頼性 こうした対策により、こうした障害の発生は稀であり、復旧も可能となっています。
RPCリクエストを高速化するにはどうすればよいでしょうか?
RPCのレイテンシは、ネットワーク通過時間とノード処理時間の合計であり、どちらも制御可能です。ユーザーから地理的に近いノードにリクエストをルーティングし、プール機能やHTTP/2の多重化を利用して接続を再利用し、関連する呼び出しを1つのリクエストにまとめ、ブロック間で変化しないデータをキャッシュします。 また、その処理に最適な手法を選択することも有効です。ヘッダーのみが必要な場合は、完全なトランザクションではなくブロックヘッダーをリクエストしてください。リクエストを遅延させる要因の詳細については、「RPCレイテンシの原因」を参照するか、世界中に分散されたQuicknode Core APIを使用することで、チューニング作業を完全に省略することも可能です。
インデックス作成やストリーミングの代わりにRPCを使用すべきなのは、どのような場合でしょうか?
RPCは、個別の照会や書き込み(単一の残高の取得、1つの契約値の読み取り、トランザクションのブロードキャストなど)には最適なツールです。しかし、大規模な履歴データセットや集計ビューが必要な場合、生のRPC呼び出しからそのデータを再構築するには時間がかかり、リクエスト数も多くなるため、非効率的になります。分析クエリについては、インデックス付きデータセットの方がはるかに効率的であり、継続的なリアルタイムデータについては、ストリーミングを利用することでリクエストとレスポンスのオーバーヘッドを完全に排除できます。 ライブ呼び出しと事前準備されたデータセットのどちらを選ぶかについては、「RPC 対 インデックス」を参照してください。
Quicknode によるRPCリクエストの最適化方法
QuicknodeのCore APIは、すべてのRPCリクエストを可能な限り高速かつ信頼性の高いものにするよう設計されています。このプラットフォームのグローバルに分散されたインフラストラクチャは、各リクエストを最も近い利用可能なノードにルーティングし、ネットワークの伝送時間を最小限に抑えます。競合他社と比較して平均で2.5倍速い応答時間と、99.99%の稼働率を保証するSLAを備えたQuicknode は、トラフィック量にかかわらず、アプリケーションのRPC呼び出しが迅速かつ安定して処理されることを保証します。
標準のJSON-RPCに加え、Quicknode は、アプリケーションが発行する必要のあるリクエスト数を削減する拡張APIメソッドを提供します。ウォレットのトークン保有状況全体を把握するために複数の標準メソッドを呼び出す代わりに、1回の拡張API呼び出しで、すべてのデータを1つのレスポンスとして取得できます。Quicknode Streams さらに、Quicknode はリアルタイムデータに関してリクエスト-レスポンスのパターンを完全に排除し、ブロックチェーン上のイベントが発生したその瞬間に、アプリケーションやデータベースへ直接プッシュします。RPCの利用を最適化したい開発者のために、 は、ページネーション、キャッシュ、エラー処理、およびメソッド選択のベストプラクティスを網羅した、効率的なRPC呼び出しに関する詳細なガイドを公開しています。
よくある質問
ブロックチェーンにおいて、RPCとは何の略ですか?
RPCとは、リモート・プロシージャ・コール(Remote Procedure Call)の略です。これは、アプリケーションが、あたかもローカルの関数を呼び出すかのように、リモートマシン(この場合はブロックチェーンノード)上で実行される関数を呼び出すパターンです。ノードは、チェーンの状態に基づいてそのプロシージャを実行し、結果を返します。
JSON-RPCとは何ですか?
JSON-RPCは、ほとんどのブロックチェーンがRPCに採用している軽量なプロトコルです。リクエストとレスポンスはプレーンなJSONオブジェクトです。リクエストにはメソッド名とそのパラメータが指定され、レスポンスには結果またはエラーが含まれ、共通のIDによってリクエストと紐付けられます。
RPCリクエストとAPI呼び出しは同じものですか?
これは特定の種類のAPI呼び出しです。一般的なREST APIは異なるURLでリソースを公開しますが、ブロックチェーンのRPC APIは単一のendpoint というURLでメソッドを公開し、リクエスト本文内のメソッド名を通じて操作を選択します。リクエストとレスポンスの往復という仕組みは同じです。
RPCリクエストにはどれくらい時間がかかりますか?
近くにある、十分なリソースを備えたノードに対する単純な読み取り操作は、通常、数十ミリ秒で完了します。広範囲にわたるログクエリやブロック全体の取得など、負荷の高い呼び出しは、ノードが応答する前に集約・シリアル化する必要があるデータ量が多いため、より時間がかかります。
RPCノードとRPCendpoint の違いは何ですか?
RPCノードとは、ブロックチェーンデータを保持し、リクエストを実行する稼働中のサーバーのことです。RPC(endpoint )とは、アプリケーションがリクエストを送信するURLのことで、このURLを通じてリクエストは背後に存在する1つ以上のノードにルーティングされます。基盤となるインフラストラクチャについては、「ブロックチェーンノードとは」を参照してください。
参考資料