# 不変性チェック

不変性チェックは、XRP Ledgerの安全機能です。これは、通常のトランザクション処理とは別に、すべての取引において特定の「不変量」が真であることを保証する一連のチェックで構成されています。

多くの安全機能がそうであるように、私たちは不変性チェックが実際に何もする必要がないことを望んでいます。しかし、XRP Ledger の不変量は XRP Ledger のトランザクション処理に対するハードリミットを定義しているため、それを理解することは有用であり、万が一不変量チェックに違反したためにトランザクションが失敗した場合に問題を認識するために有用です。

不変性はトリガーされるべきではありませんが、まだ発見されていない、あるいは作成されてもいないバグからXRP Ledgerの整合性を確保するものです。

## なぜ存在するのか

- XRP Ledgerのソースコードは複雑かつ膨大であり、コードが誤って実行される可能性が高いです。
- トランザクションを誤って実行した場合のコストは高く、どのような基準でも許容されるものではありません。


具体的には、不正なトランザクションの実行により、無効または破損したデータが作成され、後にネットワーク上のサーバを「動作不可能」な状態にすることで一貫してクラッシュさせ、ネットワーク全体を停止させる可能性があります。

不正なトランザクションの処理は、XRP Ledgerの信頼という価値を損なうことになります。不変性チェックは、信頼性という機能を付加するため、XRP Ledger 全体に価値を提供します。

## 仕組み

不変性チェッカーは、各トランザクションの後にリアルタイムで自動的に実行される第2層のコードです。トランザクションの結果がレジャーにコミットされる前に、不変性チェッカーはそれらの変更が正しいかどうかを検証します。もしトランザクションの結果がXRP Ledgerの厳格なルールに沿わない場合、不変性チェッカーはそのトランザクションを拒否します。このように拒否されたトランザクションは結果コード `tecINVARIANT_FAILED` を持ち、何の効果もなくレジャーに含まれます。

トランザクションを `tec` クラスのコードでレジャーに含めるには、何らかの最小限の処理が必要です。この最小限の処理でも不変条件に沿わない場合、トランザクションは `tefINVARIANT_FAILED` というコードで失敗し、レジャーには一切含まれません。

## 有効な不変条件

XRP Ledgerは、各トランザクションについて、以下のすべての不変条件をチェックします。

[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L92)

- [トランザクション手数料チェック](#%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E6%89%8B%E6%95%B0%E6%96%99%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF)


[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L118)

- [XRPは作成されません](#xrp%E3%81%AF%E4%BD%9C%E6%88%90%E3%81%95%E3%82%8C%E3%81%BE%E3%81%9B%E3%82%93)


[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L146)

- [アカウントルートが削除されていない](#%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%83%AB%E3%83%BC%E3%83%88%E3%81%8C%E5%89%8A%E9%99%A4%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84)


[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L173)

- [XRPの残高確認](#xrp%E3%81%AE%E6%AE%8B%E9%AB%98%E7%A2%BA%E8%AA%8D)


[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L197)

- [レジャーエントリ形式の一致](#%E3%83%AC%E3%82%B8%E3%83%A3%E3%83%BC%E3%82%A8%E3%83%B3%E3%83%88%E3%83%AA%E5%BD%A2%E5%BC%8F%E3%81%AE%E4%B8%80%E8%87%B4)


[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L224)

- [XRPのトラストラインはありません](#xrp%E3%81%AE%E3%83%88%E3%83%A9%E3%82%B9%E3%83%88%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93)


[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L251)

- [不正なオファーでない](#%E4%B8%8D%E6%AD%A3%E3%81%AA%E3%82%AA%E3%83%95%E3%82%A1%E3%83%BC%E3%81%A7%E3%81%AA%E3%81%84)


[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L275)

- [0のエスクローでない](#0%E3%81%AE%E3%82%A8%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%81%A7%E3%81%AA%E3%81%84)


[[ソース]](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h#L300)

- [有効な新規アカウントルート](#%E6%9C%89%E5%8A%B9%E3%81%AA%E6%96%B0%E8%A6%8F%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%83%AB%E3%83%BC%E3%83%88)


### トランザクション手数料チェック

- **不変条件:**
  - [トランザクションコスト](/ja/docs/concepts/transactions/transaction-cost)の金額は決してマイナスになってはならず、またトランザクションで指定されたコストより大きくなってはいけません。


### XRPは作成されません

- **不変条件:**
  - トランザクションはXRPを生成してはならず、XRPを破棄するのみです[トランザクションコスト](/ja/docs/concepts/transactions/transaction-cost)。


### アカウントルートが削除されていない

- **不変条件:**
  - [アカウント](/ja/docs/concepts/accounts)は、[AccountDeleteトランザクション](/ja/docs/references/protocol/transactions/types/accountdelete)によってのみレジャーから削除することができます。
  - AccountDelete が成功すると、常にちょうど1つのアカウントが削除されます。


### XRPの残高確認

- **不変条件:**
  - アカウントのXRP残高はXRPの形式である必要があり、0未満または1000億XRPを超えることはできません。


### レジャーエントリ形式の一致

- **不変条件:**
  - 変更されたレジャーの項目は形式が一致し、追加された項目は[有効なタイプ](/ja/docs/references/protocol/ledger-data/ledger-entry-types)である必要があります。


### XRPのトラストラインはありません

- **不変条件:**
  - XRPを使用した[トラストライン](/ja/docs/concepts/tokens/fungible-tokens)は作成できません。


### 不正なオファーでない

- **不変条件:**
  - [オファー](/ja/docs/references/protocol/ledger-data/ledger-entry-types/offer)は負でない金額でなければならず、XRP同士であってはいけません。


### 0のエスクローでない

- **不変条件:**
  - [エスクロー](/ja/docs/references/protocol/ledger-data/ledger-entry-types/escrow)エントリは、0XRP以上1000億XRP未満を保有している必要があります。


### 有効な新規アカウントルート

- **不変条件:**
  - 新しい[アカウントルート](/ja/docs/references/protocol/ledger-data/ledger-entry-types/accountroot)は、支払いの結果でなければなりません。
  - 新しいアカウントルートは、正しい開始[シーケンス](/ja/docs/references/protocol/data-types/basic-data-types#%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9)を持たなければなりません。
  - 1つのトランザクションで複数の新しい[アカウント](/ja/docs/concepts/accounts)を作成してはいけません。


## 関連項目

- **ブログ:**
  - [レジャーの保護: 不変性チェック](https://xrpl.org/blog/2017/invariant-checking.html)
- **リポジトリ:**
  - [Invariant Check.h](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.h)
  - [Invariant Check.cpp](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/app/tx/impl/InvariantCheck.cpp)
  - [System Parameters](https://github.com/XRPLF/rippled/blob/develop/src/ripple/protocol/SystemParameters.h#L43)
  - [XRP Amount](https://github.com/XRPLF/rippled/blob/develop/src/ripple/basics/XRPAmount.h#L244)
  - [Ledger Formats](https://github.com/XRPLF/rippled/blob/023f5704d07d09e70091f38a0d4e5df213a3144b/src/ripple/protocol/LedgerFormats.h#L36-L94)
- **その他:**
  - [Authorized Trust Lines](/ja/docs/concepts/tokens/fungible-tokens/authorized-trust-lines)
  - [トランザクションの残高変化の計算](https://xrpl.org/blog/2015/calculating-balance-changes-for-a-transaction.html#calculating-balance-changes-for-a-transaction)