イーサリアムの課題の1つは、デフォルトでは、どのブロックチェーンプロトコルの膨張と複雑さが時間とともに増大することです。これは2つの場所で起こります:
イーサリアムが長期的に持続するためには、これらのトレンドに対して強力なカウンタープレッシャーが必要です。時間の経過とともに複雑さと膨張を減らす必要があります。しかし、同時に、ブロックチェーンの優れた特性の一つである永続性を保持する必要があります。NFTをオンチェーンに置いたり、トランザクションのcalldataにラブノートを入れたり、100万ドルを含むスマートコントラクトをオンチェーンに置いたりすることができます。10年間洞窟に入っても、出てきた時にまだ読み取りや対話ができるように待っていてくれます。DAppが完全に分散化し、アップグレードキーを削除することに自信を持つためには、依存関係が彼らを壊すようなアップグレードを行わないことを確信する必要があります-特にL1自体。
The Purge、2023のロードマップ。
これらの2つのニーズの間のバランスを取り、肥大化、複雑化、および劣化を最小化または逆転させながら、連続性を保ち続けることは、私たちがそれに取り組むならば完全に可能です。生物はそれを行うことができます:時間の経過とともにほとんどの生物は年をとりますが、幸運なわずかな人々はしない. さらに、社会システムも 極めて長寿いくつかの機会において、イーサリアムはすでに成功を示しています: プルーフ・オブ・ワークはなくなり、SELFDESTRUCTオペコードはほとんどなくなり、ビーコンチェーンノードはすでに過去のデータを最大6か月まで保存しています。イーサリアムの将来的なスケーラビリティ、技術的な持続可能性、そしてセキュリティにとって安定した最終的な結果に向けて、より一般的な方法でこの道筋を立てることは、イーサリアムの長期的なスケーラビリティ、技術的な持続可能性、そしてセキュリティの究極の課題です。
この執筆時点では、完全同期されたEthereumノードには約1.1テラバイトディスクスペースについて実行クライアント, プラスコンセンサスクライアントの数百ギガバイト。 これの大部分は歴史です: 過去のブロック、取引、および受領に関するデータであり、そのほとんどは数年前のものです。 これは、ガスリミットが全く増加しなくても、ノードのサイズが毎年数百ギガバイトずつ増加していることを意味します。
履歴ストレージの問題を簡素化する重要な特徴は、各ブロックが前のブロックをハッシュリンクを介して指すためです(そして、その他構造)、現在についてのコンセンサスを持つことは、歴史に関するコンセンサスを得るのに十分です。ネットワークが最新のブロックについてコンセンサスを得ている限り、過去のブロック、トランザクション、または状態(口座残高、ナンス、コード、ストレージ)は、マークル証明とともに単一のアクターによって提供でき、証明により、他の人はその正確性を検証できます。コンセンサスが N/2-of-N 信頼モデルであるのに対し、履歴は1-of-N 信頼モデル.
これにより、履歴を保存する方法について多くのオプションが開かれます。自然な選択肢の 1 つは、各ノードがデータのごく一部しか格納しないネットワークです。これは、何十年にもわたってトレントネットワークが機能してきた方法です:ネットワーク全体で何百万ものファイルを保存および配布する一方で、各参加者はそのうちのいくつかしか保存および配布しません。直感に反するかもしれませんが、このアプローチは必ずしもデータの堅牢性を低下させるわけではありません。ノードをより手頃な価格で稼働させることで、100,000ノードを持つネットワークに到達し、各ノードが履歴のランダムな10%を保存することができれば、各データは10,000回複製され、各ノードがすべてを保存する10,000ノードネットワークとまったく同じ複製係数になります。
今日、Ethereumはすでにすべてのノードが永遠にすべての履歴を保存するモデルから離れ始めています。コンセンサスブロック(すなわち、ステークの証明に関連する部分)は約6ヶ月間だけ保存されます。ブロブは約18日間だけ保存されます。EIP-4444目標は、歴史的なブロックとレシートの保存期間を1年にすることです。長期的な目標は、各ノードがすべてを保存する責任がある調和した期間(約18日間)を持ち、その後、Ethereumノードで構成されるピアツーピアネットワークが古いデータを分散的に保存することです。
レプリケーションファクターを変更せずに、耐久性を高めるために、消失訂正符号を使用することができます。実際には、データの可用性サンプリングをサポートするために、既にブロブは消失訂正符号化されています。最も簡単な解決策は、この消失訂正符号を再利用し、実行およびコンセンサスブロックデータをブロブに格納することです。
主な残された作業には、実行履歴、さらにはコンセンサスとブロブを保存するための具体的な分散ソリューションを構築し、統合することが含まれます。これに対する最も簡単な解決策は、(i)既存のトレントライブラリを単に導入することです。(ii)イーサリアムネイティブのソリューションと呼ばれるものがあります。ポータルネットワーク. これらのいずれかが導入されると、EIP-4444をオンにすることができます。 EIP-4444自体はハードフォークを必要としませんが、新しいネットワークプロトコルバージョンが必要です。 そのため、すべてのクライアントで同時に有効にすることに価値があります。さもなければ、フルヒストリをダウンロードすることを期待して他のノードに接続するクライアントが実際にはそれを取得しないリスクがあります。
主なトレードオフは、いかにして「古代」の歴史的データを利用可能にするかです。最も簡単な解決策は、明日から古代の歴史を保存するのをただやめて、既存のアーカイブノードとさまざまな中央集権的なプロバイダーに依存することです。これは簡単ですが、これによりEthereumは永続的な記録の場所としての地位が弱まります。より困難ですが安全な道は、まず分散型のネットワークであるトレントネットワークを構築し、統合することです。ここで、「いかにして努力するか」には2つの次元があります:
(1)に対する最大限の偏執的なアプローチは、カストディの証明: 実際には、各ステークの証明の検証者に、一定割合の履歴を保存することを義務付け、定期的にそれを暗号化的にチェックする必要があります。 より穏やかなアプローチは、各クライアントが保存する履歴の割合について任意の標準を設定することです。
(2)について、基本的な実装は、すでに行われている作業を行うだけです。Portalはすでに、Ethereumの全履歴を含むERAファイルを保存しています。より徹底的な実装では、これを実際に同期プロセスに接続することが含まれます。これにより、フル履歴ストアリングノードまたはアーカイブノードを同期したい場合、他にアーカイブノードがオンラインに存在しなくても、Portalネットワークから直接同期することができます。
ノードの実行やスピンアップを非常に簡単にしたいのであれば、ヒストリーストレージの要件を減らすことは、ステートレスよりも間違いなく重要です:ノードに必要な1.1 TBのうち、~300 GBがステートで、残りの~800 GBがヒストリーです。イーサリアムノードがスマートウォッチ上で動作し、セットアップに数分しかかからないというビジョンは、ステートレスとEIP-4444の両方が実装されている場合にのみ実現可能です。
また、履歴ストレージを制限することで、新しいイーサリアムノードの実装では、プロトコルの最新バージョンのみをサポートすることがより現実的になり、はるかにシンプルになります。たとえば、2016年のDoS攻撃中に作成された空のストレージスロットがすべて削除されたため、多くのコード行を安全に削除できます削除. プルーフオブステークへの切り替えが遠い昔の話となった今、クライアントは安全にすべてのプルーフオブワーク関連のコードを削除できます。
クライアントが履歴の保存を不要にする場合でも、クライアントのストレージ要件は引き続き増加し続けます。それは、状態の持続的な成長によるものです:口座残高とnonce、契約コードと契約ストレージ。ユーザーは一度のコストを支払うことで、現在および将来のイーサリアムクライアントに永久に負担を課すことができます。
状態は歴史よりも「期限切れ」にするのははるかに困難です。なぜなら、EVMは基本的に、状態オブジェクトが作成されると、それが常にそこにあり、いつでも任意のトランザクションによって読み取られるという前提に基づいて設計されているからです。状態のない状態を導入すると、おそらくこの問題はそれほど悪くないという議論があります。実際に状態を保存する必要があるのは、専門的なブロックビルダーだけであり、他のすべてのノード(インクルージョンリスト(プロダクション!)は状態を持たずに実行できます。ただし、状態をあまりにも依存しすぎることは避けたいという議論もあり、最終的にはイーサリアムを分散化するために状態を期限切れにしたいという意見もあります。
今日、新しい状態オブジェクトを作成するとき(これは3つの方法のいずれかで起こる可能性があります:(i)新しいアカウントにETHを送信する、(ii)コードで新しいアカウントを作成する、(iii)以前に触れられていないストレージスロットを設定する)、その状態オブジェクトは永遠にその状態にあります。代わりに、オブジェクトが時間の経過とともに自動的に期限切れになることを望んでいます。主要な課題は、これを実現する方法であり、3つの目標を達成することです。
これらの目標を満たさなくても、問題を解決するのは簡単です。たとえば、各状態オブジェクトに有効期限のカウンターも格納し (ETH を燃やすことで延長でき、読み取りまたは書き込みのたびに自動的に行われます)、状態をループして期限切れの状態オブジェクトを削除するプロセスを持たせることができます。ただし、これにより余分な計算 (およびストレージ要件) が発生し、使いやすさの要件を満たしていないことは間違いありません。開発者も、ストレージ値がゼロにリセットされることがあるエッジケースについて推論するのに苦労するでしょう。有効期限タイマーを契約全体にすると、開発者にとっては技術的には楽になりますが、開発者はストレージの継続的なコストをユーザーに「転嫁」する方法を考えなければならないため、経済性が難しくなります。
これらは、イーサリアムのコア開発コミュニティが長年苦労してきた問題であり、提案などが含まれています。ブロックチェーンの賃貸「そして」リジェネシス「最終的に、私たちは提案のベストな部分を組み合わせ、2つのカテゴリーの「既知の最悪の解決策」に収斂しました。」
部分的な状態の期限切れ提案はすべて同じ原則に基づいています。状態をチャンクに分割します。誰もがチャンクが空であるか非空であるかの「トップレベルのマップ」を永久に保存します。各チャンク内のデータは、そのデータが最近アクセスされた場合のみ保存されます。データが保存されなくなった場合、誰でもデータが何であったかを証明することでそのデータを復元する「復活」メカニズムがあります。
これらの提案の主な違いは、(i)「最近」という用語の定義方法、および(ii)「チャンク」という用語の定義方法です。具体的な提案の1つは、EIP-7736、「茎と葉」デザインをベースに構築されたVerkleツリーに導入されました(ただし、任意の形式の状態のない状態と互換性があります、例:バイナリツリー)。この設計では、隣接するヘッダー、コード、およびストレージスロットは、同じ「ステム」の下に保存されます。ステムの下に保存されるデータは、最大で256 * 31 = 7,936バイトです。多くの場合、アカウントの全ヘッダーとコード、および多くのキーストレージスロットは、すべて同じステムの下に保存されます。特定のステムの下に保存されているデータが6ヶ月間読み取られず、書き込まれない場合、データはもはや保存されず、データへの32バイトのコミットメント(「スタブ」)のみが保存されます。そのデータにアクセスする将来の取引では、スタブに対して確認される証明を伴ってデータを「蘇生」する必要があります。
同様のアイデアを実装する他の方法があります。たとえば、口座レベルの細分化だけでは不十分な場合、木の1/232の各部分を同様の茎と葉のメカニズムによって統制されるような仕組みを作ることができます。
これはインセンティブのために少し複雑です。攻撃者は非常に大量のデータを単一の部分木に入れ、毎年単一のトランザクションを送信することでクライアントに非常に大量の状態を永久に保存させることができます。更新コストを木のサイズに比例させる(または更新期間を逆比例させる)と、誰かが同じ部分木に非常に大量のデータを入れることで別のユーザーを悩ますことができます。部分木のサイズに基づいて粒度を動的に制限することで、これらの問題を両方とも制限することができます。例えば、連続した216 = 65536個の状態オブジェクトを「グループ」として扱うことができます。ただし、これらのアイデアはより複雑です。ステムベースのアプローチはシンプルであり、インセンティブを整合させることができます。なぜなら、通常、ステムの下にあるデータは同じアプリケーションまたはユーザーに関連しているからです。
どうすれば、32バイトのスタブさえも永続的な状態の成長を避けたいと思った場合はどうなりますか?これは困難な問題です。@vbuterin/state_size_management#Resurrection-conflicts">resurrection conflicts: 状態オブジェクトが削除され、後でEVM実行がまったく同じ位置に別の状態オブジェクトを配置する場合、その後、元の状態オブジェクトに関心を持つ人が戻ってきて回復しようとするとどうなりますか? 部分的な状態の有効期限が切れると、スタブは新しいデータの作成を防ぎます。 完全な状態の有効期限が切れると、スタブさえ保存する余裕がありません。
アドレス期間ベースの設計は、これを解決するための最もよく知られたアイデアです。1 つのステートツリーでステート全体を格納するのではなく、ステートツリーのリストが絶えず増え、読み書きされたステートは最新のステートツリーに保存されます。新しい空の状態ツリーは、期間ごとに 1 回追加されます (1 年と考えてください)。古い状態ツリーは固まっています。フル ノードは、最新の 2 つのツリーのみを格納することが期待されます。状態オブジェクトが 2 期間タッチされず、期限切れのツリーに陥った場合でも、読み取りまたは書き込みは可能ですが、トランザクションはマークル証明を証明する必要があり、一度タッチされると、コピーが最新のツリーに再び保存されます。
これをすべてユーザーフレンドリーかつ開発者フレンドリーにするための重要な考え方は、アドレス期間という概念です。アドレス期間とは、アドレスの一部である数値です。重要なルールの1つは、アドレス期間Nのアドレスは、期間Nまたはそれ以降(つまり状態ツリーリストの長さがNに達した後)にのみ読み取りまたは書き込みできることです。新しい状態オブジェクト(たとえば、新しい契約、または新しいERC20残高)を保存する場合、状態オブジェクトをアドレス期間がNまたはN-1である契約に入れておけば、以前にその場所に何もなかったことを証明する必要なくすぐに保存できます。一方、古いアドレス期間における状態の追加や編集には、証明が必要です。
この設計は、Ethereumの現在の特性のほとんどを保存し、余分な計算を非常に軽くし、アプリケーションをほぼ現在のままに書くことを可能にし(ERC20は書き直す必要があり、アドレス期間Nでアドレスの残高が子契約に格納されるようにするために)、そして「ユーザーが5年間洞窟に入る」問題を解決します。ただし、1つ大きな問題があります:アドレスはアドレス期間に収まるように20バイトを超えて拡張する必要があります。
提案の1つは、バージョン番号、アドレス期間番号、および拡張ハッシュを含む新しい32バイトアドレス形式を導入することです。
0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF
赤色はバージョン番号です。ここでオレンジ色に着色された4つのゼロは、将来的にシャード番号が収まる可能性のある空白スペースとして意図されています。緑色はアドレス期間番号です。青色は26バイトのハッシュです。
ここでの主な課題は、後方互換性です。既存の契約は20バイトのアドレスを基に設計されており、しばしばアドレスが正確に20バイトであるという前提を明示的に前提として、緻密なバイトパッキング技術を使用しています。@ipsilonこれを解決するための一つのアイデアは、古いスタイルの契約が新しいスタイルのアドレスとやり取りする際に、新しいスタイルのアドレスの20バイトのハッシュを見る変換マップを使用することです。しかし、これを安全にするには重要な複雑さが関わります。
別のアプローチは逆方向に進むことです:私たちは直ちにいくつかの2128サイズのサブレンジ(例:0xffffffffで始まるすべてのアドレス)を禁止し、その範囲を使用してアドレス周期と14バイトのハッシュを導入します。
0xfffffff000169125d5dFcb7B8C2659029395bdF
この方法が犠牲にしている主要な点は、カウンターファクチャルなアドレスにセキュリティリスクを導入します: アドレスは資産や権限を保持していますが、そのコードはまだチェーンに公開されていません。リスクは、あるアドレスが(まだ公開されていない)コードの1つを持つと主張するが、同じアドレスにハッシュされる別の有効なコードも持っている場合に関わります。そのような衝突を計算するには、2つが必要です80今日のハッシュ; アドレススペースの縮小により、この数値は非常にアクセスしやすい2になります56ハッシュ値。
キーウェリスクエリア、単一の所有者によって保持されるウォレットではない仮想アドレスは、現在は比較的まれなケースですが、マルチL2の世界に入るにつれてより一般的になる可能性があります。唯一の解決策は、このリスクを単純に受け入れることですが、この問題になり得るすべての一般的なユースケースを特定し、効果的な回避策を考案することです。
私は将来について4つの可能性のある道があると考えています:
重要な点は、アドレススペースの拡張と縮小に関する難しい問題が、アドレス形式の変更に依存する状態の有効期限のスキームが実装されるかどうかに関係なく、いずれ対処されなければならないということです。今日、およそ280アドレスの衝突を生成するためにハッシュを使用すると、すでに非常に豊富なリソースを持つアクターにとって実現可能な計算負荷が発生します:GPUでは約2つのハッシュを処理することができます27ハッシュ、1年間実行すると2を計算できます52、だからすべて世界には約2^30個のGPUがあります約1/4年で衝突を計算でき、FPGAとASICはこれをさらに加速する可能性があります。将来、このような攻撃はますます多くの人々に開かれるようになるでしょう。したがって、完全な状態の有効期限を実装する実際のコストは、非常に困難なアドレスの問題を解決する必要があるため、それほど高くないかもしれません。
状態の期限切れを行うことで、1つの状態ツリー形式から別の形式への移行が容易になる可能性があります。なぜなら、移行手順は必要ないからです。新しい形式を使用して新しいツリーを作成し、後で古いツリーを変換するためにハードフォークを行うだけで済むからです。したがって、状態の期限切れは複雑ですが、ロードマップの他の側面を簡素化する利点があります。
セキュリティ、アクセシビリティ、およびの重要な前提条件の一つ信頼性のある中立性シンプルさこそが鍵です。プロトコルが美しくシンプルであれば、バグの可能性が低くなります。新しい開発者がどの部分でも作業できる可能性が高くなります。特定の利益に対抗するためにも公平で容易に防御できる可能性が高くなります。残念ながら、プロトコルは他の社会システムと同様に、デフォルトでは時間の経過と共に複雑になります。イーサリアムがますます複雑になる黒い穴に入ることを望まないのであれば、次のいずれかを行う必要があります:(i)変更を停止し、プロトコルを堅固化する、(ii)実際に機能を削除し、複雑さを減らすことができる。プロトコルへの変更を少なくし、時間の経過とともに少なくとも少しの複雑さを取り除くという中間の道も可能です。このセクションでは、どのようにして複雑さを減らすか、または取り除くかについて説明します。
プロトコルの複雑さを減らす大きな単一の修正はありません。問題の本質は、多くの小さな修正があることです。
ほぼ完成した一つの例は、他を扱う方法の青写真として機能することができます。@vbuterin/selfdestruct">SELFDESTRUCTオペコードの削除。SELFDESTRUCTオペコードは、1つのブロック内のストレージスロットの数を無制限に変更できる唯一のオペコードであり、DoS攻撃を回避するためにクライアントは大幅に複雑なものを実装する必要がありました。オペコードの本来の目的は、自発的な状態クリアを可能にし、時間の経過とともに状態サイズを小さくすることでした。実際には、それを使用することになった人はほとんどいませんでした。ザオペコードは弱体化されましたDencunハードフォークで、同じトランザクションで作成された自己破壊アカウントのみを許可するようにする。これにより、DoSの問題が解決し、クライアントコードの大幅な簡素化が可能になる。将来的には、おそらく命令コードを完全に削除することが理にかなっているでしょう。
これまでに特定されたプロトコル簡素化の機会の主な例には、次のようなものがあります。まず、EVMの外部にある例をいくつか紹介します。これらは比較的非侵襲的であるため、より短い時間枠でコンセンサスを得て実装することが容易です。
今、EVM内部にあるいくつかの例:
この種の機能の簡素化を行う際の主なトレードオフは、(i) どれだけ簡素化し、どれだけ速く行うか、と (ii) 旧バージョンとの互換性です。 Ethereumの価値は、アプリケーションを展開し、将来数年間も問題なく動作することができるプラットフォームであることから生じます。同時に、その理想を過度に追求することも可能ですが、ウィリアム・ジェニングス・ブライアンを言い換える「バックワード互換性の十字架にイーサリアムを磔する」。イーサリアム全体で特定の機能を使用するアプリケーションが2つしかなく、1つは数年間ユーザーがいなく、もう1つはほとんど使用されずに総額57ドルの価値を保証している場合、その機能を削除し、必要な場合には被害者に57ドルを支払うべきです。
より広範な社会的問題は、非緊急の後方互換性を壊す変更のための標準化されたパイプラインを作成することにあります。 これに取り組む1つの方法は、SELFDESTRUCTプロセスなどの既存の先例を調査および拡張することです。 このパイプラインは次のように見えます。
ステップ1とステップ4の間には、複数年にわたるパイプラインがあり、どのアイテムがどのステップにあるかについての明確な情報があります。その時点で、機能削除パイプラインの活発さと速さと、より保守的で他のプロトコル開発の領域により多くのリソースを投入するというトレードオフがありますが、まだパレートフロンティアからは遠いです。
EVMに提案された重要な変更の一連の中で、最も重要なのはEVMオブジェクトフォーマット(EOF). EOFは、ガスの観測不可能性、コードの観測性の禁止(即ち、CODECOPYなし)、静的なジャンプのみを許可するなど、多くの変更を導入します。目標は、より強力な特性を持つ方法でEVMをアップグレードできるようにすることであり、同時に後方互換性を維持します(EOF前のEVMも引き続き存在します)。
これには、新しいEVMの機能を追加し、より制限の強いEVMへの移行を促進するという利点があります。ただし、古いEVMを廃止および削除する方法を見つけることができない限り、プロトコルの複雑さが大幅に増加します。主要な問題の1つは、EVMの簡素化提案においてEOFが果たす役割です。特にEVM全体の複雑さを低減することが目標である場合には、どのような役割を果たすのでしょうか。
ロードマップの残りの「改善」提案の多くも、古い機能の簡素化の機会でもあります。上記の例をいくつか繰り返します。
より過激なEthereumの簡略化戦略は、プロトコルをそのままにしておくが、プロトコルの機能の大部分を契約コードに移すことです。
これの最も極端なバージョンは、Ethereum L1を「技術的に」ビーコンチェーンにすることであり、最小限のVM(例えば、RISC-V, カイロ、または証明システムに特化したさらに最小限のもの)を使用して、他の人が独自のロールアップを作成できるようにします。このEVMは、これらのロールアップの最初の1つになります。これは皮肉なことに、2019-20年の実行環境提案ただし、SNARKsのおかげで、実際に実装することがかなり可能になります。
より穏やかなアプローチは、ビーコンチェーンと現在のEthereum実行環境の関係をそのまま維持するが、EVMを現地で交換することです。 RISC-V、Cairo、または他のVMを新しい「公式Ethereum VM」として選び、すべてのEVM契約を新しいVMコードに強制変換し、元のコードのロジックを解釈するコード(コンパイルまたは解釈)にします。 理論的には、「ターゲットVM」がEOFのバージョンである場合、これは実現可能です。
イーサリアムの課題の1つは、デフォルトでは、どのブロックチェーンプロトコルの膨張と複雑さが時間とともに増大することです。これは2つの場所で起こります:
イーサリアムが長期的に持続するためには、これらのトレンドに対して強力なカウンタープレッシャーが必要です。時間の経過とともに複雑さと膨張を減らす必要があります。しかし、同時に、ブロックチェーンの優れた特性の一つである永続性を保持する必要があります。NFTをオンチェーンに置いたり、トランザクションのcalldataにラブノートを入れたり、100万ドルを含むスマートコントラクトをオンチェーンに置いたりすることができます。10年間洞窟に入っても、出てきた時にまだ読み取りや対話ができるように待っていてくれます。DAppが完全に分散化し、アップグレードキーを削除することに自信を持つためには、依存関係が彼らを壊すようなアップグレードを行わないことを確信する必要があります-特にL1自体。
The Purge、2023のロードマップ。
これらの2つのニーズの間のバランスを取り、肥大化、複雑化、および劣化を最小化または逆転させながら、連続性を保ち続けることは、私たちがそれに取り組むならば完全に可能です。生物はそれを行うことができます:時間の経過とともにほとんどの生物は年をとりますが、幸運なわずかな人々はしない. さらに、社会システムも 極めて長寿いくつかの機会において、イーサリアムはすでに成功を示しています: プルーフ・オブ・ワークはなくなり、SELFDESTRUCTオペコードはほとんどなくなり、ビーコンチェーンノードはすでに過去のデータを最大6か月まで保存しています。イーサリアムの将来的なスケーラビリティ、技術的な持続可能性、そしてセキュリティにとって安定した最終的な結果に向けて、より一般的な方法でこの道筋を立てることは、イーサリアムの長期的なスケーラビリティ、技術的な持続可能性、そしてセキュリティの究極の課題です。
この執筆時点では、完全同期されたEthereumノードには約1.1テラバイトディスクスペースについて実行クライアント, プラスコンセンサスクライアントの数百ギガバイト。 これの大部分は歴史です: 過去のブロック、取引、および受領に関するデータであり、そのほとんどは数年前のものです。 これは、ガスリミットが全く増加しなくても、ノードのサイズが毎年数百ギガバイトずつ増加していることを意味します。
履歴ストレージの問題を簡素化する重要な特徴は、各ブロックが前のブロックをハッシュリンクを介して指すためです(そして、その他構造)、現在についてのコンセンサスを持つことは、歴史に関するコンセンサスを得るのに十分です。ネットワークが最新のブロックについてコンセンサスを得ている限り、過去のブロック、トランザクション、または状態(口座残高、ナンス、コード、ストレージ)は、マークル証明とともに単一のアクターによって提供でき、証明により、他の人はその正確性を検証できます。コンセンサスが N/2-of-N 信頼モデルであるのに対し、履歴は1-of-N 信頼モデル.
これにより、履歴を保存する方法について多くのオプションが開かれます。自然な選択肢の 1 つは、各ノードがデータのごく一部しか格納しないネットワークです。これは、何十年にもわたってトレントネットワークが機能してきた方法です:ネットワーク全体で何百万ものファイルを保存および配布する一方で、各参加者はそのうちのいくつかしか保存および配布しません。直感に反するかもしれませんが、このアプローチは必ずしもデータの堅牢性を低下させるわけではありません。ノードをより手頃な価格で稼働させることで、100,000ノードを持つネットワークに到達し、各ノードが履歴のランダムな10%を保存することができれば、各データは10,000回複製され、各ノードがすべてを保存する10,000ノードネットワークとまったく同じ複製係数になります。
今日、Ethereumはすでにすべてのノードが永遠にすべての履歴を保存するモデルから離れ始めています。コンセンサスブロック(すなわち、ステークの証明に関連する部分)は約6ヶ月間だけ保存されます。ブロブは約18日間だけ保存されます。EIP-4444目標は、歴史的なブロックとレシートの保存期間を1年にすることです。長期的な目標は、各ノードがすべてを保存する責任がある調和した期間(約18日間)を持ち、その後、Ethereumノードで構成されるピアツーピアネットワークが古いデータを分散的に保存することです。
レプリケーションファクターを変更せずに、耐久性を高めるために、消失訂正符号を使用することができます。実際には、データの可用性サンプリングをサポートするために、既にブロブは消失訂正符号化されています。最も簡単な解決策は、この消失訂正符号を再利用し、実行およびコンセンサスブロックデータをブロブに格納することです。
主な残された作業には、実行履歴、さらにはコンセンサスとブロブを保存するための具体的な分散ソリューションを構築し、統合することが含まれます。これに対する最も簡単な解決策は、(i)既存のトレントライブラリを単に導入することです。(ii)イーサリアムネイティブのソリューションと呼ばれるものがあります。ポータルネットワーク. これらのいずれかが導入されると、EIP-4444をオンにすることができます。 EIP-4444自体はハードフォークを必要としませんが、新しいネットワークプロトコルバージョンが必要です。 そのため、すべてのクライアントで同時に有効にすることに価値があります。さもなければ、フルヒストリをダウンロードすることを期待して他のノードに接続するクライアントが実際にはそれを取得しないリスクがあります。
主なトレードオフは、いかにして「古代」の歴史的データを利用可能にするかです。最も簡単な解決策は、明日から古代の歴史を保存するのをただやめて、既存のアーカイブノードとさまざまな中央集権的なプロバイダーに依存することです。これは簡単ですが、これによりEthereumは永続的な記録の場所としての地位が弱まります。より困難ですが安全な道は、まず分散型のネットワークであるトレントネットワークを構築し、統合することです。ここで、「いかにして努力するか」には2つの次元があります:
(1)に対する最大限の偏執的なアプローチは、カストディの証明: 実際には、各ステークの証明の検証者に、一定割合の履歴を保存することを義務付け、定期的にそれを暗号化的にチェックする必要があります。 より穏やかなアプローチは、各クライアントが保存する履歴の割合について任意の標準を設定することです。
(2)について、基本的な実装は、すでに行われている作業を行うだけです。Portalはすでに、Ethereumの全履歴を含むERAファイルを保存しています。より徹底的な実装では、これを実際に同期プロセスに接続することが含まれます。これにより、フル履歴ストアリングノードまたはアーカイブノードを同期したい場合、他にアーカイブノードがオンラインに存在しなくても、Portalネットワークから直接同期することができます。
ノードの実行やスピンアップを非常に簡単にしたいのであれば、ヒストリーストレージの要件を減らすことは、ステートレスよりも間違いなく重要です:ノードに必要な1.1 TBのうち、~300 GBがステートで、残りの~800 GBがヒストリーです。イーサリアムノードがスマートウォッチ上で動作し、セットアップに数分しかかからないというビジョンは、ステートレスとEIP-4444の両方が実装されている場合にのみ実現可能です。
また、履歴ストレージを制限することで、新しいイーサリアムノードの実装では、プロトコルの最新バージョンのみをサポートすることがより現実的になり、はるかにシンプルになります。たとえば、2016年のDoS攻撃中に作成された空のストレージスロットがすべて削除されたため、多くのコード行を安全に削除できます削除. プルーフオブステークへの切り替えが遠い昔の話となった今、クライアントは安全にすべてのプルーフオブワーク関連のコードを削除できます。
クライアントが履歴の保存を不要にする場合でも、クライアントのストレージ要件は引き続き増加し続けます。それは、状態の持続的な成長によるものです:口座残高とnonce、契約コードと契約ストレージ。ユーザーは一度のコストを支払うことで、現在および将来のイーサリアムクライアントに永久に負担を課すことができます。
状態は歴史よりも「期限切れ」にするのははるかに困難です。なぜなら、EVMは基本的に、状態オブジェクトが作成されると、それが常にそこにあり、いつでも任意のトランザクションによって読み取られるという前提に基づいて設計されているからです。状態のない状態を導入すると、おそらくこの問題はそれほど悪くないという議論があります。実際に状態を保存する必要があるのは、専門的なブロックビルダーだけであり、他のすべてのノード(インクルージョンリスト(プロダクション!)は状態を持たずに実行できます。ただし、状態をあまりにも依存しすぎることは避けたいという議論もあり、最終的にはイーサリアムを分散化するために状態を期限切れにしたいという意見もあります。
今日、新しい状態オブジェクトを作成するとき(これは3つの方法のいずれかで起こる可能性があります:(i)新しいアカウントにETHを送信する、(ii)コードで新しいアカウントを作成する、(iii)以前に触れられていないストレージスロットを設定する)、その状態オブジェクトは永遠にその状態にあります。代わりに、オブジェクトが時間の経過とともに自動的に期限切れになることを望んでいます。主要な課題は、これを実現する方法であり、3つの目標を達成することです。
これらの目標を満たさなくても、問題を解決するのは簡単です。たとえば、各状態オブジェクトに有効期限のカウンターも格納し (ETH を燃やすことで延長でき、読み取りまたは書き込みのたびに自動的に行われます)、状態をループして期限切れの状態オブジェクトを削除するプロセスを持たせることができます。ただし、これにより余分な計算 (およびストレージ要件) が発生し、使いやすさの要件を満たしていないことは間違いありません。開発者も、ストレージ値がゼロにリセットされることがあるエッジケースについて推論するのに苦労するでしょう。有効期限タイマーを契約全体にすると、開発者にとっては技術的には楽になりますが、開発者はストレージの継続的なコストをユーザーに「転嫁」する方法を考えなければならないため、経済性が難しくなります。
これらは、イーサリアムのコア開発コミュニティが長年苦労してきた問題であり、提案などが含まれています。ブロックチェーンの賃貸「そして」リジェネシス「最終的に、私たちは提案のベストな部分を組み合わせ、2つのカテゴリーの「既知の最悪の解決策」に収斂しました。」
部分的な状態の期限切れ提案はすべて同じ原則に基づいています。状態をチャンクに分割します。誰もがチャンクが空であるか非空であるかの「トップレベルのマップ」を永久に保存します。各チャンク内のデータは、そのデータが最近アクセスされた場合のみ保存されます。データが保存されなくなった場合、誰でもデータが何であったかを証明することでそのデータを復元する「復活」メカニズムがあります。
これらの提案の主な違いは、(i)「最近」という用語の定義方法、および(ii)「チャンク」という用語の定義方法です。具体的な提案の1つは、EIP-7736、「茎と葉」デザインをベースに構築されたVerkleツリーに導入されました(ただし、任意の形式の状態のない状態と互換性があります、例:バイナリツリー)。この設計では、隣接するヘッダー、コード、およびストレージスロットは、同じ「ステム」の下に保存されます。ステムの下に保存されるデータは、最大で256 * 31 = 7,936バイトです。多くの場合、アカウントの全ヘッダーとコード、および多くのキーストレージスロットは、すべて同じステムの下に保存されます。特定のステムの下に保存されているデータが6ヶ月間読み取られず、書き込まれない場合、データはもはや保存されず、データへの32バイトのコミットメント(「スタブ」)のみが保存されます。そのデータにアクセスする将来の取引では、スタブに対して確認される証明を伴ってデータを「蘇生」する必要があります。
同様のアイデアを実装する他の方法があります。たとえば、口座レベルの細分化だけでは不十分な場合、木の1/232の各部分を同様の茎と葉のメカニズムによって統制されるような仕組みを作ることができます。
これはインセンティブのために少し複雑です。攻撃者は非常に大量のデータを単一の部分木に入れ、毎年単一のトランザクションを送信することでクライアントに非常に大量の状態を永久に保存させることができます。更新コストを木のサイズに比例させる(または更新期間を逆比例させる)と、誰かが同じ部分木に非常に大量のデータを入れることで別のユーザーを悩ますことができます。部分木のサイズに基づいて粒度を動的に制限することで、これらの問題を両方とも制限することができます。例えば、連続した216 = 65536個の状態オブジェクトを「グループ」として扱うことができます。ただし、これらのアイデアはより複雑です。ステムベースのアプローチはシンプルであり、インセンティブを整合させることができます。なぜなら、通常、ステムの下にあるデータは同じアプリケーションまたはユーザーに関連しているからです。
どうすれば、32バイトのスタブさえも永続的な状態の成長を避けたいと思った場合はどうなりますか?これは困難な問題です。@vbuterin/state_size_management#Resurrection-conflicts">resurrection conflicts: 状態オブジェクトが削除され、後でEVM実行がまったく同じ位置に別の状態オブジェクトを配置する場合、その後、元の状態オブジェクトに関心を持つ人が戻ってきて回復しようとするとどうなりますか? 部分的な状態の有効期限が切れると、スタブは新しいデータの作成を防ぎます。 完全な状態の有効期限が切れると、スタブさえ保存する余裕がありません。
アドレス期間ベースの設計は、これを解決するための最もよく知られたアイデアです。1 つのステートツリーでステート全体を格納するのではなく、ステートツリーのリストが絶えず増え、読み書きされたステートは最新のステートツリーに保存されます。新しい空の状態ツリーは、期間ごとに 1 回追加されます (1 年と考えてください)。古い状態ツリーは固まっています。フル ノードは、最新の 2 つのツリーのみを格納することが期待されます。状態オブジェクトが 2 期間タッチされず、期限切れのツリーに陥った場合でも、読み取りまたは書き込みは可能ですが、トランザクションはマークル証明を証明する必要があり、一度タッチされると、コピーが最新のツリーに再び保存されます。
これをすべてユーザーフレンドリーかつ開発者フレンドリーにするための重要な考え方は、アドレス期間という概念です。アドレス期間とは、アドレスの一部である数値です。重要なルールの1つは、アドレス期間Nのアドレスは、期間Nまたはそれ以降(つまり状態ツリーリストの長さがNに達した後)にのみ読み取りまたは書き込みできることです。新しい状態オブジェクト(たとえば、新しい契約、または新しいERC20残高)を保存する場合、状態オブジェクトをアドレス期間がNまたはN-1である契約に入れておけば、以前にその場所に何もなかったことを証明する必要なくすぐに保存できます。一方、古いアドレス期間における状態の追加や編集には、証明が必要です。
この設計は、Ethereumの現在の特性のほとんどを保存し、余分な計算を非常に軽くし、アプリケーションをほぼ現在のままに書くことを可能にし(ERC20は書き直す必要があり、アドレス期間Nでアドレスの残高が子契約に格納されるようにするために)、そして「ユーザーが5年間洞窟に入る」問題を解決します。ただし、1つ大きな問題があります:アドレスはアドレス期間に収まるように20バイトを超えて拡張する必要があります。
提案の1つは、バージョン番号、アドレス期間番号、および拡張ハッシュを含む新しい32バイトアドレス形式を導入することです。
0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF
赤色はバージョン番号です。ここでオレンジ色に着色された4つのゼロは、将来的にシャード番号が収まる可能性のある空白スペースとして意図されています。緑色はアドレス期間番号です。青色は26バイトのハッシュです。
ここでの主な課題は、後方互換性です。既存の契約は20バイトのアドレスを基に設計されており、しばしばアドレスが正確に20バイトであるという前提を明示的に前提として、緻密なバイトパッキング技術を使用しています。@ipsilonこれを解決するための一つのアイデアは、古いスタイルの契約が新しいスタイルのアドレスとやり取りする際に、新しいスタイルのアドレスの20バイトのハッシュを見る変換マップを使用することです。しかし、これを安全にするには重要な複雑さが関わります。
別のアプローチは逆方向に進むことです:私たちは直ちにいくつかの2128サイズのサブレンジ(例:0xffffffffで始まるすべてのアドレス)を禁止し、その範囲を使用してアドレス周期と14バイトのハッシュを導入します。
0xfffffff000169125d5dFcb7B8C2659029395bdF
この方法が犠牲にしている主要な点は、カウンターファクチャルなアドレスにセキュリティリスクを導入します: アドレスは資産や権限を保持していますが、そのコードはまだチェーンに公開されていません。リスクは、あるアドレスが(まだ公開されていない)コードの1つを持つと主張するが、同じアドレスにハッシュされる別の有効なコードも持っている場合に関わります。そのような衝突を計算するには、2つが必要です80今日のハッシュ; アドレススペースの縮小により、この数値は非常にアクセスしやすい2になります56ハッシュ値。
キーウェリスクエリア、単一の所有者によって保持されるウォレットではない仮想アドレスは、現在は比較的まれなケースですが、マルチL2の世界に入るにつれてより一般的になる可能性があります。唯一の解決策は、このリスクを単純に受け入れることですが、この問題になり得るすべての一般的なユースケースを特定し、効果的な回避策を考案することです。
私は将来について4つの可能性のある道があると考えています:
重要な点は、アドレススペースの拡張と縮小に関する難しい問題が、アドレス形式の変更に依存する状態の有効期限のスキームが実装されるかどうかに関係なく、いずれ対処されなければならないということです。今日、およそ280アドレスの衝突を生成するためにハッシュを使用すると、すでに非常に豊富なリソースを持つアクターにとって実現可能な計算負荷が発生します:GPUでは約2つのハッシュを処理することができます27ハッシュ、1年間実行すると2を計算できます52、だからすべて世界には約2^30個のGPUがあります約1/4年で衝突を計算でき、FPGAとASICはこれをさらに加速する可能性があります。将来、このような攻撃はますます多くの人々に開かれるようになるでしょう。したがって、完全な状態の有効期限を実装する実際のコストは、非常に困難なアドレスの問題を解決する必要があるため、それほど高くないかもしれません。
状態の期限切れを行うことで、1つの状態ツリー形式から別の形式への移行が容易になる可能性があります。なぜなら、移行手順は必要ないからです。新しい形式を使用して新しいツリーを作成し、後で古いツリーを変換するためにハードフォークを行うだけで済むからです。したがって、状態の期限切れは複雑ですが、ロードマップの他の側面を簡素化する利点があります。
セキュリティ、アクセシビリティ、およびの重要な前提条件の一つ信頼性のある中立性シンプルさこそが鍵です。プロトコルが美しくシンプルであれば、バグの可能性が低くなります。新しい開発者がどの部分でも作業できる可能性が高くなります。特定の利益に対抗するためにも公平で容易に防御できる可能性が高くなります。残念ながら、プロトコルは他の社会システムと同様に、デフォルトでは時間の経過と共に複雑になります。イーサリアムがますます複雑になる黒い穴に入ることを望まないのであれば、次のいずれかを行う必要があります:(i)変更を停止し、プロトコルを堅固化する、(ii)実際に機能を削除し、複雑さを減らすことができる。プロトコルへの変更を少なくし、時間の経過とともに少なくとも少しの複雑さを取り除くという中間の道も可能です。このセクションでは、どのようにして複雑さを減らすか、または取り除くかについて説明します。
プロトコルの複雑さを減らす大きな単一の修正はありません。問題の本質は、多くの小さな修正があることです。
ほぼ完成した一つの例は、他を扱う方法の青写真として機能することができます。@vbuterin/selfdestruct">SELFDESTRUCTオペコードの削除。SELFDESTRUCTオペコードは、1つのブロック内のストレージスロットの数を無制限に変更できる唯一のオペコードであり、DoS攻撃を回避するためにクライアントは大幅に複雑なものを実装する必要がありました。オペコードの本来の目的は、自発的な状態クリアを可能にし、時間の経過とともに状態サイズを小さくすることでした。実際には、それを使用することになった人はほとんどいませんでした。ザオペコードは弱体化されましたDencunハードフォークで、同じトランザクションで作成された自己破壊アカウントのみを許可するようにする。これにより、DoSの問題が解決し、クライアントコードの大幅な簡素化が可能になる。将来的には、おそらく命令コードを完全に削除することが理にかなっているでしょう。
これまでに特定されたプロトコル簡素化の機会の主な例には、次のようなものがあります。まず、EVMの外部にある例をいくつか紹介します。これらは比較的非侵襲的であるため、より短い時間枠でコンセンサスを得て実装することが容易です。
今、EVM内部にあるいくつかの例:
この種の機能の簡素化を行う際の主なトレードオフは、(i) どれだけ簡素化し、どれだけ速く行うか、と (ii) 旧バージョンとの互換性です。 Ethereumの価値は、アプリケーションを展開し、将来数年間も問題なく動作することができるプラットフォームであることから生じます。同時に、その理想を過度に追求することも可能ですが、ウィリアム・ジェニングス・ブライアンを言い換える「バックワード互換性の十字架にイーサリアムを磔する」。イーサリアム全体で特定の機能を使用するアプリケーションが2つしかなく、1つは数年間ユーザーがいなく、もう1つはほとんど使用されずに総額57ドルの価値を保証している場合、その機能を削除し、必要な場合には被害者に57ドルを支払うべきです。
より広範な社会的問題は、非緊急の後方互換性を壊す変更のための標準化されたパイプラインを作成することにあります。 これに取り組む1つの方法は、SELFDESTRUCTプロセスなどの既存の先例を調査および拡張することです。 このパイプラインは次のように見えます。
ステップ1とステップ4の間には、複数年にわたるパイプラインがあり、どのアイテムがどのステップにあるかについての明確な情報があります。その時点で、機能削除パイプラインの活発さと速さと、より保守的で他のプロトコル開発の領域により多くのリソースを投入するというトレードオフがありますが、まだパレートフロンティアからは遠いです。
EVMに提案された重要な変更の一連の中で、最も重要なのはEVMオブジェクトフォーマット(EOF). EOFは、ガスの観測不可能性、コードの観測性の禁止(即ち、CODECOPYなし)、静的なジャンプのみを許可するなど、多くの変更を導入します。目標は、より強力な特性を持つ方法でEVMをアップグレードできるようにすることであり、同時に後方互換性を維持します(EOF前のEVMも引き続き存在します)。
これには、新しいEVMの機能を追加し、より制限の強いEVMへの移行を促進するという利点があります。ただし、古いEVMを廃止および削除する方法を見つけることができない限り、プロトコルの複雑さが大幅に増加します。主要な問題の1つは、EVMの簡素化提案においてEOFが果たす役割です。特にEVM全体の複雑さを低減することが目標である場合には、どのような役割を果たすのでしょうか。
ロードマップの残りの「改善」提案の多くも、古い機能の簡素化の機会でもあります。上記の例をいくつか繰り返します。
より過激なEthereumの簡略化戦略は、プロトコルをそのままにしておくが、プロトコルの機能の大部分を契約コードに移すことです。
これの最も極端なバージョンは、Ethereum L1を「技術的に」ビーコンチェーンにすることであり、最小限のVM(例えば、RISC-V, カイロ、または証明システムに特化したさらに最小限のもの)を使用して、他の人が独自のロールアップを作成できるようにします。このEVMは、これらのロールアップの最初の1つになります。これは皮肉なことに、2019-20年の実行環境提案ただし、SNARKsのおかげで、実際に実装することがかなり可能になります。
より穏やかなアプローチは、ビーコンチェーンと現在のEthereum実行環境の関係をそのまま維持するが、EVMを現地で交換することです。 RISC-V、Cairo、または他のVMを新しい「公式Ethereum VM」として選び、すべてのEVM契約を新しいVMコードに強制変換し、元のコードのロジックを解釈するコード(コンパイルまたは解釈)にします。 理論的には、「ターゲットVM」がEOFのバージョンである場合、これは実現可能です。