はじめに
初めまして。
CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です!
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。
代表的なゲームはクリプトスペルズというブロックチェーンゲームです。
今回は、トランザクションレシートの中間状態ルートフィールドを、トランザクションが成功したか失敗したかを示すステータスコード(成功は1
、失敗は0
)に置き換える提案しているEIP658についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIPについてまとめています。
概要
このEIP(Ethereum Improvement Proposal、イーサリアム改善提案)では、トランザクションの結果を記録するレシートの一部を変更する提案がされています。
レシートに含まれる「中間状態ルート」という技術的な情報を、もっとシンプルで直感的な「ステータスコード」という形に置き換えようというものです。
具体的には、Ethereumのトランザクション処理において、各トランザクション後のブロックチェーンの状態を示す「中間状態ルート」を、トランザクションが成功したか否かを表すシンプルなステータスコードに変更するというものです。
これにより、トランザクションの結果をより直接的かつ簡潔に理解できるようになります。
トランザクションがコントラクト内の操作、例えばtransfer
やmint
関数の呼び出しを含む場合でも、その実行が成功したかどうかをすぐに把握できるようになります。
中間状態ルート(Intermediate State Root)は、Ethereumブロックチェーンの各トランザクションが実行された後の、ブロックチェーンの状態を一意に表すハッシュ値です。
Ethereumでは、状態はアカウントの残高、コントラクトのコード、ストレージなどの情報を含んでおり、これらの情報は状態トライ(State Trie)というデータ構造に保存されます。
状態トライは、キーと値のペアを持つマージパトリシア(Merkle Patricia)トライで、ブロックチェーンの各ブロックに対して、そのブロックが実行された後の全てのアカウントの状態を反映します。
中間状態ルートは、あるブロック内の特定のトランザクションが実行された直後の状態トライのルートハッシュです。
中間状態ルートを使用することで、ブロックチェーンの任意の時点における正確な状態を検証することができます。
これにより、トランザクションの結果がブロックチェーンの状態にどのように影響を与えたかを追跡し、検証することが可能になります。
しかし、この情報は非常に技術的な詳細を含んでおり、一般のユーザーや開発者にとって直感的ではない可能性があります。
そのため、中間状態ルートをステータスコードに置き換えることで、トランザクションの成功や失敗をより直接的に表現し、ブロックチェーンの操作をより理解しやすくする試みがなされています。
State Trie
State Trie(状態トライ)は、Ethereumブロックチェーンにおける全てのアカウントの状態(残高、ストレージ、ノンス、コントラクトコードなど)を格納するためのデータ構造です。
Ethereumでは、この状態トライを使用して、ブロックチェーンの任意の時点での全てのアカウントの正確な状態を維持および追跡します。
状態トライは、マークルパトリシア(Merkle Patricia)トライという特殊な種類のトライを使用して実装されています。
このデータ構造は、効率的な検索、挿入、削除操作を可能にし、データの一貫性と完全性を保証します。
状態トライの特徴と機能
-
一意性と検証
- 状態トライのルートハッシュは、トライ内の全てのデータを一意に表すため、このハッシュ値を変更するにはトライ内のデータを変更する必要があります。
- これにより、データの改ざんを防ぎ、ブロックチェーンの状態の検証を可能にします。
-
効率的なデータアクセス
- マークルパトリシアトライは、データの追加、更新、検索において高い効率を提供します。
- これはブロックチェーンのパフォーマンスに直接影響を与えます。
-
軽量ノードのサポート
- 状態トライの一部のみを持つことで、フルノードと同じレベルのセキュリティを維持しながら、より少ないリソースでブロックチェーンと対話する軽量ノード(Light Nodes)をサポートします。
Ethereumの状態トライは、ブロックチェーンの透明性とセキュリティを保証する上で中心的な役割を果たしており、スマートコントラクトやトランザクションがブロックチェーンの状態に与える影響を正確に追跡することを可能にします。
参考: https://medium.com/@eiki1212/ethereum-state-trie-architecture-explained-a30237009d4e
レシート
「レシート」とは、Ethereumブロックチェーンにおけるトランザクションの実行結果を記録した証拠です。
トランザクションがブロックに取り込まれると、そのトランザクションに関連したレシートが生成されます。
このレシートには、トランザクションの実行に関する重要な情報が含まれており、トランザクションが正常に完了したかどうか(成功または失敗)、使用されたガスの量、トランザクションによって発生したイベント(スマートコントラクトからのログ出力など)などが記載されています。
レシートが含む主な情報
-
トランザクションの状態
- トランザクションが成功したか失敗したかを示すステータスコード。
- 成功した場合は「
1
」(またはtrue
)、失敗した場合は「0
」(またはfalse
)が設定されます。
-
ガス使用量
- トランザクションの実行に使用されたガスの総量。
- ガスはトランザクションの計算資源を測る単位で、トランザクションの複雑さや実行に必要な計算量によって消費されます。
-
ログ情報
- トランザクションの実行中にスマートコントラクトによって生成されたログ。
- これには、イベントのパラメータや、そのイベントが発生したスマートコントラクトのアドレスなどが含まれます。
レシートは、トランザクションがブロックチェーンにどのような影響を与えたかを把握するために重要です。
開発者はレシートを使用してトランザクションの結果を確認し、デバッグ情報を取得し、スマートコントラクトが予期した通りに動作しているかを検証することができます。
また、ユーザーはレシートを通じて、自分のトランザクションが正常に処理されたかどうかを確認できます。
動機
EIP140によってREVERT
オペコードが導入された後、トランザクションが失敗したかどうかを判断するために全てのガスが消費されたかどうかだけを見る方法はもはや有効ではありません。
これは、トランザクションが失敗した場合でも全てのガスを消費しないで終了することができるためです。
その結果、トランザクションが成功したか、そしてその中で行われた状態の変更が実際にブロックチェーンに適用されたかを確認する明確な方法がなくなりました。
フルノードはトランザクションを再び実行し、その結果を通じてトランザクションの成功または失敗を判定する機能を提供することができますが、この方法は全てのノードタイプに適用可能ではありません。
特に、ファストノードは特定のポイント以降のトランザクションについてのみこの情報を提供でき、ライトノードではこの機能を提供することができません。
この問題を解決するために、古くなった中間状態ルートを廃止し、代わりにトランザクションの成功または失敗を示す単純な戻りステータス(成功は「1
」、失敗は「0
」)をレシートに含めることを提案しています。
これにより、トランザクションの呼び出し元はトランザクションが成功したかどうかを簡単に判断できるようになり、また、レシートから戻りデータが省略されていた問題も修正されます。
ファストノード
ファストノードは、Ethereumネットワーク内で使用されるノードの一種で、フルノードよりも高速に同期を完了させることができます。
通常、Ethereumネットワークに参加するノードは、ネットワーク上の全てのトランザクションと状態の履歴をダウンロードして検証する必要がありますが、これは時間がかかるプロセスです。
ファストノードの特徴と動作
-
効率的な同期
- ファストノードは、ブロックヘッダー、トランザクション、および受領書(レシート)のみをダウンロードし、それぞれを検証します。
- これにより、ノードはネットワークに迅速に同期することができます。
-
状態のダウンロード
- 一定数の最新ブロックに到達すると(これをピボットポイントと呼びます)、ファストノードはネットワークから現在の完全な状態トライをダウンロードし始めます。
- このプロセスは、ノードがフルノードとして機能するための全ての情報を持つまで続きます。
-
リソースの使用
- ファスト同期は、フルノードの同期に比べてディスクスペースと処理時間を大幅に削減しますが、ピボットポイント以前のブロックに関する完全な状態情報は持ちません。
ファストノードは、特に新しいユーザーや、リソースに制約がある環境でEthereumネットワークに参加したい場合に有用です。
しかし、ピボットポイント以前のトランザクションや状態に関する詳細情報を取得する機能は限られており、これにアクセスするにはフルノードの機能が必要になる場合があります。
ファストノードは、ネットワークの安全性と整合性を維持するために、最終的にはフルノードと同様のデータセットを保持するようになりますが、その同期プロセスはより効率的で時間がかからないという利点があります。
参考: https://techmedia-think.hatenablog.com/entry/2021/03/21/165151
仕様
ブロック番号がBYZANTIUM_FORK_BLKNUM
以上のブロックでは、中間状態ルートがステータスコードに置き換えられます。
ここで、「0
」は失敗を示し(トランザクションやトップレベルのコールがrevert
する原因となる任意の操作によるもの)、一方「1
」は成功を示します。
これにより、ブロックチェーンの各トランザクションの結果がより明確になり、トランザクションやコントラクトの実行が成功したかどうかを簡単に判断できるようになります。
補足
この提案は、トランザクションの成功/失敗の状態を取得することを可能にする最小限の変更であり、Metropolis(Ethereumのアップグレードの一つ)において既存の機能を維持しつつ、最小限の中断や追加の作業を伴うように設計されています。
つまり、Ethereumネットワークの機能性を損なうことなく、トランザクションの結果をより簡単に把握できるようにするための、効率的で実用的な改善を意味しています。
この変更により、開発者やユーザーはトランザクションが正常に完了したかどうかを簡単に確認できるようになり、Ethereumの使い勝手が向上します。
引用
Nick Johnson nick@ethereum.org, "EIP-658: Embedding transaction status code in receipts," Ethereum Improvement Proposals, no. 658, June 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-658.
最後に
今回は「トランザクションレシートの中間状態ルートフィールドを、トランザクションが成功したか失敗したかを示すステータスコード(成功は1
、失敗は0
)に置き換える提案しているEIP658」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!