はじめに

初めまして。 CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です! スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

代表的なゲームはクリプトスペルズというブロックチェーンゲームです。

今回は、アカウントnonceを0から2^64-1の範囲に制限することで、システムの効率を向上させる提案しているEIP2681についてまとめていきます!

以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。

他にも様々なEIPについてまとめています。

概要

アカウントの「nonce」を0から2^64-1の範囲に限定するという提案です。 ここでの「nonce」とは、特定の操作やトランザクションが一度だけ行われることを保証するための一意の番号のことです。 これを使うことで、同じ操作が2回以上行われるのを防ぎます。 例えば、オンラインバンキングの送金処理において、同じ送金が2回行われないようにするためにnonceが使われます。

ここでの範囲、つまり0から2^64-1というのは、数字の限界を示しています。 2^64-1は、64ビットの整数で表せる最大の数です。 これは非常に大きな数で、約1.84 x 10^19(1844京)に相当します。 この範囲内であれば、実用上はほとんど無限と言ってもいいほどのトランザクションを扱うことができます。

あなたのアカウントが行う各トランザクションには、0から始まって次第に1ずつ増えていく番号(nonce)が割り当てられます。 そして、この番号は2^64-1まで増えることができますが、それ以上は増えません。 これにより、トランザクションが一意であることが保証され、セキュリティが強化されます。

nonce

ブロックチェーンにおける「nonce」の役割を理解するために、イーサリアムのトランザクションを具体例として考えてみましょう。

イーサリアムのトランザクションとNonce

イーサリアムは、スマートコントラクトを実行できるブロックチェーンプラットフォームです。ユーザーがイーサリアム上でトランザクション(例えば、ETHの送金やスマートコントラクトの実行)を行う際、そのトランザクションはユニークである必要があります。ここで、nonceが重要な役割を果たします。

Nonceの役割

イーサリアムの各アカウントには、nonceが割り当てられています。 このnonceは、そのアカウントが行ったトランザクションの数を表します。 アカウントが新しく作成されたとき、nonceは0から始まります。 アカウントがトランザクションを行うたびに、nonceは1ずつ増加します。

具体例

  1. アカウント作成
    • Aliceが新しいイーサリアムアカウントを作成しました。
    • この時点でのAliceのアカウントnonceは0です。
  2. 初トランザクション
    • AliceがBobに1ETHを送るトランザクションを行います。
    • このトランザクションのnonceは0です(Aliceのアカウントにとってこれが最初のトランザクションだからです)。
  3. トランザクションの確認
    • トランザクションがブロックチェーンに追加され、確認されると、Aliceのアカウントnonceは1に増加します。
  4. 2回目のトランザクション
    • Aliceが再び別のトランザクションを行うと、このトランザクションのnonceは1になります(これがAliceのアカウントにとって2番目のトランザクションだからです)。

なぜ重要か?

このシステムにより、トランザクションが一意に識別され、順序付けられます。 トランザクションの順序は特に重要で、例えばAliceが残高を超えてETHを送ろうとした場合、トランザクションは順序に従って処理され、不正なトランザクションは拒否されます。 また、nonceはリプレイ攻撃を防ぐのにも役立ちます。 攻撃者が既に行われたトランザクションを再度ブロックチェーンに送信しようとしても、そのトランザクションのnonceは既に使用されているため、ネットワークによって無効とみなされます。

動機

現在、イーサリアムのブロックチェーンにおいて、各アカウントは「nonce」と呼ばれる一意の番号を持っています。 このnonceはトランザクションが行われるたびに増加し、アカウントのトランザクションが一意であることを保証します。 しかしこのnonceは、理論上はどんな大きさの数値でも取り得る「任意の長さの符号なし整数」として定義されています。 これは、ブロックチェーンのデータ構造内で扱うには非効率的です。 特にブロックチェーンの「状態証人」と呼ばれる部分で、システムが全てのトランザクションの履歴を検証する時に、このような大きな数値を扱うのは最適ではありません。

そこで提案されているEIPでは、nonceをより効率的に扱うための新しい方法が提案されています。 これにより、データの扱いが簡単になり、ブロックチェーンの処理速度や効率が向上する可能性があります。

さらに、この変更はトランザクションのフォーマットにも影響を与えるかもしれません。 現在、他のいくつかの提案でもトランザクションの改善が検討されており、このEIPによるnonceの扱いの変更が、それらの提案と組み合わせて、より大きな改善をもたらす可能性があります。

最後に、nonceを現在の256ビットの数値ではなく、より小さなデータとして扱うことができれば、イーサリアムのクライアント(イーサリアムネットワークに接続してトランザクションを処理するソフトウェア)におけるデータ管理が簡単になり、わずかながらですがシステムの性能向上に寄与する可能性があります。

仕様

提案されている変更では、ブロックチェーンの始まり(ジェネシス)から遡って2つの新しい制約を導入することを考慮しています。

トランザクションの無効化

nonceが2^64-1に達するかそれを超えるトランザクションを無効とみなします。 つまり、あるアカウントのnonceが2^64-1になった時点で、そのアカウントはこれ以上のトランザクションを行うことができなくなります。 これは、nonceの最大値を2^64-1に制限することで、トランザクションの数に上限を設けることを意味します。

CREATEおよびCREATE2命令の制約

アカウントのnonceが2^64-1の場合、CREATEおよびCREATE2命令の実行は結果としてスタックに0をプッシュして終了します。 CREATEとCREATE2は、新しいスマートコントラクトをブロックチェーン上にデプロイするための命令です。 この制約により、nonceが最大値に達したアカウントは新しいコントラクトを作成できなくなります。 さらに、このケースではinitcode(コントラクトの初期化コード)の実行に必要なガス(トランザクションを処理するために必要な手数料)は差し引かれません。 これは、実質的にトランザクションが実行されないため、ガスの消費も発生しないという理由からです。

これらの制約は、ブロックチェーンのセキュリティと整合性を高めるために提案されています。 nonceの最大値を制限することで、アカウントによる無限のトランザクションやコントラクトの作成を防ぎ、システムの負荷を軽減することができます。 また、これらの変更はブロックチェーンの基本ルールに影響を与えるため、過去に遡って適用されることが提案されています。 これにより、ブロックチェーンの全履歴を通じて一貫性が保たれ、ルールの変更が将来のトランザクションにのみ影響することなく、過去のトランザクションにも適用されます。

補足

提案されているnonceの上限に達することは非常に稀であり、その理由と背景について説明しています。

達成の難しさ

提案されているnonceの上限、つまり2^64-1に達する、またはそれを超えることは極めて不可能に近いです。 仮に外部トランザクションを通じてこの限界に到達しようとする場合、そのコストは最低でも21000(トランザクションの最小ガス料金)×(2^64-1)となり、これは約387兆3816億2565万479万583万915千ガスに相当します。この量のガス料金は実質的に支払い不可能なほど高額であり、そのため実際にこの上限に達することはほぼあり得ません。

歴史的背景

過去には、Mordenテストネットでは、メインネットのトランザクションと区別するために、新しいアカウントの開始nonceを2^20に設定していました。 しかし、このリプレイ保護の方法は、EIP155がチェーン識別子を使用するより洗練された方法を導入して以来、時代遅れになりました。

EIP155については以下の記事を参考にしてください。

クライアントの対応

多くのクライアント(例えばgo-ethereum)では、すでにnonceフィールドを64ビットとして扱っています。 これは、システムが実際に扱うことができるnonceの範囲を反映しており、提案された上限は実際の運用においてすでに考慮されていると言えます。

無効化の理由

nonceが2^64-1であるトランザクションが無効とされる理由は、そのトランザクションがブロックチェーンに含まれた後、送信者アカウントのnonceが2^64-1を超えてしまう可能性があるためです。 ブロックチェーンシステムは、各トランザクション後にアカウントのnonceをインクリメントします。 したがって、最大値に達した状態でさらにインクリメントすると、システムの整合性が損なわれるため、このようなトランザクションは最初から無効とされます。

この説明から、nonceの上限設定は理論的なものであり、実際の運用上はその限界に達することはほとんど考えられないということが分かります。 また、この上限設定は、過去の実装や現在のクライアントの実装とも一致しており、システムの整合性を保つために必要な措置です。

互換性

このテキストは、ブロックチェーン(特にイーサリアムに関連している可能性が高い)におけるある変更提案について述べています。この変更は、理論上は破壊的(既存のシステムや運用に大きな変更をもたらす)なものですが、実際には既存の状態や運用に影響を与えることはないと説明しています。

理由

現在のアカウント状態

2020年11月時点で、イーサリアムネットワーク上には、nonceが提案された上限を超えるアカウントは存在しません。 nonceの最大値が約29百万であるアカウント(0xea674fdde714fd979de3edf0f56aa9716b898ec8と識別されるアカウント)が、最高のnonce値を持つアカウントとして記録されています。 これは、提案された上限(2^64-1)に比べると非常に小さい数値であり、現状のアカウントのnonceがこの制限に達していることはありません。

既存の実装

go-ethereum(イーサリアムを動作させるための主要なクライアントソフトウェアの一つ)は、すでにこの制限を部分的に実装しています。 具体的には、go-ethereumの内部でアカウントのnonceを表すstate.Account.Nonceとトランザクションデータを表すtypes.txdata.AccountNonceは64ビットの数値として扱われています。 これは、nonceの上限が2^64-1であるという提案と一致しており、go-ethereumは既にこの上限を実質的に尊重しています。

結論

提案された変更は技術的には「破壊的変更」と見なされますが、実際のイーサリアムネットワークの運用には影響を与えないと予想されます。これは、現在のアカウントのnonceが提案された上限に近づいていないこと、および主要なクライアントが既にこの制限を部分的に導入しているためです。したがって、この変更は既存のシステムやユーザーにとって透明であり、実際の運用には影響を与えないことが予想されます。

引用

Alex Beregszaszi (@axic), "EIP-2681: Limit account nonce to 2^64-1," Ethereum Improvement Proposals, no. 2681, April 2020. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2681.

最後に

今回は「アカウントnonceを0から2^64-1の範囲に制限することで、システムの効率を向上させる提案しているEIP2681」についてまとめてきました! いかがだったでしょうか?

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!

他の媒体でも情報発信しているのでぜひ他も見ていってください!