BIP: 22
Layer: API/RPC
Title: getblocktemplate - Fundamentals
Authors: Luke Dashjr <luke+bip22@dashjr.org>
Status: Deployed
Type: Specification
Assigned: 2012-02-28
License: BSD-2-Clause
概要
本 BIP は、「賢い」ビットコインマイナーおよびプロキシ向けの新しい JSON-RPC メソッドを記述する。 ハッシュ計算用の単純なブロックヘッダーを送信する代わりに、ブロック構造全体が送信され、(任意で)カスタマイズおよび組み立てをマイナー側に委ねる。
著作権
本 BIP は BSD 2-clause ライセンスの下でライセンスされる。
仕様
ブロックテンプレートリクエスト
「getblocktemplate」と呼ばれる JSON-RPC メソッドが定義される。 このメソッドはちょうど 1 個の引数を受け取り、それはリクエストパラメーターのオブジェクトでなければならない。 リクエストパラメーターに “mode” キーが含まれる場合、それは既定の “template” リクエストと「proposal」のいずれかを明示的に選択するために用いられる。
ブロックテンプレートの作成は、さまざまなパラメーターによって左右されうる。
template request
| キー | 必須 | 型 | 説明 |
|---|---|---|---|
| capabilities | いいえ | 文字列の配列 | クライアント側のサポートを示すため、以下の一覧を含むべきである: “longpoll”、“coinbasetxn”、“coinbasevalue”、“proposal”、“serverlist”、“workid”、および mutations のいずれか |
| mode | いいえ | 文字列 | ”template” または省略でなければならない |
getblocktemplate は、以下のキーを含む JSON オブジェクトを返さなければならない。
template
| キー | 必須 | 型 | 説明 |
|---|---|---|---|
| bits | はい | 文字列 | 圧縮された難易度(16 進表記) |
| curtime | はい | 数値 | サーバーが認識する現在時刻(ブロック時刻として推奨される)。これは必ずしもシステムクロックではなく、mintime/maxtime のルールの範囲内に収まらなければならない |
| height | はい | 数値 | 求めているブロック高 |
| previousblockhash | はい | 文字列 | 直前のブロックのハッシュ(ビッグエンディアン 16 進表記) |
| sigoplimit | いいえ | 数値 | ブロック内で許容される sigop 数 |
| sizelimit | いいえ | 数値 | ブロック内で許容されるバイト数 |
| transactions | should | オブジェクトの配列 | ビットコイントランザクションに関する情報を含むオブジェクト(コインベースを除く) |
| version | はい | 数値 | 常に 1 または 2(少なくともビットコインでは)。クライアントは使用するバージョンの含意を理解しなければならない(例えばバージョン 2 では BIP 0034 に準拠する) |
| coinbaseaux | いいえ | オブジェクト | コインベースの scriptSig の内容に含めるべきデータ。このオブジェクトのうち値(バイト単位で 16 進表記)のみを含めるべきであり、キーは含めない。これにはブロック高は含まれない。ブロック高は BIP 0034 により scriptSig への含有が要求されている。値は “PUSH” オペコードの中にエンコードすることが望ましい。カウントに含まれる SIGOP を、実行されないにもかかわらず意図せず消費しないようにするためである |
| coinbasetxn | this or ↓ | オブジェクト | コインベーストランザクションに関する情報 |
| coinbasevalue | this or ↑ | 数値 | コインベースに利用可能な総資金(サトシ単位) |
| workid | いいえ | 文字列 | 提供される場合、結果とともにこの値を返さなければならない(Block Submission を参照) |
transactions オブジェクトの形式
レスポンスの “transactions” キーに列挙されるオブジェクトは、以下のキーを含む。
template “transactions” element
| キー | 型 | 説明 |
|---|---|---|
| data | 文字列 | 16 進表記(バイト単位)でエンコードされたトランザクションデータ |
| depends | 数値の配列 | このトランザクションが最終ブロックに含まれる場合に、同じく含まれていなければならない、それより前のトランザクション(“transactions” 一覧中の 1 始まりのインデックスによる)。キーが存在しない場合、依存関係は不明であり、クライアントは依存関係がないと仮定してはならない |
| fee | 数値 | トランザクションの入力と出力の額の差(サトシ単位)。コインベーストランザクションの場合は、集められたブロック手数料の合計を表す負の数値となる(ブロック補助金は含まない)。キーが存在しない場合、手数料は不明であり、クライアントは手数料がないと仮定してはならない |
| hash | 文字列 | リトルエンディアン 16 進表記のハッシュ/ID |
| required | 真偽値 | 提供され true である場合、このトランザクションは最終ブロックに含まれなければならない |
| sigops | 数値 | ブロック上限の算定に用いられる SigOp の総数。キーが存在しない場合、sigop 数は不明であり、クライアントはないと仮定してはならない |
“data” キーのみが必須であるが、サーバーは既知であれば他のキーも提供すべきである。
ブロックの提出
「submitblock」と呼ばれる JSON-RPC メソッドが定義され、これにより採掘済みのブロック(またはシェア)を提出する。 このメソッドは 2 個の引数を受け取る。 最初の引数は常に、提出するブロックデータを 16 進エンコードした文字列である。 2 番目の引数はパラメーターのオブジェクトであり、パラメーターが不要な場合は省略できる。
submitblock parameters (2nd argument)
| キー | 型 | 説明 |
|---|---|---|
| workid | 文字列 | サーバーが workid を提供していた場合、提出時に含めなければならない |
このメソッドは、シェアが受理された場合には null を、シェアが却下された場合はその理由を簡潔に述べる文字列を、あるいはシェアが提出された各マージマイニングチェーンごとにキーを持つオブジェクトを、いずれか返さなければならない。
任意: ロングポーリング
template request
| キー | 型 | 説明 |
|---|---|---|
| capabilities | 文字列の配列 | ロングポーリングをサポートするマイナーは、文字列 “longpoll” を含む一覧を提供すべきである |
| longpollid | 文字列 | 期限切れを監視するジョブの “longpollid”。ロングポールリクエストに対してのみ必須かつ有効である |
template
| キー | 型 | 説明 |
|---|---|---|
| longpollid | 文字列 | ロングポールリクエストの識別子。サーバーがロングポーリングをサポートしない場合は省略しなければならない |
| longpolluri | 文字列 | 提供される場合、ロングポールリクエストに用いる代替の URI |
| submitold | 真偽値 | ロングポールレスポンスにのみ関係する。このレスポンス以前に受け取った作業がなお有効である可能性があり(既定)、そのシェアを提出すべきかどうかを示す。false の場合、マイナーはシェアキューを破棄したくなるかもしれない |
サーバーがロングポーリングをサポートする場合、ブロックテンプレートに “longpollid” キーを含めなければならず、各イベントについて一意でなければならない。 任意の “longpollid” は 1 つの条件のみを確認すべきであり、再利用すべきではない。 例えば、新しいブロックについてのみロングポールのウェイクアップを行うサーバーは、直前のブロックハッシュを用いてもよい。 ただし、クライアントは “longpollid” に何らかの特定の意味があると仮定すべきではない。 サーバーは “longpolluri” キーを、相対または絶対の URI として提供してよく、これは元の接続とは(ポート番号を含め)まったく異なるリソースを指定してもよい。 サーバーが “longpolluri” を提供した場合、クライアントはロングポールリクエストにそちらの URI のみを用いなければならない。
クライアントは、標準的な JSON-RPC リクエスト(HTTP トランスポートの場合はデータを伴う POST)と同じ認証情報を用い、リクエスト中の “longpollid” パラメーターにサーバーから提供された値を設定して、ロングポールリクエストを開始してよい。
このリクエストは、サーバーが “longpollid” によって識別される現在のブロックデータを置き換えたいと考えるまで、処理も応答もされるべきではない。 クライアントは非常に長いリクエストタイムアウトでこのリクエストを行うべきであり、サーバーが(“chunked” Transfer-Encoding を伴う HTTP ヘッダーなど)部分的なレスポンスをあらかじめ送り、最終的な JSON レスポンスの完了のみを遅延させる場合、それを受け入れなければならない。
完了したレスポンスを受信した際:
- “submitold” が提供されかつ false である場合に限り、クライアントは過去の操作の結果を破棄してよく、直ちに新しい作業に取りかからなければならない。
- クライアントは、直ちにではないとしても、できるだけ早く受け取った新しい作業に取りかかるべきである。
- クライアントは、同じロングポーリング URI に対して新しいリクエストを行うべきである。
クライアントが不完全または無効なレスポンスを受信した場合、指数バックオフを用いてリクエストを再試行すべきである。 クライアントはこのバックオフに(最大バックオフ時間などの)制限を設けてもよく、適切と判断する任意のアルゴリズムを用いてもよい。 ただし、複数回の失敗の後に遅延なく直ちに再試行することは禁止される。 「Forbidden」レスポンス(例えば HTTP 403)の場合、クライアントはユーザーの介入なしに再試行を試みるべきではない。
任意: テンプレートの調整
template request
| キー | 型 | 説明 |
|---|---|---|
| sigoplimit | 数値または真偽値 | テンプレートに含める sigop の最大数 |
| sizelimit | 数値または真偽値 | ブロック全体に用いるバイト数の最大値 |
| maxversion | 数値 | サポートするブロックバージョン番号の最大値 |
“sigoplimit” と “sizelimit” については、負の値とゼロはサーバーが定める上限からのオフセットとして扱われる。 真偽値が提供され true である場合は既定の上限が用いられ、false の場合はサーバーに対し、返すテンプレートに一切の上限を用いないよう指示する。 サーバーはこれらの希望する上限を尊重すべきであるが、それは必須ではない。 クライアントは、返されたテンプレートが自身の要件を適切に満たしていることを確認すべきである。
付録: 却下理由の例
シェアが却下されうる理由には、以下を含むがこれに限られない。
share rejection reasons
| 理由 | 説明 |
|---|---|
| bad-cb-flag | サーバーが、許可していない機能を示すフラグを検出した |
| bad-cb-length | コインベースが長すぎた(ビットコインの上限は 100 バイト) |
| bad-cb-prefix | サーバーはコインベースへの追記のみを許可しているが、それを超えて変更されていた |
| bad-diffbits | ”bits” が変更されていた |
| bad-prevblk | 直前のブロックが、サーバーが構築しようとしているものではない |
| bad-txnmrklroot | ブロックヘッダーのマークルルートがトランザクションのマークルツリーと一致しなかった |
| bad-txns | ブロック内のトランザクションについて、サーバーが何らかの点で受け入れなかった |
| bad-version | バージョンが誤っていた |
| duplicate | サーバーが既にこのブロックデータを処理済みである |
| high-hash | ブロックヘッダーが、指定されたターゲットより低い値へハッシュされなかった |
| rejected | 詳細のない一般的な却下 |
| stale-prevblk | 直前のブロックが、もはやサーバーが構築しようとしているものではなくなった |
| stale-work | このブロックの元になった作業が、もはや受け入れられなくなった |
| time-invalid | 時刻が許容されるものでなかった |
| time-too-new | 時刻が未来に寄りすぎていた |
| time-too-old | 時刻が過去に寄りすぎていた |
| unknown-user | ブロックを提出したユーザーが認識されなかった |
| unknown-work | テンプレートまたは workid を識別できなかった |
動機
bitcoind の JSON-RPC サーバーは、ビットコインを生産的にマイニングするために必要な作業を生成する負荷にもはや耐えられず、作業生成に特化した外部ソフトウェアが必要になっている。 同時に、新しい独立したノード実装も成熟しつつあり、いずれマイナーをサポートできるようになる。
フルノードと作業生成ソフトウェアの間の互換性を確保するには、ブロック構築の詳細を伝達するための共通の標準が必要である。
論拠
トランザクションを(txid の)ハッシュとして単純に扱わないのはなぜか。
- サーバーがトランザクションデータベースにアクセスできない場合や、マイナーがネットワーク全体にブロードキャストされていないトランザクションを含めたい場合がある。
- マイナーは完全なトランザクション検証を行わないことを選ぶ場合があり、その側でトランザクションデータベースにアクセスできない場合もある。
“workid” の目的は何か。
- サーバーがすべての mutation を許容する場合、それがどのジョブに基づくものかを識別するのが難しくなりうる。内容によって提出物を検証することも可能ではあるが、発行されたジョブと比較する方がはるかに容易である。マイナーにとってこれを記録しておくことは非常に容易である。したがって、“workid” を用いることは、より多くの mutation を可能にする非常に安価な解決策である。
トランザクションについて “sigops” を提供すべきなのはなぜか。
- BIP 0016 によるブロック sigop に関するルールの変更のため、トランザクション自体から sigop を数えることは不可能になっている(scriptCheck 内の sigop もカウントに含めなければならない)。
リファレンス実装
- Eloipool(サーバー) (
https://gitorious.org/bitcoin/eloipool) - libblkmaker(クライアント) (
http://gitorious.org/bitcoin/libblkmaker) - bitcoind(最小構成のサーバー) (
https://github.com/bitcoin/bitcoin/pull/936/files)
関連項目
- BIP 23: getblocktemplate - プールドマイニング


