# [EIP2681] Etherumアカウントのnonceの範囲を制限する提案を理解しよう！

> アカウントの「nonce」を0から2^64-1の範囲に限定するという提案です。ここでの「nonce」とは、特定の操作やトランザクションが一度だけ行われることを保証するための一意の番号のことです。

- URL: https://cardene.dev/articles/5c48b751358eb85d6821
- 公開日: 2024-02-10
- 更新日: 2024-02-10
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

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

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

https://eips.ethereum.org/EIPS/eip-2681

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

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

## 概要

アカウントの「`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`まで増えることができますが、それ以上は増えません。
これにより、トランザクションが一意であることが保証され、セキュリティが強化されます。

:::message
#### 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**がチェーン識別子を使用するより洗練された方法を導入して以来、時代遅れになりました。

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

[\[EIP155\] Ethereumネットワークでリプレイ攻撃を防ぐ仕組みを理解しよう！](/articles/2526432899353e4a0225)

### クライアントの対応
多くのクライアント（例えば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などからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

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

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4
