Ethereum yellow paper メモ
調査項目
GHOSTプロトコル
Abstract
暗号学的に保護されたトランザクションに関連するブロックチェーンのバラダイムは何個ものプロジェクトを通してその有効性を実証してきた
最も注目されたものはBitcoin
シンプルな非中央集権なアプリケーションとして見られているが、実施はシングルトンなコンピュータリソースである
著者らはこのパラダイムをtransactional singleton machine with shard-stateと読んでいる
winor.icon > シングルトンな状態がトランザクションによって変化し、その状態がシェア(分散化)されているみたいなニュアンス
Ethereumはこのパラダイムを一般的化された方法で実装する
さらに、Ethereumは複数のリソースをもたらす
1. 明確な状態
2. Operating code
しかし、メッセージ通過フレームワークを通して他のものとインタラクションを取ることができる
著者らはその設計、問題、もたらす機会、想像する未来に関して議論する
Introduction
インターネットは世界中に普及しており、どこでも安く利用することができる
ビットコインのような技術の根幹の動向はインターネットを非中央集権な価値の移転システムへと変えることを可能とする
価値の移転システムは世界中とバーチャルな手数料を使うことでシェアされる価値の移転システム
このシステムはトランザクションベースのステートマシンで暗号学的な保護のとてもスペシャルなバージョンである
Nameコインのような上記であげたシステムはこのオリジナルな「通貨アプリケーション」を適応した
↑シンプルなアプリケーションではあるが、他のアプリケーションへとこのテクノロジーで
Ethereumはこういったテクノロジーの一般化を作るための試みるプロジェクトである
こういったテクノロジーとはすべてのトランザクションベースなステートマシンのコンセプトを作れるかもしれない技術
また、Ethereumはend-developerへソフトウェアをビルドするためのしっかりと結合したe2eなシステムを提供することも目的である
↑これまでメインストリーム上のよくわからなかったコンピュータパラグラ上で構築するソフトウェア
1.1 Driving Factors
たくさんのゴールがある
そのなかでも重要な一つとしては、お互いが信用していない他の人とでも、トランザクションを発行(取引)することを促進すること
豊かで、曖昧な言葉を通してステートチェンジマシンをを指定し、私達が合理的に自動で強制されるような合意を予測できるようなシステムを構築することによって、この方法を提供することができる(Ethereum?)
提案したシステム上での取引をすることは現実の世界ではあまり見つからない属性をいくつか持つだろう
発見することが難しいジャッジの腐敗は無益なアルゴリズムのインタプリタから導かれる
透明性や正確に状態か判定を見ることができるようにすることはTxログとルールもしくは教育的なコードを通して起きる
決して人間ベースのシステムで起きることはない
自然言語は必然的に曖昧で、情報が欠損し、普通の古い偏見(常識は)は覆しにくいため
まとめると、Ethereumの開発者らは(GAVIN WOOD CTO of Ethereum)下記のようなシステムを提供することを望んでいる
ユーザーが他の個人、システム、組織などに対するとインタラクトすることは問題なく、彼らは発生しうる結果の上で絶対的信頼を起くことができ、それらの結果がどのようになるかを保証されることが可能
winor.icon > Ethereumの目的というよりも、ブロックチェーンプラットフォーム全体の目的
winor.icon > 当たり前だが、分散性が必要なことについて述べている
winor.icon > システムを信頼しないでも、絶対的に結果が起きるシステムを作る重要性
1.2 Previous Work
Vitalikは2013, Nov. にこの研究のコアを最初に提案した
今は様々な方法で進化されたが、チューリング完全と内部TXのストレージ容量が圧迫しないような効率性を持つブロックチェーンのキーとなる機能は残っていて変わらない
Dwork and Naorはある提案した
計算学的支出の暗号学的証明の使用法に関する研究(PoW)
インターネットを通り、value signalを送信するという意味がある
Value signalはこの研究でも利用された、
すべての通貨の種類で必要なものではなくスパムを抑止するメカニズムとして
しかし、Value signalは批判的に可能性を実証した
可能性とはstrong economic signalをもたらす可能性
また、信頼に頼ることなく、物理的なアサーションを作るために受診者を許可することができた(トラストレスに正しいデータを認識することができた)
通貨をセキュアにするためにstrong economic signalとしてPoW使われた最初の例は2003のもの
この場合では、トークンはP2Pファイルで取引履歴をチェックし、保持されて使われた
サービスのサプライヤにマイクロペイメントを実現する機能をコンシューマへ提供する
PoWによって与えられたこのセキュリティモデルは電子署名と台帳によって増強された
この台帳は歴史的な記録が破損できないようにすることや攻撃者が偽装した決済やサービス提供に関する不平な主張をすることをできないようにすることを保証するためのもの
5年後、Satoshi Nakamtoは2008でもう一つのPoWが使われたセキュアな価値トークンを提案した
このプロジェクト、Bitcoinの果実(すごいところとかの意味かな?)ははじめてのグローバルな分散的取引台帳の広い採用になった
他のプロジェクトはビットコインの成功によって作られたアルトコインは他のプロトコルを通して多数の他の通貨を提案した
よく知られたいくつかのものは、LitecoinとPrimecoinである(2013)
他のプロジェクトはそのプロトコルのコアな価値となるメカニズムを模索された
Aron(2012)は下記について議論した
分散的な名前解決システムを提供することを目的としたNamecoinプロジェクトについて
他のプロジェクトはまだ、Bitcoinネットワーク自体の上で構築することを目的としている
システムとコンセンサスメカニズムによってもたらされる莫大な計算量の上に位置する価値のほとんどを活用することによって
Mastercoinプロジェクトは2013に提案された
これは、リッチなプロトコルを構築することを目的としている
↑コアプロトコルに多くの補助的なパーツをつけ、ビットコインプロトコルの上に多くの付加されたハイレベルな機能を関与させることによって
Coloured Coins(2012)はMastercoinに似ているがもっとシンプルな戦略を撮っている
↑トランザクションのルールを装飾することによって
↑Bitcoinの基礎通貨の代替性を壊すため
特殊なウォレットプロトコルでトークンの生成とトラックを許可するため
他の研究としては、Ripple
通貨取引所のための連合システムを作ることが求められた
効率的に新しいクリアな金融システムを作るために
これは実施された
スマートコントラクトに関する前の研究ではは1997に提案された
90sには、それは明確になっていた
どのようにかというと合意をアルゴリズムな強制することは人間の会社に対して重大になる
そのような特定のシステムは提案されていないが、それは提案された
↑法律の未来は、そのようなシステムによって大きく影響を与えるだろうと考えられた
この光のなかで、Ethereumはcrypto lawシステムのような一般的な実装になるかもしれない
The Blockchain paradigm
全体としてEthereumはトランザクションベースのステートマシンと見られることができる
私達はgenesisステートではじめ、最後のステートに変わるために徐々にトランザクションを実行する
著者らはEthereumの世界の標準的なバージョンとして、この最後の状態を受け入れる
ステートはある情報を含むことができる
情報とは、アカウントのバランス、評判、信頼契約?、実世界の情報に対する関連データ
要するに、現在にコンピュータによって表現されるすべては容認できる
したがって、トランザクションは2つの状態の遷移を表現する
検証の部分は重要である
はるかに無効な状態が存在する
不正な状態への変化は例えば、他の場所を増加させ、全体での均衡を保つことなくアカウントの残高を減らすようなことかもしれない
検証されたステート遷移はトランザクションを通ってもたらせる
$ \sigma_{t+1} = \gamma(\sigma_t, T)
イーサリアムの状態遷移関数:$ \gamma()
Ethereumでは、$ \sigmaと一緒の$ \gammaはかなり強力である(ほかの比較可能なシステムに比べて)
$ \gammaは任意の計算を実施するコンポーネントを許可する
$ \sigmaはトランザクション間での任意のステートを保存するコンポーネントを許可する
トランザクションはブロック内に集められる
ブロックは暗号学的ハッシュ値を参照とするような方法と一生にチェーンのように繋がれる
前のブロックと最後の状態の識別子(全体を保存するのは大きすぎて無理)と一緒にトランザクションの連なりを記録するジャーナルとしてのブロック関数
それらはまた、トランザクションシリーズを区切る
↑どんなトランザクションシリーズかといいうと、マイニングすることによってインセンティブを与えることが関連した
このインセンティブは指定されたアカウントに価値を追加し、状態遷移関数として起こる
マイニングは努力を捧げるプロセスである
↑努力とは、ブロックのシリーズが他の潜在的な競合ブロックに比べて強化される
暗号学的セキュアな証明のおかげでこの目的を達成できる
このスキーマはPoWとして知られていて、section 11.5で詳細について議論している
定式化すれば
$ \sigma_{t+1} = \Pi(\sigma_t, B)(2)
$ B = (\cdots, (T_0, T_1, \cdots), \cdots)(3)
$ \Pi(\sigma, B) = \Omega(B, \gamma(\gamma(\sigma, T_0), T_1)\cdots)(4)
ブロックのファイナリティ状態遷移関数:$ \Omega
この関数は指定したパーティに報酬を与える
ブロック:$ B
いくつかの他のコンポーネントとの間でトランザクションの連なりを含む
ブロックレベルでの状態遷移関数$ \Pi
winor.icon > トランザクションによってEthereumのステートが変化する
winor.icon > ブロックはそのトランザクションを集めたようなものなので、ブロックレベルで見れば、ブロックと前の状態をインプットに状態遷移関数によって、次の状態へ移る
winor.icon > また(4)はトランザクションを順番に実行し、ブロックによってどう状態が遷移するかに関する式
これはブロックチェーンパラダイムの基本となっている、
どんなパラアイムかというと、Ethereumだけでなく現在までのすべての分散的な合意形成トランザクションシステムのバックボーンを形式化するモデル
2.1 Value
ネットワーク内で計算量にインセンティブを与えるために、値を伝えることに合意する方法が必要である
この問題を扱うために、Ethereumは固有の通貨を持っている
Etherと呼ばれ、ETHと表記
たまに、古い英語のDで呼ばれる(winor.icon > マジ?)
最も小さなEtherの単位はWeiで表され、Wei単位のintegerで表される
$ 10^{18}Weiが$ 1Etherとなる
2.2 Witch History?
システムが非中央集権的ですべてのパーティがすでにあるブロックのあとに新しいブロックを作る機会があるので、得られた構造はブロックのtreeが必要とされる
genesisブロックから現在のブロックまでのどのパスが正しいかに関する合意を形式化するためには、合意するスキーマがなければならない。
ルートから末端までのパスでどれがベストなブロックチェーンかのようにノード間で不一致がある場合、フォークが発生する
これは、ブロックによって与えられた過去はそのシステムの複数の状態として共存するかもしれない
いくつかのノードは標準的なトランザクションを含むあるブロックであると信じている
標準的な他のブロックを信じている他のノードは根本的に異なるもしくは互換性のないトランザクションを潜在的に含んでいる
これは不確実性のようにすべてのコストで避けることである。
↑どのような不確実性かというと、システム全体ですべての信頼を殺すようなことを続ける不確実性
著者らが合意を生成するために使うこのスキーマはGHOSTプロトコル(2013)というバージョンのシンプルなものである
このプロセスはセクション10で説明される
たまに、特定のブロック高から新しいプロトコルでメインチェーンのパスが適用される。
このドキュメントはこのプロトコルのあるバージョンについて記述する
3. Conventions
正規記法のための多数の表記規則を使う、このうちのいくつかはこの研究ではかなり特殊
トップレベルとステートバリューから構成される高次の2つの集合は太字の小文字で表示される
ワールドステート:$ \bold{\sigma}
マシーンステート:$ \bold{\mu}
関数はギリシャ大文字で表すよ
例:$ \bold{\gamma}
winor.icon > 大文字・・・?
よく使う関数に関しては、英語の大文字
コスト関数$ C
$ C_{SSTORE}の場合は、$ {}_{SSTORE}オペレーションのコスト関数
外部の一般的な処理を関数として表す場合はその手法の名前について
Keccak256ハッシュ:$ KEC
Keccak512ハッシュ:$ KEC512
イーサリアムのトランザクション:$ T
$ T_nの場合はそのひとつのコンポーネントを表す
スカラや固定サイズのバイトは普通の小文字で表す
トランザクションのインデックス$ n
特殊なギリシャ文字もある
オペレーションのスタック上の要素数:$ \delta
任意の長さのシークエンスは一般的に太字の小文字
メッセージコールのアウトプットのバイト列:$ \bold{o}
全面的に、スカラーは非負な整数で、自然数の集合に属する
すべてのバイトのシークエンスは$ Bに属する(Appendix B)
また、長さを制限した場合は下付き文字にする
自然数の最大値が$ 2^256の場合は$ N_{256}
[]はインデックスを表す
一部を表現する場合は$ \mu(0..31)(scrapboxでは[]を表現できないため()で代用)
グローバルステート$ \sigmaの場合は、アカウントを表す
存在する変数を考慮する場合、著者らはルールを記した
ルールとは、与えられた定義のスコープ内の
もし、未修正のinputの値がplaceholder $ aで表現されたとしたら、修正かつ使用可能なものは$ a'と表し、中間値は$ a^*, a^{**}と表せるだろう
存在する関数を使うことを考慮するとき、関数$ fが与えられたとき、$ f^*はシーケンスの代わりに、関数マッピングの要素のようなものを表す
便利な関数として、$ lを定義する
最後のアイテムを表す
$ l(x) = x[|x| - 1
4. Blocks, State And Transactions
イーサリアム背後にあるベーシックなコンセプトに関して紹介する
トランザクション、ブロック、ステート
4.1. ワールドステート
ワールドステートはアドレスとアカウントのステート間でのマッピングである
ブロックチェーンに保存はしないで、修正マークルパトリシアツリーとして保存する
このマークルツリーはシンプルなデータベースで提供できる
著者らはこのDBをステートDBと呼んでいる
何個も利点がある
ルートノードはすべての内部データに暗号学的に依存する
このハッシュはシステム全体のステートとしてセキュアなアイデンティティとして使われる
イミュータブルなデータ構造であることはすべての前の状態を許可する
ルートハッシュに応じてシンプルに変わることによって再度コールされる前の状態
そのため、全てのルートハッシュを残している
アカウントステート:$ \bold{\sigma}(a)としたとき4つのフィールドを持つ
ナンス
スカラーでトランザクションをそのアドレスが何個送ったか
$ \bold{\sigma}(a)_n
バランス
Weiの残高
$ \bold{\sigma}(a)_b
sotrageRoot
256bitのルートハッシュ
ストレージのコンテンツがエンコードされて保存されたマークルパトリシアツリー
256ビットのintキーのKeccak 256ハッシュ値とRLPエンコードした256ビットの値
$ \bold{\sigma}(a)_s
codeHash
このアカウントのEVMのコードのハッシュ
このアドレスがメッセージを呼び出しを受信される場合に実行されるコード
これは普遍で、他のフィールドとは異なり、チェンジすることができない
すべてのコードの断片はあとで検索するために関連するハッシュ値でステートデータベースに含まれる
このコードハッシュは$ \bold{\sigma}(a)_c
コードが$ \bold{b}なら$ \bold{KEC}(\bold{b}) = \sigma(a)_c
私達は望む
ルートハッシュを参照するのではなく、内部に保存されているキーバリューペアの根底にあるものを参照すること
$ \bold{TRIE}(L_1^* (\bold{\sigma} (a)_s)) = \bold{\sigma}(a)_s
ツリーのキーバリューペアの集合のための崩壊関数?$ L_1^*は基本関数$ L_1の要素的な変換として定義される
$ L_1((k,v)) = (\bold{KEC}(k), \bold{RLP}(v))
$ where
$ k \in \mathbb{B}_{32} \land v \in \mathbb{N}
これは、$ \bold{\sigma}(a)_sはアカウントの物理的なメンバーではなく、その後のシリアライゼーションに貢献することは関係ない
もし、codeHashフィールドが空のKeccak-256ハッシュならば($ \bold{\sigma}(a)_c = \bold{KEC}(()))、ノードはシンプルなアカウントを表現する
ときどきノンコントラクトアカウントとして表される
ゆえにworldステートは$ L_Sを使った場合こう定義される
$ L_S(\sigma) = (p(a):\sigma(A) \neq \empty)
$ where
$ p(a) = (\bold{KEC}(a), \bold{RLP}((\sigma(a)_n, \sigma(a)_b, \sigma(a)_s, \sigma(a)_c)))
winor.icon > ↑アカウントのKeccak-256ハッシュがキーで、ステートのRLPシリアライゼーションがバリュー
winor.icon > 結局マークルツリーはキーバリューのCRUDができるデータ構造のため
$ L_Sはワールドステートの短いハッシュを提供するためにツリー関数と一緒に使われる
$ \forall a: \sigma(a) = \empty \lor (a \in \mathbb{B}_{20} \land v(\sigma(a)))
アカウントバリデーター関数:$ v
$ v(x) = x_n \in \mathbb{N}_{256} \land x_b \in \mathbb{N}_{256} \land x_s \in \mathbb{N}_{32} \land x_c \in \mathbb{N}_{32}
winor.icon > 値が空かアカウントが20bytesの場合、バリデータ関数がtrueを返す
winor.icon > バリデータ関数はナンス、バランス、ストレージルート、コードハッシュのバリデーションを行っている
コードを持たない、ゼロナンス、ゼロバランス場合はアカウントが空である
$ \bold{EMPTY(\sigma, a) = \sigma(a)_c = KEC(())\land \sigma(a)_n = 0 \land \sigma(a)_b = 0}
コンパイル前の呼ぶことができるコントラクトは空アカウントステートを持つことができる
これはそれらのアカウントステートは一般的にコントラクトの振る舞いを記述したコードを含まないためである
アカウントステートが存在しないもしくは空の場合、アカウントは死んでいる
$ \bold{DEAD}(\bold{\sigma}, a) = \sigma(a) = \empty \lor \bold{EMPTY(\sigma, a)}
The Transaction
トランザクションは単一の暗号学的な署名された命令である
↑この命令はイーサリアムのスコープの範囲外でアクター(ユーザーとか)によって構築された
究極の外部的なアクターが自然での人間であると仮定されている場合、ソフトウェア・ツールはその作成と普及に使われる。
2種類のTxがある
メッセージコールでの結果と関連するコードと一緒に新しいアカウントを作るTx
Txフィールド
nonce:$ T_n
スカラーバリューで、senderによって送られたトランザクションの何個目かというものを表す:
gasPrice:$ T_p
スカラーバリュー
Wei / gas
gasはトランザクションの実行結果を得るためのすべての計算コストに使用するもの
gasLimit:$ T_g
スカラー
トランザクションを実行するガスの総量
to:$ T_t
このメッセージの受取人で160bitのアドレス
もしくはContractのクリエイションの場合は$ \empty、$ \mathbb{B}_0とも表す
value:$ T_v
相手に送るWei
コントラクションを作る場合新しいアカウントを作ることへの寄付
v, r, s:$ T_w, T_r, T_s
Appendix F参考
init:$ T_i
コントラクト生成のみ対象
サイズの制限がないバイト列
アカウントを初期化する処理のときにEVMコードによって特定する
winor.icon > ぱっと読んだ感じ、r, s, vはECDSA署名に関するもの
winor.icon > r, sは署名で送るもの
initはEVMコードの一部で、ボディを返す
↑ボディとは2つめのコードの一部で、コードとはアカウントがメッセージをコールした毎に実行する内容が示されたもの
initはアカウントが作られるとき一回だけ実行され、その後破棄される
対象的にメッセージTxには↓が含まれている
data: $ T_d
制限がないバイト列でメッセージのインプットデータが含まれている
Appendix Fは関数$ S特定している
↑はトランザクションと送信者をマッピングする
また、SECP-256k1曲線のECDSAから起きる
署名するデータとして、トランザクションのハッシュ値が使われることによって
現在は、シンプルに与えられたトランザクションの送信者は$ S(T)と表すことができると主張する
$ L_T(T) =
$ (T_n, T_p, T_g, T_t, T_v, T_\bold{i}, T_w, T_r, T_s): T_t = \empty
$ (T_n, T_p, T_g, T_t, T_v, T_{\bold{d}}, T_w, T_r, T_s): \bold{otherwise}
winor.icon > ↑はコントラクト生成のトランザクションを表していて、↓はメッセージコール
全てのコンポーネントはRLPによって解釈される
任意の長さのバイト列$ T_i, T_dは例外として
$ T_* \in \mathbb{N}_{256}:(* = n,v,p,g,r,s)
$ T_w \in \mathbb{N}_{5}
$ T_d, T_i \in \mathbb{B}
where
$ \mathbb{N}_n = (P:P\in\mathbb{N} \land P < 2^n)(winor.icon > 2^nより小さい自然数)
アドレスハッシュ$ T_tはわずかに異なる
これは、20バイトのアドレスハッシュか、コントラクトの生成Txかによる違いがあるため
$ T_t \in
$ \mathbb{B}_{20} if $ T_t \neq \empty
$ \mathbb{B}_{0} otherwise
4.3. The Block
イーサリアムのブロックは情報の関連するピースの集まり(ブロックヘッダー)である
と一緒にトランザクションの情報を含み、他のブロックヘッダーの情報を含む
ブロックヘッダーはいくつかの情報から構成される
parentHash: $ H_p
Keccak 256bitのハッシュで親のブロックヘッダー
ommersHash: $ H_o
Keccak 256bitのハッシュでおじ(祖父の兄弟とかも)とかの関係に位置するブロック
beneficiary: $ H_c
160bit address
このブロックのマイニングが成功した人(報酬をもらうために送られる)
stateRoot: $ H_r
ステートツリーのルートノードのKeccak 256bitハッシュ
すべてのトランザくsyんが実行されたあとに、このルートになる
transactionsRoot: $ H_t
そのブロックのトランザクションリストによるマークルツリーのルートノードのKeccak 256ビットのハッシュで
receiptsRoot: $ H_e
Keccac256
ブロックに含まれるトランザクションのレシートのツリーのルートノードのハッシュ
logsBloom: $ H_b
ブルームフィルタ
トランザクションリスト内のそれぞれのトランザクションのレシートから得られるログエントリを含む情報からインデックスすることが可能となる
difficulty: $ H_d
ブロック生成難易度
number: $ H_i
ジェネシスブロックを0としたときのブロックナンバー
gasLimit: $ H_l
ガスリミット
現在の1ブロックあたりのガスリミット
gasUsed: $ H_g
このブロックのトランザクションでどの程度ガスが使われたか
timestamp: $ H_s
合理的なUnixtimetamp
extraData: $ H_x
任意のバイトデータ
32バイト以下
mixHash: $ H_m
256bitのハッシュ
このブロックの上で十分な計算を実施されたかを証明するナンスを含む
nonce: $ H_n
64bit value
mix-hashと混ざる
winor.icon > たぶん、mixHashとnonceはnonceが64ビットだと足りなくなったらとか・・・?(ビットコインはそうだった)
ほかの2つのコンポーネントはシンプルにommerブロックヘッダーとトランザクションのシリーズである
$ B = (B_H, B_{\bold{T}}, B_{\bold{U}})
4.3.1 Transaction Rceipt
ゼロ知識証明を使いインデキシングや検索を便利にすることに関連するトランザクションについての情報をエンコードするために、著者らはトランザクションのレシートエンコードする
↑のトランザクションは明らかに実行結果から得られる情報を含む
それぞれのレシートは$ B_{\bold{R}}(i)と表記される(i番目のトランザクション)
↑レシートはインデックスのキーとしてツリーに位置する
最終的にはこのツリーのルートハッシュは$ H_e
トランザクションのレシート、Rは4つのアイテムのタプルである
トランザクションが実行された直後、トランザクションのレシートを含むブロック使用された蓄積したガス
$ R_u
トランザクションの実行中に作られたログの集合
$ R_{\bold{l}}
これらのログの情報から構成されたブルームフィルタ
$ R_{b}
トランザクションのステータスコード
$ R_z
$ R = (R_u, R_b, R_{\bold{l}}, R_z)
関数$ L_Rはトランザクションのレシートを準備する
RLPシリアライズを用いて
$ L_R(R) = (0 \in \mathbb{B}_{256}, R_u, R_b, R_{\bold{l}})
ここで$ 0 \in \mathbb{B}_{256}はプロトコルの旧バージョンで存在する前のトランザクションルートを置き換える
ステータスコード
$ R_z \in \mathbb{N}:非負
使用済み蓄積ガス量は非負整数、ログのブルームフィルタは2048ビットのハッシュ
$ R_u \in \mathbb{N} \land R_b \in \mathbb{B_{256}}
ログのシークエンス$ R_{\bold{l}}はログの連なり$ (O_0, O_1, \cdots)
ログの要素$ Oはタプルである
ロガーのアドレス、$ O_a
空配列を許可する32バイトのログトピック:$ O_{\bold{t}}
いくつかのデータバイト:$ O_{\bold{d}}
$ O = (O_a, (O_{\bold{t}0}, O_{\bold{t}1}, \cdots), O_{\bold{d}})
$ O_a \in \mathbb{B}_{20} \land \forall_{x\in (O_a) \bigcup O_{\bold{t}}:x \in\mathbb{B}_{32}} \land O_{\bold{d}} \in \mathbb{B}
ブルームフィルタの関数$ Mはログエントリを256バイトのハッシュへと減少させる
$ M(O) = \bigvee_{x \in (O_a) \bigcup O_{\bold{t}}}(M_{3:2048}(x))
ここで、$ M_{3:2048}は特定のブルームフィルタを表す
↑与えられた任意のバイト列から2048のうち3ビットを設定する
これはバイトシーケンスのkec, cak-256ハッシュで、最初の3ペアのバイトのそれぞれ下位11ビットを取ることによってこれを行う
$ M_{3:2048}(\bold{x}:\bold{x}\in\mathbb{B}) = \bold{y}:\bold{y}\in\mathbb{B}_{256} where:
$ \bold{y} = (0,0,\ldots,0) except:
$ \forall_{i\in(0,2,4)} : \bold{\beta}_{m(\bold{x},i)}(\bold{y}) = 1
$ m(\bold{x}, i) = \bold{KEC}(\bold{x})(i,i+1) \mod 2048
ここで、$ \betaはビット参照関数
↑は$ \beta_j(\bold{x})はバイト列$ \bold{x}のインデックス$ jのビットと等しい
4.3.2 Holistic Validity
ブロックの有効性について述べる
いくつかの条件を満たすことで
それは内部的にommerブロックとの整合性が取れてなければならない
また、トランザクションのブロックハッシュとブロックに含まれるトランザクション$ B_{\bold{T}}は新しいステートのアイデンティ$ H_rの結果となる
↑はベースの状態$ \bold{\sigma}で実行された場合
$ H_r = \bold{TRIE}(L_S(\Pi(\sigma, B))) \land
$ H_o = \bold{KEC}(\bold{RLP}(L_S^*(B_U))) \land
$ H_t = \bold{TRIE}((\forall i < ||B_{\bold{T}}||, i\in \mathbb{N}:p(i,L_T(B_{\bold{T}}(i))))) \land
$ H_e = \bold{TRIE}((\forall i < ||B_{\bold{R}}||, i\in \mathbb{N}:p(i,L_R(B_{\bold{R}}(i))))) \land
$ H_b = \bigvee_{r\in B_{\bold{R}}}(\bold{r}_b)
ここで、$ p(k,v)はRLPとRLPのKVである
$ p(k,v) = (\bold{RLP}(k),\bold{RLP}(v))
さらに
$ \bold{TRIE}(L_S(\sigma)) = P(B_H)_{H_{r}}
つまり、$ \bold{TRIE}(L_S(\sigma))はマークルパトリシアツリーのルートノードハッシュ
↑$ \sigmaのバリューがRLPシリアライゼーションされたKVを含む
親ブロックから直接定義できる:$ P(B_H)
トランザクションの計算からブロックしているバリュー特にトランザクションのレシピは定義される
↑トランザクション状態蓄積関数として
$ \Piに関しては11.4で
winor.icon > ---
$ H_r: stateRoot = $ \bold{TRIE}(L_S(\Pi(\sigma, B)))
$ \Pi(\sigma_t,B) = \sigma_{t+1}
ワールドステートがブロックによって遷移する
$ L_S(\sigma) = (p(a):\sigma(a)\neq\empty)
$ p(a) = (\bold{KEC}(a), \bold{RLP}((\sigma(a)_n, \sigma(a)_b, \sigma(a)_s, \sigma(a)_c)))
すべてのワールドステート内のアドレスを、KECがキーでRLPシリアライズのバリュー形式にした集合
$ \bold{TRIE}(L_I^*(\sigma(a)_s)) = \sigma(a)_s
その、TRIEのハッシュ
だから、$ \bold{TRIE}(L_S(\Pi(\sigma, B)))はルートハッシュを表す
$ H_o: ommerHash = $ \bold{KEC}(\bold{RLP}(L_S^*(B_U)))
$ B_{\bold{U}}: ommerブロックのヘッダー
ommerブロックのヘッダーをKEC, RLPのKVにして、シリアライゼーションして、KECでハッシュする
要は、ommerブロックのヘッダーをまとめている
$ H_t:transactionHash = $ \bold{TRIE}(\forall i < ||B_{\bold{T}}||, i\in \mathbb{N}:p(i,L_T(B_{\bold{T}}(i))))
$ B_{\bold{T}}ブロック内のトランザクション
$ L_T(T) =
$ (T_n, T_p, T_g, T_t, T_v, T_\bold{i}, T_w, T_r, T_s): T_t = \empty
$ (T_n, T_p, T_g, T_t, T_v, T_{\bold{d}}, T_w, T_r, T_s): \bold{otherwise}
つまり、ブロック内のトランザクションのKEC・RLPのKVをトランザクションをマークルパトリシアツリーとしたときのルートハッシュ
$ H_e:receiptsRoot = $ H_e = \bold{TRIE}(\forall i < ||B_{\bold{R}}||, i\in \mathbb{N}:p(i,L_R(B_{\bold{R}}(i))))
$ B_Rブロック内のレシート
$ L_R(R) = (0 \in \mathbb{B}_{256}, R_u, R_b, R_{\bold{l}})
つまり、ブロック内のレシートのKEC・RLPのKVをレシートのマークルツリーとしたときのルートハッシュ
$ H_b: logsBloom = $ \bigvee_{r\in B_{\bold{R}}}(\bold{r}_b)
winor.icon > ---
winor.icon > KeccakのハッシュとRLPシリアライゼーションめっちゃ使う・・・
winor.icon > $ p(a) = (\bold{KEC}(a), \bold{RLP}((\sigma(a)_n, \sigma(a)_b, \sigma(a)_s, \sigma(a)_c)))は教養レベル
winor.icon > あとは、マークルツリーはKVってことを忘れない
4.3.3 Serialisation
ブロックとブロックヘッダーのための準備関数$ L_Bと$ L_Hは
トランザクションのレシートの準備関数$ L_Rとかなり似ていて、RLPシリアライゼーションで表すと下記のようになる
$ L_H(H) = (H_*): * = p,o,c,r,h,e,b,d,i,l,g,s,x,m
$ L_B(B)=(L_H(B_H),L_T^*(B_\bold{T}),L_H^*(B_\bold{U}))
$ \bold{where}
$ f^*((x_0,x_1,\ldots)) = (f(x_0),f(x_1),\ldots)
また、↑の$ H_*は基本的に$ \in \mathbb{B}_n \lor \mathbb{N}_n
正式なブロックの生成には厳しい条件を備えている
RLP関数は標準メソッドを提供する
↑どんな標準かというと、ある構造をバイト列に変換する標準
↑どんなバイト列かというとワイヤーorローカルストレージに送信する準備ができたもの
4.3.4 Block Header Validity
著者らは$ P(B_H)を定義
ブロック$ Bの親ブロックを表す
$ P(H) = B' : \bold{KEC}(\bold{RLP(B'_H)}) = H_p
ブロックナンバーは親ブロックに1足すだけ
$ H_i = P(H)_{H_i} + 1
標準的なディフィカリティ
$ D(H) =
$ D_0 $ \bold{if}:H_i = 0
$ \max(D_0, P(H)_{H_i} + x \times \varsigma_2 + \epsilon) $ \bold{otherwise}
$ where
$ D_0 = 131072
$ x = \lfloor\frac{P(H)_{H_d}}{2048}\rfloor
$ \varsigma_2 = \max(y - \lfloor \frac{H_S - P(H)_{H_S}}{9} \rfloor, -99)
$ y =
$ 1 $ \bold{if}:||P(H)_\bold{U}|| = 0
$ 2 $ \bold{otherwise}
$ \epsilon = \lfloor 2^{\lfloor H_i'\div100000 \rfloor -2} \rfloor
$ H_i' = max(H_i - 3000000, 0)
$ D_0はジェネシスブロックのディフィカリティ
ホームステッドディフィカリティパラメータ$ \varsigma_2は動的でブロック間の時間の恒常的な影響として使われる
↑ブロック間に時間についてはEIP2で議論されている
homesteadリリースでは、エクスポネンシャルにディフィカリティが増えるシンボル$ \epsilon はかなり遅く増加する(1000000ブロック毎)
winor.icon > 1000000ブロックとは何秒? -> 約173.61日
winor.icon > ブロック高によってディフィカリティが増加するのはどうなんだろ・・・
winor.icon > ただ、結局$ \epsilon_2がブロック間の計算量を15秒に一定にするインセンティブになるのだろう
ブロック時間の差を増加する
proof of stakeへの時間的圧力になる
この影響はdifficulty bombもしくはice ageはとして知られている
EIP-649で説明されている
winor.icon > 特定のブロックからあえてディフィカリティを上げることによって、PoSに移行する際に移行させる
$ \varsigma_2もEIP100で修正された
修正要素として分母の9を
↑unkcleブロックを平均時間とするために
最終的に、Byzantiumのリリースでは、EIP649でアイス・エイジはフェイクのブロックナンバーを入れることによって遅れるようにされた($ H_i - 3000000)
これを別の言葉で言えば、$ \epsilonとブロック間の時間をへらすことは、PoSの開発へもっと時間が必要で、ネットワークが固まってしまうのを防ぐため
標準的なガスリミットは下記の関係を満たす
$ H_l < P(H)_{H_l} + \lfloor \frac{P(H)_{H_l}}{1024} \rfloor \land
$ H_l > P(H)_{H_l} - \lfloor \frac{P(H)_{H_l}}{1024} \rfloor \land
$ H_l >= 5000
タイムスタンプは下記を満たす
$ H_s > P(H)_{H_s}
winor.icon > ビットコインではブロック時間は前のブロックの2時間以内という条件があった(あまりにも遅い時間を作らせないようにするため)
winor.icon > しかし、Ethの場合はディフィカリティの計算でタイムスタンプを用いるので、この条件だけで十分なのかもしれない
このメカニズムはブロック間の時間を安定させる
2つのブロックの間がより短い期間はディフィカリティのレベルが上がる結果になる
ゆえに、追加の計算量が必要になり、次の期間までが長くなる
逆に、もしピリオドが長すぎる場合は、ディフィカリティは減少し、次のブロックができる時間も減る
ナンスは下記を満たす
$ n <= \frac{2^{256}}{H_d} \land m = H_m
$ \bold{with} : (n,m) = \bold{PoW}(H_{n^*}, H_n, \bold{d})
ナンスとミックスハッシュがない新しいブロックヘッダー$ H_{n^*}
ミックスハッシュを計算するために必要な大きいデータの集合である現在のDAG$ \bold{d}
PoW関数は$ \bold{PoW}
↑PoWは評価する
1つめのアイテムはミックスハッシュ
正しいDAGかを証明するためのもの
2つめのアイテムは擬似乱数
暗号学的に依存する$ Hと$ \bold{d}
だいたい$ 0~2^{64}のレンジの一様分布で決まる
ディフィカリティ$ H_dに比例して予測時間はかかる
これはブロックチェーンのセキュリティの財団であり、基本的な理由である
↑のりゆうとは、なぜ攻撃ノードが新しいブロックを作り伝搬できないのかという理由
過去を改変するようなブロック
なぜなら、ナンスは上記条件をみたさなけらばならない
また、この条件はブロックの内容に依存し、それら(トランザクション、新しく作ったブロック、ディフィカリティ、オーバータイム)を変えるならは莫大な計算パワーが必要になる
ゆえに、ブロックヘッダーのバリデーションは下記のように定義できる
$ V(H) =
$ n <= \frac{2^{256}}{H_d} \land m = H_m \land
$ H_d = D(H) \land
$ H_g <= H_l \land
$ H_l < P(H)_{H_l} + \lfloor \frac{P(H)_{H_l}}{1024} \rfloor \land
$ H_l > P(H)_{H_l} - \lfloor \frac{P(H)_{H_l}}{1024} \rfloor \land
$ H_l >= 5000 \land
$ H_s > P(H)_{H_s} \land
$ H_i = P(H)_{H_i} + 1 \land
$ ||H_x|| <= 32
where $ (n,m) = \bold{PoW}(H_{n^*}, H_n, \bold{d})
5. GAS AND PAYMENT
ネットワークの乱用問題を防ぐために、すべてのプログラマブルな計算には手数料が発生する
この手数料のスケジュールはガスの単位で特定される
ゆえに、プログラマブルな計算の一部は普遍的に同意されるコストとなる
コントラクトの生成、メッセージコール
すべてのトランザクションは特定のガスの量を持っている
↑のガスはGaslimitに関連する
これは、ガスの量である
↑送信者のバランスから買われたガスの量である
アカウントのbランスが買うことにサポートされない場合は、トランザクションは不正であると考えられる
トランザクションの最後でのすべての未使用ガスは払い戻しされるので、これはガスリミットと呼ばれる
ガスはトランザクションの実行の外では存在しない
ゆえに、トラストなコードに関連するアカウントいとっては、比較的高いガスリミット設定したほうがよいかもしれない
一般的に、イーサはガスを買うために使われる
受診者アドレスへ届けるわけでなく
↑のアカウントのアドレスは通常マイナーの制御下にある
トランザクションの発行者はただである
すべてのガス価格を特定するために
↑トランザクションが選ばれるのを無視するために、マイナーがただだとしても
トランザクション上の高いガスはセンダーのコストになる
より高いEtheを支払わなければならないので
ゆえに、マイナーによってより選ばれやすくなる
マイナーは一般的に、最小のガス価格について宣伝することを選択し、取引者は自由にその価格を決めることができる
最小の承認されるガスプライスの分布が存在するので、トランザクターはトレードオフを保つ必要がある
トレードオフとはガスを低い価格にするか?トランザクションがマイナーによってすぐにブロックにいれられるか
6. Transaction execution
トランザクションの実行はイーサリアムのプロトコルの中でも最も難しいパート
状態トランザクション関数$ \gamma定義する
最初に実行されたトランザクションはすべて、本質的妥当性の初期テストに合格すると想定される
下記を含む
トランザクションが整形されたRLPフォーム
トランザクションの署名が正しい
トランザクションのナンスが正しい(送信者のナンスと等しい)
ガスリミットを超えていない
送信者のバランスが最低限ある
トランザクションの実行の定式化
$ \sigma' = \gamma(\sigma, T)
ゆえに、$ \sigma'はトランザクションを実行した後の状態
$ \gamma^gはトランザクションの実行中で使用されたガスの量を評価するために定義される
$ \gamma^{\bold{l}}はトランザクションの発生したログを評価するため
$ \gamma^{z}はトランザクションから得られる結果のステータスコードを評価すうため
6.1substate
実行中のトランザクションでは、私達は特定の情報を蓄積する
↑情報とは関連するトランザクションがすぐに行動された
このトランザクションのsubstate($ A)は下記のように表せる
$ A = (A_{\bold{s}}, A_{\bold{l}}, A_{\bold{t}}, A_{r})
$ A_{\bold{s}}
自己破壊集合?(self-destruct set)
特定のアカウントの集合
↑のアカウントとはトランザクションの完了後に破棄されるもの
$ A_{\bold{l}}
ログのシリーズ
これはVMコードの実行中でアーカイブしインデックスできるチェックポイントのシリーズ
↑この実行は、Ethereumの世界の外の見物者も追跡することが簡単になるためにコントラクトのコールを許可をする(DappsのFEとか)
$ A_{\bold{t}}
タッチしたアカウントの集合
からのそれらはトランザクションの最後に削除される
$ A_r
払い戻し残高
↑はSSTORE命令を実行することによって増加する
↑コントラクトのストレージを0以外の値から0にリセットするために
すぐには返金されないが、すべての実行コストを部分的にオフセットを持たすことを許す
$ A^0: 空のsubstate
self-destructs、log、touchedアカウント、払い戻し残高がなにも持っていないために↑を定義した
$ A^0 = (\empty,(),\empty,0)
6.2 Execution
内在的なガスは下記のように定義できる
$ g_0 =
$ \sum_{i \in T_i,T_d} G_{txdatazero} if $ i=0
$ \sum_{i \in T_i,T_d} G_{txdatanonzero} otherwise
$ + G_{txcreate} if $ T_t=0
$ +0 otherwise
$ + G_{transaction}
トランザクションに関連するEVMの初期化コードとデータバイトの配列を意味する$ T_i,T_d
↑はコントラクトを作成するトランザクションかメッセージコールかどうかに依存する
トランザクションがコントラクトの生成だった場合、$ G_{txcreate}を追加する
先行投資コスト$ v_0は下記のように計算さrた
$ v_0 = T_g T_p + T_{\bold{v}}
下記のように検証する
$ S(T) \neq \empty $ \land
$ \sigma(S(T)) \neq \empty $ \land
$ T_n = \sigma(S(T))_n $ \land
$ g_0 \leq T_g $ \land
$ v_0 \leq \sigma(S(T))_b $ \land
$ T_g \leq B_{H1} - l(B_{\bold{R}})_u
最終的な条件はすべてのトランザクションのガスの上限$ T_gと前のブロックで利用したガスが、ブロックのガスリミットよりも大きくない
トランザクション検証の実行は取り消し不可能で始まる
↑取り消し不可能とはステートを変更すること
送信者のナンス$ S(T)は1だけインクリメントされる
残高から減らすコスト$ T_g T_p
計算中に消費するガス gは$ T_g - g_0
コントラクト生成やメッセージコールの計算はステートでの結果となる
↑合法的に現在のステートと等しくなる
この変化は決定的で決して間違えない
チェックポイントのステート$ \sigma_0
$ \sigma_0 = $ \sigma expect:
$ \sigma_0(S(T))_b = $ \sigma(S(T))_b -T_g T_p
$ \sigma_0(S(T))_n = $ \sigma(S(T))_n +1
$ \sigma_pから$ \sigma_0にトランザクションタイプによって評価される場合は下記タプルであらわせる
$ (\sigma_P,g', A, z) =
$ \Lambda_4 (\sigma_0, S(T), T_o, g, T_p, T_v, T_i,0,T) if$ T_t=\empty
$ \Theta_4 (\sigma_0, S(T), T_o, T_t, T_t, g, T_p, T_v, T_v, T_d ,0,T) otherwise
gはトランザクションが存在することに対して支払うのに必要なガスを排除した残りのガス
$ g = T_g - g_0
オリジナルなトランザクション送信者$ T_o
↑EVMのコードから実行されたトランザクションによって直接トリガーされていないメッセージコールやコントラクト生成では送信者が異なる可能性があるため
$ \Sigma_4, \Lambda_4は関数の値の最初の4コンポーネントを抽出する
メッセージコールやコントラクト生成の処理後、リファウンドカウンター(余ったガスとかを再分配)はアカウントに追加しなくてはならない
$ A'_r = A_r + \sum_{i\in A_s}R_{selfdestruct}
そして、ステートはリファウンドさえる量がきまることによって、ファイナライズされる
$ g^*は残ったガス$ g'とリファウンドカウンターからの手当を足したもの
$ g^* = g' + \min(\lfloor \frac{T_g-g'}{2} \rfloor, A'_r)
すべての再分配可能な量は合法的に残ったガス$ g'に$ A_rかガスリミットから残ったガスを引いた量$ T_g -g 'の/2のどちらか小さい方
さらに、$ g^*はトランザクションが実行された後の合計ガスである
ガスのためのEtherはマイナーに与えられる
↑マイナーのアドレスは現在のブロック$ Bの受益者として特定される
したがって、下記のようにpre-finalステート$ \sigma^*を定義できる
$ \sigma^* = \sigma_P expect
$ \sigma^*(S(T))_b = \sigma_P(S(T))_b + g^*T_P
$ \sigma^*(m)_b = \sigma_P(m)_b + (T_g-g^*)T_p
$ m = B_{H_c}
winor.icon > 再分配する分のガス x ガス料金が各アカウントに再分配される
winor.icon > 使用されたガスはマイナーの残高へ加算される
消滅リストにあるか空のアカウントをすべて削除すると、最後の状態$ \sigma'になる
$ \sigma' = \sigma^*
$ \forall i \in A_S : \sigma'(i) = \empty
$ \forall i \in A_t : \sigma'(i) = \empty if $ \bold{DEAD}(\sigma^*,i)
最終的には
$ \gamma^gはすべてのガスを使ったトランザクション
$ \gamma^{\bold{l}}はトランザクションによって作られたログ
$ \gamma^zはトランザクションのステータスコードとなる
$ \gamma^g(\sigma, T) = T_g-g^*
$ \gamma^{\bold{l}}(\sigma, T) = A_{\bold{l}}
$ \gamma^z(\sigma, T) = z
これらはトランザクションのレシートを定義するのを助けるために使われ、最新のステートとナンスのバリデーションに用いられもする
7. Contract Creation
アカウントを作るときに使われる内在敵パラメータはいくつかある
送信者:$ (s)
オリジナルトランスレーター:$ (o)
利用できるガス:$ (g)
ガスプライス:$ (p)
寄付額:$ (v)
初期化EVMコード:$ \bold{i}
メッセージコールとコントラクト生成のスタックの深さ:$ (e)
ステートを修正するためのパーミッション:$ (w)
生成関数$ \Lambdaは上のパラメータから評価される
↑から新しいステートとかを生成する
$ (\sigma', g',A,z,\bold{o}) = \Lambda(\sigma, s, o, g, p,v, \bold{i}, e, w)
新しいアカウントのアドレスは送信者と送信者のナンスのRLPエンコーディング+KECハッシュにした一番左の160ビットである
$ a = B_{96..255}(\bold{KEC}(\bold{RLP}((s, \sigma(s)_n-1))))
$ B_{a..b}(X)はXの中のb〜aまでのビットを抽出して返す
winor.icon > ↑はすべてcontractのアカウントの話
winor.icon > EOAはprivate keyから決まる
最初は
アカウントナンス:1
残高:送られてきた値
storage:空
code hash:空文字のkeccak 256
式(78)〜(82)
送信された後のステート
winor.icon > $ \sigma^*(a)が作られたアカウント、$ \sigma^*(s)が送信者
winor.icon > 送信者が空もしくは、残高が0の場合、送信された後の送信者アカウントは空
winor.icon > そうでなければ、ナンスが1足され、残高が作られたアカウントへ送られたステートへとなる
最終的には初期化EVMコードの実行によってアカウントは初期化される
Sec. 9!
(83)は初期化EVMコードによって、アカウントが初期化されることを表している
$ g^**は残ってるガス
$ \sigma^{**}結果のステート
(84)〜(92)は初期化コード実行時のパラメータ
インプットのデータはない
コードの実行でガスを使い果たした場合
out-of-gas(OOG)エクセプションが発生すると著者らは呼んでいる
評価されるステートはから集合で定義され、操作全体がステートに対して影響を与えることはない
初期化コードが成功した場合、最終的なコントラクト生成コストはコードデポジットコストを払う(作成したコントラクトのコードのサイズに比例)
もし、ガスが十分でない場合、OOG例外
OOGの場合では、トランザクションのバリューは中止されたコントラクトへ送信されない
OOGが発生しない場合は、残ったガスはコントラクト作成者に再分配される。
(94)〜(97)はガス、最終的なステート、ステータスコードがコントラクト作成後にどうなるかの定式化
ガスは初期化コードからコード実行で使われたコストからコントラクトを生成するコスト(データの永続化)に使用されるガスを引いた分
ステートはアカウントがある場合、コードのハッシュが保存
7.1 Subtleties
初期化コード実行中は新しいアカウントは作られるが、コードはない
ゆえにその最中はなにもメッセージを受け付けても実行できない
もし、初期化コードが実行の終了に自己崩壊がしてしまった場合は、トランザクションを完了する前に、アカウントを削除してしまう。
↑ゾンビアカウントになってしまうので、残っているバランスとかは永久にロックされてしまう。
8. Message Call
メッセージコールの場合は下記パラメータが必要
センダー
トランザクションのオリジン発行者
レシート
実行されるためのコードのアカウント
可能なガス
バリュー
インプットデータ
現在のメッセージコールやコントラクト生成のスタックの深さ
ステートを修正するパーミッション
メッセージコールはアウトプットが追加のコンポーネントとしてある
(98)はメッセージコールによってステートが変化することを表した定式化
送信さあれる値$ vとDELEGATECALLの$ \tilde{v}は違う
(99)は最初のステートにsenderからのレシートを受け取ったステート
$ \sigma_1(r)がundefinedならば、コードorステートがなくバランスナンスが0なアカウントが作られる
(100)〜(105)は↑の仮定も取り入れた式
winor.icon > シンプルにsenderからreciverがvalue(Eth)を送信したので、バランスがそれぞれ-+された式
winor.icon > 例外として、valueが0だったり、アカウントが空だったりするケースも想定している
コントラクト生成と一緒で、例外的な方法でメッセージコールの処理が止まった場合は、ガスは返金されない
(106)〜(120)はメッセージコール実行後のステとの変化に関する式
Ethreumでは、8つの一般的な評価方法で分けられている
↑はprecompiled contractsと呼ばれる
1. 楕円曲線公開鍵復活関数
2. SHA2 256ハッシュスキーマ
3. RIPEMD 160ハッシュスキーマ
4. アイデンティティ関数
5. 冪剰余(べき乗したあとのmで割ったあとのあまり)
6. 楕円曲線の拡張
7. 楕円曲線のスカラー乗算
8. 楕円曲線のペアチェック
9. Execution Model
実行モデルはどのようにシステムのステートは与えられたデータからどのように変化されるのかを特定する
EVM
準チューリッヒ完全
準になっている理由はガスによって計算量が制限されるところから来ている
9.1 Basic
EVMはシンプルなスタックベースアーキテクチャ
word: 256bit
Keccak256、ECDSAに合わせたため
メモリもシンプルなワードアドレスバイトアレイモデル
1024 max
メモリに似ているストレージモデルもある
システムステートの一部を維持している
EVMは一般のノイマン型コンピューターではない
プログラムコードとかはvirtual ROMで保存される
例外時はステートをそのままにはしない
動作止めて、問題をエージェントへレポートする
9.2 Fee Overview
手数料は3パターンで請求される
計算量
支払いとかをするときに早く処理されたい場合
メモリーを拡張する
32バイトごとにメモリのガスフィーを払う
ストレージに関しては払い戻しがされる
ストレージの容量を圧迫することを防ぐために(全額ではないけどね)
9.3 Execution Environment
システムステートと計算ガスの残りかすはの他に実行エージェントは重要なものをもたらす
(121)はシステムステートとガスと↑の要素を実行モデルで実行したあとの結果を表す
9.4 Execution Overview
(123)〜(135)は実行によるステートの遷移について
Xが再帰関数となっており、Oはイテレータ関数
Zは例外時かを判定する
例外判定されない場合まで or Hがマシンが終了するところまで達したことを示す連なりになる場合まで、Xは再帰的に実行される
9.4.1 Machine State
マシーンステート
使用可能ガス
プログラムカウンタ
次の命令を実行するアドレス
メモリ content
メモリー上アクティブなアドレス
0〜
stack content
メモリコンテントは$ 2^256のzeroの配列
$ wは現在のオペレーションを表す
(136)は実行するコードが存在する場合は$ I_bのものを逐次実行し、そうでなければSTOP
9.4.2 Exceptional Halting
例外ストップ関数Zを(137)は表している
条件としては
ガス量が十分でない
命令が不正
不正なスタックアイテム
JUMP or JUMPIの先が不正
新しいスタックサイズが1024より大きくなってしまう
9.4.3 Jump Destination Validity
アドレスのジャンプ先が正しいか検証する関数
9.4.4 Normal Halting
正常終了する関数$ H
RETURN、REVERTは特殊
あとは空とかを返す
9.5 The Execution Cycle
Stackのアイテムは左から足されたり消えたり
(143)〜(146)は状態を更新するイテレータ関数
ガスを命令で使うガス分だけ減らす、各ステップで
Self-destructの場合はシステムステートに変化はない
10. Blocktree to blockchain
正規のブロックチェーンはルートリーフを通り全体のブロックツリーのパスを構成する
コンセンサスを得るためにはこの中でも最も重い(計算量のかかった)パスを選ぶ必要あり
blockヘッダーにdifficultyが含まれるので、その合計が最も高いチェーン
11. Block finalisation
4つのステージ
1. オマーブロックの検証
2. トランザクションの検証
3. 報酬の適用
4. ステートとブロックナンスの検証
11.1 Ommer Validation
オマーヘッダーのバリデーションは最大6個前までの関係を検証する
(155)〜(157)
オマーヘッダーは最大で2まで
11.2 Transaction Validation
gasUsedが全てのガスと一致するか
11.3 Reward Application
アプリケーションの報酬はブロックとそれぞれのommerによって決まる
生成しブロックの1/32もらえる
11.4 State & Nonce Validation
ステートのハッシュを求めて、ナンスのバリデーション
11.5 PoW
多くの人がマイニングできないと配布に型月がでるので、2つの特性を保つ必要がある
多くの人が実行可能であること
ASICとかの耐性
super linearではないべき
初期の障壁が高くなるため
ハッシュパワーの偏りがでてしまうため
ASICの耐性は2つある
多くのメモリを必要とする
12. Implementing contracts
12.1 Data Feeds
data feed contractはEthereumの外側とつながることを許可する
12.2 Random Number
13. Future directions
Appendix B Recursive Length Prefix
winor.icon > 結構使いそうなので、読む
任意のバイナリデータのエンコーディングのためのserialisationの方法
$ \mathbb{T} = \mathbb{L} \bigcup \mathbb{B}
$ \mathbb{L} = (t:t=(t_0, t_1, \cdots) \land \forall_{n<|t|}t_n \in \mathbb{T} )
$ \mathbb{B} = (b:b=(b_0, b_1, \cdots) \land \forall_{n<|b|}b_n \in \mathbb{O} )
バイト(8bit)の集合:$ \mathbb{O}
バイトのシークエンス(配列):$ \mathbb{B}
すべてのツリーのような構造の集合$ \mathbb{L}
↑1つの葉ではなく
すべてのバイト配列とその構造的なシークエンスの集合:$ \mathbb{T}
著者らは$ RLP関数を定義
2つのサブ関数で構成されている
1. 値がバイト配列の場合か
2. それ以外の場合
$ \bold{RLP}(x) =
$ R_b(\bold{x}) $ if :\bold{x} \in \mathbb{B}
$ R_l(\bold{x}) $ otherwise
もし、引数がバイト配列の場合、RLPシリアライゼーションは3つの形式のうち1つを取る
1. もしバイト配列が1つのバイトでその値が128以下の場合、インプットとアウトプットは等しい
2. バイト配列が56バイト以下の場合は、そのアウトプットはバイト配列の長さに128を加えたもので始まる+インプットに等しい
3. それ以外の場合は、出力はインプットにプレフィックスをつけたもの
↑プレフィックスとは、入力のバイト配列の長さと等しいビッグインディアンに解法された最小長
$ R_b(\bold{x}) =
$ \bold{x} $ if: ||\bold{x}|| = 1 \land \bold{x}(0) < 128
$ (128 + ||\bold{x}||)\cdot\bold{x} $ elseif: ||\bold{x}|| < 56
$ (183 + ||\bold{BE}(||\bold{x}||)||) \cdot \bold{BE}(||\bold{x}||)\cdot\bold{x} $ otherwise
$ \bold{BE}(x) = (b_0, b_1, \cdots):b_o\neq0 \land x = \sum^{n<||\bold{b}||}_{n=0} b_n\cdot 256^{||\bold{b}||-1-n}
winor.icon > BE(x)はバイトをビッグエンディアン(降順にreadするみたいな)で読めるようにしている
代わりに、$ R_lの場合($ \bold{x} \notin \mathbb{B})
$ R_l(x) =
$ (192 + ||s(\bold{x}||)\cdot s(\bold{x}) $ if ||s(\bold{x})|| < 56
$ (247 + ||\bold{BE}(||s(\bold{x})||)||)\cdot \bold{BE}(||s(\bold{x})||)\cdot s(\bold{x}) otherwise
$ s(\bold{x}) = \bold{RLP}(\bold{x}_0)\cdot \bold{RLP}(\bold{x}_1)\cdots
もし、RLPをスカラーに対して使った場合は、ビッグエンディアン解釈の特定の短いバイトになる
ゆえに、いくつかの非負整数では下記のように定義されるRLPは
$ \bold{RLP}(i:i\in\mathbb{N})=\bold{RLP}(\bold{BE}(i))
RLP解釈をする場合、もし、予測された断片がスカラとしてデコードされ、先頭のゼロがバイト配列から発見された場合、クライアントはそれが非標準であることを考慮する必要があり、そうでなければ無効なRLPのデータとして扱う
署名や浮動小数点特定のための標準なエンコードフォーマットはない
Apendix D Modified Markle Patricia Tree
意味わからない
修正版マークルパトリシアツリーは永続的なデータ構造を提供する
↑永続的なデータ構造とは、任意の長さのバイナリデータ間のマッピングをするためのもの
256ビットのバイナリ断片と任意の長さのバイナリデータの間でマッピングするために変更可能なデータ構造の観点で定義される
一般的にはデータベースとして実装される
ツリーのコアは、プロトコルの特定の唯一の要件は一つの値を提供すること
↑一つの値とは与えられたキーバリューの集合を識別するためのもの
↑キーバリューのペアは32バイトのシークエンスか空のバイトシークエンスになるかもしれない
それはプロトコルの効率的かつ効果的な実用を許す方法でツリー構造を保存し、維持するたの実装の考慮事項として残ります
公式化、キーバリューのペアが含まれている$ \bold{J}
$ \bold{J} = ((\bold{k}_0\in\mathbb{B},\bold{v}_0\in\mathbb{B}),(\bold{k}_1\in\mathbb{B},\bold{v}_1\in\mathbb{B}),\cdots)
シークエンスを考える場合、私達は一般的な記法をすれば下記のようになる
$ \forall_{\bold{I}\in\bold{J}}I = (I_0,I_1)
ビッグエンディアンを想定したもの
$ y(\bold{J}) = ((\bold{k}_0'\in\mathbb{B},\bold{v}_0\in\mathbb{B}),(\bold{k}_1'\in\mathbb{B},\bold{v}_1\in\mathbb{B}),\cdots)
$ \forall_n \forall_{i:i<2||\{bold{k}_n||} \bold{k}_n'(i) =
$ \bold{k}_n(i\div2)\div16 if i is even
$ \bold{k}_n(i\div2) \mod 16 otherwise
著者らはTRIEを定義する
↑この構造でエンコードされたとき、この集合を表すツリーのルートを定式化
$ TRIE(\bold{J}) = KEC(c(\bold{J,0}))
また関数nについても定義
↑はツリーのノードのキャパシティの関数
nodeが作られているとき、その構造をエンコードするためにRLPを使う
ストレージの複雑さをへらす手段として、構築されたRLPが32バイト未満のノードに関しては、そのRLPを直接保存する
しかし、それ以外の場合はKeccakハッシュが参照するバイト配列の優先度とする
基数木と同様の方法で、ツリーがルートから葉へ移動する場合、それは一つのキーバリューのペアとなるかもしれない
キーはその道筋を通り蓄積され、ルートからそれぞれの葉ノードの一つのnibleを取得する
radix treeでないような点は、同じプレフィックスでシェアされる複数のキーのケースかユニークなsuffixを持つシングルなキーのケースで2つのノードで最適化されている
ゆえに、横断する場合、あるものはそれおぞれから複数のニブルを潜在的に取得できるかもしれない
Leaf: 2つのアイテム構造
1つそのキーのニブルに対応する
キーの累積とルートから横断されたブランチによってすでに占領されていない
16進数のプレフィックスエンコーディング方法が仕様され、関数の2番めのパラメータはtrue
Extension
2つのアイテムで構築
1つは2以上のサイズのニブルの配列に対応し、ニブルのキーの