coetus’s blog

Blockchain の Improvement Proposal などの和訳をしています

EIP-4 - EIP Classification (ざっくり和訳)

  • レイヤー:Process
  • 著者:Joseph Chow
  • ステータス:Draft
  • タイプ:Meta
  • 作成日:2015-11-17

要約

このドキュメントでは EIP のクラス分類のスキーマについて記述する。出典は BIP 123 である。

EIP より複雑な相互運用性の要件を含む、低い番号のレイヤーをもつシステムレイヤーによって分類される。

本仕様は、レイヤーを定義し、standard EIP が属するレイヤーを決定するための 4 つの明確な判断基準を設定する。

動機

Ethereum は多数の異なる標準を含むシステムである。相互運用性のための絶対的な要件となる標準もあれば、一方で、実装者が対応の可否を選択できるオプショナルと見なされる要件もある。

相互運用性の要件をより綿密に反映する EIP のプロセスを持つためには、それ相応に EIP のカテゴライズが必須である。低いレイヤーでは、標準を受理しデプロイするにあたり、かなり大きな課題が提示される。

仕様

Standard EIP は 4 つのレイヤーのうち、どれか 1 つに該当する。

  1. コンセンサス
  2. ネットワーキング
  3. API/RPC
  4. アプリケーション

1. コンセンサスレイヤー

コンセンサスレイヤーは暗号学的なコミットを行う構造である。目的は参加者が個別にステートや取引履歴を評価し、合意を保証し、全体で唯一の結果に達することを保証することである。

コンセンサスレイヤーは、メッセージがどのようにネットワーク上で伝播されたかを考慮しない。

コンセンサスレイヤーで否認されたとき、ネットワークの分離やフォークが発生しうる。別々のノードが相容れない歴史を受容することになる。コンセンサスレイヤーでの変更を、さらにソフトフォークとハードフォークの 2 つに細分化しよう。

ソフトフォーク

ソフトフォークでは、古いルールの下では妥当であった構造が、新しいルールのもとではもはや妥当ではなくなる。古いルールの下で不当だった構造は、新しいルールのもとでも不当のままで継続する。

ハードフォーク

古いルールの下で不当だった構造が、新しいルールのもとで妥当となる。

ネットワーキングレイヤー

ネットワーキングレイヤーは Ethereum wire protocol (eth) と Light Ethereum Subprotocol (les) を定義する。RLPx は除外されており、devp2pのリポジトリでトラッキングされる。

サブプロトコルのある部分集合のみが、基本的なノードの相互運用性の要件となる。ノードはさらなるオプショナルの拡張をサポートできる。

新しいサブプロトコルを、既存のプロトコルとの互換性を破壊せずに追加することは常に可能である。古いプロトコルはだんだんと非推奨になっていく。この方法で、サービスが落ちる深刻なリスクなしに全体のネットワークをアップグレードできる。

3. API/RPC レイヤー

API/RPC レイヤーでは、アプリケーションにアクセス可能な高レベルの呼び出しをサポートする。これらの EIP をサポートすることは基本的なネットワーク相互運用性において必須ではないが、クライアントアプリケーションがサポートを期待する場合がある。

このレイヤーには、基本的なネットワーク相互運用性を破壊せずに標準化の競争を許す余裕がある。

4. アプリケーションレイヤー

アプリケーションレイヤーでは、様々なアプリケーションで同様の機能をサポートし、データを共有する、高レベルの構造、抽象、手法を定義する。

EIP-3 - Addition of CALLDEPTH opcode (和訳)

要約

これは新しい opcode CALLDEPTH の提案である。CALLDEPTH opcode は、残りの call stack の深さを返す。

動機

コントラクトが、別のコントラクトを呼ぶ深度がどのくらいかを定義するリミットが call stack である。call stack のリミットは現在のところ 256 である。コントラクトが別のコントラクトを(CALLCALLCODE を介して)呼び出したとき、call stack depth がリミットに達していたら、処理は失敗する。

この挙動によってコントラクトは "call stack attack" の被害を受ける可能性がある[1]。このような攻撃では、例えば再帰的な呼び出しによって、攻撃者は初めに適切なスタックの深度を設定する。その次に攻撃者は対象のコントラクトを呼び出す。対象のコントラクトが別のコントラクトを呼び出す場合、その呼び出しは失敗する。呼び出しが成功したかどうかを確認するために戻り値のチェックすることを適切に行っていなければ、結果に悪影響を及ぼしてしまう。

例:

  1. コントラクト A は定期的に呼び出されることを期待しており、1 ブロック毎に呼び出し元に Ether を支払う。
  2. コントラクト A が呼び出されたとき、Aコントラクト BC を呼び出す。これには大量の gas を消費する。呼び出し後に、コントラクト A は呼び出し元に Ether を支払う。
  3. 悪意のあるユーザ X は、A を呼び出す前にスタックの深さが浅いことを保証しておく。両方の B, C に対する呼び出しは失敗するものの、依然として X は報酬を受け取ることが出来る。

この攻撃を防ぐには、以下の 2 つの方法がある。

  1. 呼び出し後に、戻り値をチェックする。
  2. call stack の深さを実験的にチェックする。この目的のために Piper Merriam が作成したライブラリ[2]が存在する。この方法は gas を大量に消費する。

[1] "shallow stack attack" や "stack attack" という名前で知られている。しかしながら、正確に言うと、ここでの "stack" という単語は EVM 上での意味とは異なっており、"call stack" と混同すべきではない。

[2] https://github.com/pipermerriam/ethereum-stack-depth-lib

仕様

opcode CALLDEPTH は、残りの call stack の深度を返さなければならない。戻り値が 0 であることは call stack を使い切ったことを意味し、これ以上の呼び出しは起こせないことを意味する。

原理

実際の call stack の深さとリミットは、実行中に EVM 上に存在している。しかし、それらは EVM 内で単に使用できなくなる。実装はかなり単純であるはずで、安価なやり方で call stack attack から守る方法を提供する。

実装

未実装。

EIP-2 - Homestead Hard-fork Changes (ざっくり和訳)

Meta EIP は EIP-606: Hardfork Meta: Homestead を参照

仕様

block.number >= HOMESTEAD_FORMBLKNUM で以下を行う。

  1. トランザクションコントラクトを作成する gas cost が 21000 から 53000 まで上昇する。即ち、空のアドレスにトランザクションを送信したとき、初期のgas減少値が 53000 + (txdata の gas cost) であり、現在の 21000 よりも大きくなる。CREATEのopcodeを使ったコントラクト生成は影響を受けない。
  2. s-valuesecp256k1n/2 より大きい全てのトランザクションの署名は不当と見なされる。ECDSAでプリコンパイルされたコントラクトを復号する場合は影響を受けず、s-valueが大きい値を受け取り続ける。この仕様は、例えば古い Bitcoin の署名を復号するコントラクト場合に役立つ。
  3. コントラクトが、コントラクトコードを状態に追加するために必要な最終的な gas の手数料を払うのに十分な gas を持たないとき、コントラクトを空のママにするのではなく、コントラクト生成が失敗するようになる(out-of-gas)。
  4. 現状の公式から難易度調整アルゴリズムの変更が起こる。 block_diff = parent_diff + parent_diff // 2048 * (1 if block_timestamp - parent_timestamp < 13 else -1) + int(2**((block.number // 100000) - 2))(where the+ int(2**((block.number // 100000) - 2))represents the exponential difficulty adjustment component) toblock_diff = parent_diff + parent_diff // 2048 * max(1 - (block_timestamp - parent_timestamp) // 10, -99) + int(2**((block.number // 100000) - 2)), // は、整数除算の演算子である。minDifficulty は、難易度の最小値を示しており、この値より小さい難易度に調整されることはない。

原理

現在のところ、トランザクションコントラクトを作成する余分なインセンティブがある。トランザクションのコストが 21000 であり、コントラクトのコストの 32000 より小さいからである。加えて suicide refunds のお蔭で、現状はたった 11644 gas で単純な ether value transfer が可能である。以下のコードで実現できる。

from ethereum import tester as t
> from ethereum import utils
> s = t.state()
> c = s.abi_contract('def init():\\n suicide(0x47e25df8822538a8596b28c637896b4d143c351e)', endowment=10**15)
> s.block.get_receipts()\[-1\].gas_used
11664
> s.block.get\_balance(utils.normalize\_address(0x47e25df8822538a8596b28c637896b4d143c351e))
1000000000000000

これはとりわけ深刻な問題ではないが、しかしながら間違いなくバグである。

0 < s < scp256k1n の範囲内である任意の s 値のトランザクションを現状通り許容してしまうと、トランザクションの malleability concern を開放することになる。トランザクションを受け取って s -> secp256k1n - s に s 値の反転が可能になり、 v 値を 27 -> 28, 28 -> 27 と言ったように反転できてしまい、計算した署名が正当になってしまうからである。これは深刻なセキュリティの欠陥ではない。Ethereum は ether value transfer や 他のトランザクションへの入力に、トランザクションのハッシュではなくアドレスを利用しているのが主な理由である。しかしながら、この欠陥によってブロックに入っている承認済みトランザクションが、任意のユーザが送信したトランザクションの異なるハッシュ値に変更できてしまい、トランザクションハッシュをトラッキングIDとして利用するUIに影響を与えてしまう。高い s 値を避けることで、この問題を取り除くことができる。

コントラクト生成で、最終的な gas の手数料が支払えない場合に out-of-gas するようにした場合、以下のような利益がある。

  1. コントラクト生成のプロセスの結果において、成功と失敗の区別がより直感的になる。
  2. コントラクト生成が完全に成功しない限り、コントラクトアカウントが生成されないため、失敗の検知がより容易になる。
  3. 寄付金がある場合にコントラクト生成を安全にする。全体の初期のプロセスが起こるか、トランザクションが否認されるかによって、寄付金の払い戻しが保証されるからである。

難易度調整の変更は Ethereum プロトコルが、過度のマイナーがタイムスタンプ = parent_timestamp + 1 を含むブロックのマイニングをしていた 2 ヶ月前を参照する問題を最終的に解決する。この問題はブロック生成の時間分布を歪めてしまった。現在のブロック生成時間のアルゴリズムは、13秒のメジアンになるように調整されるものだが、メジアンは同じでも平均は上昇し始めてしまった。51% のマイナーがこの方法でマイニングを始めてしまったら、平均は無限大まで上昇してしまうだろう。提案された新しい公式は、ざっくり目標の平均値に基づくものである。この公式を利用することで、平均のブロック生成時間が長期的な視点で数学的に 24 秒を超えることが不可能になるという証明がされている。

メインの入力変数として、時刻変位ではなく (block_timestamp - parent_timestamp) // 10 を利用することは、アルゴリズムの粗さを抑えることに直接役立ち、微小に難易度が高いブロックを生成するために、ちょうど 1 だけ異なるタイムスタンプを設定しようというインセンティブを抑えることにもなる。これによって、フォークの可能性に打ち勝つことが保証される。-99の上限は、クライアントのセキュリティバグや black-swan 問題のために、2 つのブロックが非常に遠く離れている場合に、難易度が極端に落ちないようにするものである。

EIP-1 - EIP Purpose and Guidelines (ざっくり和訳)

github.com

EIP-1 の序盤だけ和訳。ワークフロー以降は一旦省略。

EIP-1 - EIP Purpose and Guidelines

EIPとはなにか

EIP は Ethereum Improvement Proposal の略語である。EIP は Ethereum コミュニティに情報を提供したり、Ethereum の新機能や、その進捗状況や環境を説明する設計のドキュメントである。EIP の筆者は、コミュニティ内で同意を得て、反対意見をドキュメント化する責任がある。

EIPの基本原理

EIPの主な機能は、新機能提案、コミュニティの技術的なインプットを Issue にまとめること、Ethereum に適用された設計の決定をドキュメント化することである。EIPはバージョン管理システムでテキストファイルとして管理されるため、リビジョンの履歴が機能提案の歴史的な記録になっている。

Ethereum の実装者にとって、EIP の活用は現在の実装の進捗状況を追跡するのに便利な方法である。理想的には、各々の実装の Maintainer が、実装した EIP をリストに記載すると良い。そうすればエンドユーザーが、実装やライブラリの現在の状況を知ることができる。

EIPのタイプ

EIPには3つのタイプがある。

Standard Track EIP

  • Standard Track EIP は Ethereum の実装の殆どまたは全てに影響する任意の変更が記述される。ネットワークプロトコルの変更、ブロックやトランザクションの検証ルールの変更、提案されたAppの標準・慣例、あるいは Ethereum を使う App との相互運用性に影響する変更・追加のようなものが該当する。更に、Standard EIP は次のカテゴリに細分化される。Standards Track EIP は 3 つの部分に分かれている。設計のデザイン、実装、最終的には適切な場合に、正式な仕様への更新がある。
  • Core は、コンセンサスの fork 必要とする改善(例: EIP5, EIP101)である。必ずしもコンセンサスにクリティカルではないが、"core dev"のディスカッションに関連するだろう変更も該当する(例:EIP90、EIP86 の Miner strategy の変更 2, 3, 4)。
    • Networking には、devp2p (EIP8) や Light Ethereum Subprotocol に関する改善、whisper や swarm のネットワークプロトコルの仕様の改善提案が含まれる。
    • Interface は、クライアントの API/RPC の仕様や標準に関する改善、メソッド名(EIP56, EIP6)や contract ABI といったような特定の言語レベルでの標準が含まれる。"interface" のラベルは interfacesリポジトリで整頓されて、EIPリポジトリにEIPとして提出される前に、そこで主な議論がされる。
    • ERC - applicationレベルの標準・慣例で、コントラクトの標準が含まれている。トークンの標準(ERC20)や name registries (ERC26, ERC137)、URIスキーマ (ERC67)、ライブラリ/パッケージのフォーマット (EIP82)、ウォレットのフォーマット(EIP75, EIP85) のようなものが該当する。
  • Informational EIP は、Ethereum設計のIssueを記述したり、Ethereumコミュニティへの一般的なガイドラインや情報を提供するが、新機能の提案は記述されない。Informational EIPはEthereumコミュニティの合意や推奨を代表するものではないため、ユーザや実装者は記述されている助言に対して、自由に無視したり従ったりすることが出来る。
  • Meta EIP は、Ethereum周辺のプロセスが記述され、プロセスやプロセスに含まれる事柄の変更の提案がされる。 Process EIP は Standard Track EIP と類似しているが、Ethereum プロトコルそれ自体以外の領域にも適用される。実装の提案もありうる。Ethereumのコードベースでなく、コミュニティの合意が必要だが、Informational EIPとは異なり、より"推奨"の内容になる。ユーザは基本的にこのEIPの記述について考慮が必要になる。例には、手順、ガイドライン、意思決定の過程の変更Ethereum開発に使われるツールや環境の変更を含んでいる。任意の Meta EIP は Process EIP とも見なされる。

一つのEIPは一つの key proposal や、新しいアイデアを含むことが強く推奨される。より焦点のあったEIPの方が、よりうまくいく傾向にある。一つのクライアントに対しての変更ではなく、複数のクライアントに影響する変更であったり、複数のアプリで使われるような標準の定義であるとかがEIPに採用される。

EIPには、最低限満たすべき基準が存在する。 提案された改善は、明瞭かつ完全に記述されていなければならない。改善は、正味で改善することを表さなければんらない。提案された実装は、強固でなければならず、プロトコルを過度にしてはならない。

(EIP Work Flow 以下は省略)