用語集 / ノードとソフトウェア
RPC
別名はJSON-RPC、Remote procedure callです。
- RPCとは?
- RPCは、ビットコインのノードが他のプログラムに対して公開するコマンドインターフェースであり、ウォレット、取引所のバックエンド、あるいは自身のターミナルからノードに質問を送ったり指示を出したりできるようにするものです。
ビットコインを自動化するものはすべて、この方法でノードと通信します。Bitcoin CoreはJSONを含むHTTPリクエストをポート8332で待ち受け、1回に1つの呼び出しに応答し、既定では実行されているマシンからの接続だけを受け付けます。あるサービスが手数料の見積もりを示してきたことがある場合や、出金が確認されたと伝えてきたことがある場合、その回答は何らかのRPC呼び出しが生成したものです。
仕組み
RPC呼び出しはHTTP POSTであり、その本文でメソッド名を指定し、引数を列挙します。
getblockchaininfoを要求すると、チェーン名、現在の高さ、検証の進捗、ディスク上のサイズが返ってきます。listunspentやsendtoaddressを要求すると、ノードのウォレットを操作することになります。getrawtransactionを要求すると、バイト列が得られます。同梱のbitcoin-cliプログラムは、JSONを組み立てて送信し、応答を出力する薄いラッパーであるため、コマンドラインで入力できることは、プログラムがソケット経由で実行できます。
認証には知っておく価値のある経緯があります。Bitcoin Coreはバージョン0.12.0で組み込みのSSL対応を廃止したため、このインターフェースは暗号化されていないHTTPのみで通信します。同じリリースでクッキーファイルが導入されました。これは起動時にデータディレクトリに書き込まれるランダムな認証情報で、再起動のたびに置き換えられるため、bitcoin-cliはパスワードを設定しなくても自身のマシンで動作します。リモートからの呼び出し元向けにはrpcauthがあり、設定ファイルに平文の秘密ではなくソルト付きハッシュを保存します。トランスポートの暗号化は依然として存在しないため、ネットワーク越しにノードへ到達するにはSSHトンネル、VPN、Torのヒドゥンサービスが必要で、それ以外の方法は使えません。
各ネットワークにはそれぞれ専用のポートがあり、複数のデーモンが1台のマシンを共有できます。メインネットは8332、testnet3は18332、testnet4は48332、signetは38332、regtestは18443です。メインネットのRPCポートはピアツーピアポート8333のすぐ下にあり、この2つを混同することはよくある最初の間違いです。
この方言はゆっくりと変化してきました。Bitcoin Coreは10年以上にわたり、JSON-RPC 1.0の緩やかな変種に応答していました。バージョン28.0では、サーバーがJSON-RPC 2.0のリクエストを認識し、その仕様に厳密に準拠して応答できるようになりましたが、旧来の形式も引き続き受け付けます。ウォレット固有の呼び出しはパスで指定されるため、複数のウォレットを保持するノードは、/wallet/に続けてウォレット名を付けたパスでそれらを振り分けます。
どこで使われているか
RPCは、ビットコインそのものと、その上に構築されたあらゆる製品との間の接点です。
ライトニングネットワークの実装は、ノードにブロックを要求し、クローズ用のトランザクションをノード経由で送信します。ブロックエクスプローラー、mempoolのダッシュボード、BTCPay Serverのような決済処理業者は、bitcoindのインスタンス上に構築され、それをより使いやすい形で包み込みます。取引所の出金システムは、その階層の最下層ではsendrawtransaction呼び出しのキューです。当サイトの取引所レビューで、あるプラットフォームが出金をバッチ処理していると記載されている場合、そのバッチ処理は最終的にここに至るコードで行われています。
また、ここはセルフホストの環境が侵害される場所でもあります。ポート8332は常時スキャンされており、推測しやすいパスワードと資金の入ったウォレットを備えたノードをインターネットに公開すると、そのウォレットは空にされてしまいます。インターフェースはローカルマシンに限定してバインドし、他の場所から必要とする場合はトンネル経由で接続してください。
RPC vs RPCバイト順
RPCとRPCバイト順は頭字語を共有するだけで、それ以外に共通点はありません。これが実際のバグを引き起こします。RPCはインターフェースです。RPCバイト順は表示上の慣習です。ブロックとトランザクションのハッシュは一方向で計算・送信され、RPC層はそれらを逆順で出力します。そのため、ブロックエクスプローラーからコピーしたtxidは、生のトランザクション内にある同じ32バイトと比べて逆向きに読めます。コピーしたtxidを逆順にせずにそのままバイトレベルのパーサーに渡すと、検索は決して一致しません。