# バッチ

`Batch`では、複数のトランザクションをまとめてパッケージ化し、単一のユニットとして実行できます。部分的な完了や予期しない結果のリスクを排除し、複雑な操作をより信頼性が高く予測可能な方法で実行できます。1つのバッチで最大8つのトランザクションを送信できます。

`Batch`の潜在的な使用例は以下の通りです。

- 全て成功か全て失敗：NFTをミントして同時にオファーを作成できます。オファー作成が失敗した場合、NFTミントも取り消されます。
- 複数のオファーの試行：異なるスリッページ量で複数のオファーを送信しますが、成功するのは1つだけです。
- プラットフォーム手数料：プラットフォーム手数料をトランザクション自体に含めることで、プロセスを簡素化できます。
- スワップ（マルチアカウント）：複数のアカウント間でのトラストレスなトークン/NFTスワップ。
- アカウント引き出し（マルチアカウント）：当座預金からの引き出しを試行し、失敗した場合は代わりに普通預金から引き出します。


`Batch`トランザクションは、ラッパーである`Batch`トランザクション自体の *外部トランザクション* と、それぞれがアトミックに実行される *内部トランザクション* で構成されます。内部トランザクションの正確な処理方法は、バッチ *モード* によって決まります。

## バッチのモード

`Batch`には`ALLORNOTHING`、`ONLYONE`、`UNTILFAILURE`、`INDEPENDENT`の4つのモードがあります。

### All or Nothing（全て成功か全て失敗）

`ALLORNOTHING`モードでは、いずれかの内部トランザクションが成功するには、全ての内部トランザクションが成功する必要があります。

### Only One（1つだけ）

`ONLYONE`モードでは、最初に成功したトランザクションのみが成功します。他の全てのトランザクションは失敗するか、実行されません。

### Until Failure（失敗まで）

`UNTILFAILURE`では、全ての内部トランザクションをいずれかが失敗するまで適用します。最初の失敗後の全てのトランザクションは適用されません。

### Independent（独立）

`INDEPENDENT`では、1つ以上の内部トランザクションが失敗しても、全てのトランザクションが適用されます。

## Raw Transactions

`RawTransactions`オブジェクトは、実行するトランザクションのリストを格納するコンテナです。1つのバッチには最大8つのトランザクションを含めることができます。トランザクションは単一のアカウントまたは複数のアカウントからのものを混在させることができます。

各内部トランザクションは以下の要件を満たす必要があります。

- `tfInnerBatchTxn`フラグを設定する必要があります。
- 手数料を設定してはいけません。手数料の値は *0* を使用する必要があります。
- 署名されてはいけません（グローバルトランザクションは既に関連する全ての当事者によって署名されています）。代わりに`SigningPubKey`フィールドに空文字列（""）を設定する必要があります。(`TxnSignature`フィールドは設定してはいけません。)


`tesSUCCESS`以外の結果を受け取った場合、トランザクションは失敗と見なされます。

### 共通のフラグ

`Batch`は次のグローバルなトランザクションフラグを追加します。

| フラグ名 | 値 |
|  --- | --- |
| `tfInnerBatchTxn` | 0x40000000 |


このフラグは、トランザクションがバッチトランザクションの内部トランザクションである場合にのみ使用されます。これは、トランザクションが署名されていないことを示します。このフラグを含む通常のトランザクションは拒否されます。

### BatchSigners

このフィールドは、アカウントがマルチサインで署名している場合（単一署名とは対照的に）に含まれます。標準トランザクションのマルチサインで使用される`Signers`フィールドと同等に動作します。このフィールドは`Flags`フィールドと`RawTransactions`内のトランザクションのハッシュの署名を保持します。このフィールドは、複数のアカウントのトランザクションが`Batch`トランザクションに含まれている場合にのみ必要となります。それ以外の場合は、通常のトランザクション署名が同じセキュリティを保証します。

このフィールドは、1つ以上のアカウントが内部トランザクションをバッチに含める場合に提供する必要があります。その場合、外部トランザクションに署名するアカウント（該当する場合）を除き、内部トランザクションを含む全てのアカウントからの署名を含める必要があります。

この配列内の各オブジェクトには、以下のフィールドが含まれます。

| フィールド | 必須？ | JSONの型 | 内部の型 |
|  --- | --- | --- | --- |
| Account | はい | string | STAccount |
| SigningPubKey | いいえ | string | STBlob |
| TxnSignature | いいえ | string | STBlob |
| Signers | いいえ | array | STArray |


`SigningPubKey`と`TxnSignature`フィールド、または`Signers`フィールドのいずれかを含める必要があります。

#### Account

これは、少なくとも1つの内部トランザクションを持つアカウントです。

#### SigningPubKeyとTxnSignature

これらのフィールドは、アカウントが単一署名で署名している場合（マルチサインとは対照的に）に含まれます。これらは`Flags`フィールドと`RawTransactions`内のトランザクションのハッシュに署名します。

#### Signers

このフィールドは、アカウントがマルチサインで署名している場合（単一署名とは対照的に）に含まれます。標準トランザクションのマルチサインで使用される`Signers`フィールドと同等に動作します。このフィールドは`Flags`フィールドと`RawTransactions`内のトランザクションのハッシュの署名を保持します。

## 手数料

外部トランザクションの手数料は、ベース手数料の2倍（手数料エスカレーションがない場合は合計20 drop）に、全ての内部トランザクションのトランザクション手数料の合計（`multisign`や`AMMCreate`などのより高い手数料などの要因を組み込む）を加え、さらにトランザクション内の各追加署名（例：`BatchSigners`から）に対する追加のベース手数料金額を加えたものです。式で表すと以下の通りです。

2 * (ベース手数料) + SUM(内部トランザクション手数料) + 各追加署名に対する追加のベース手数料

個々の内部トランザクションの手数料は、内部トランザクション自体ではなく外部トランザクションで支払われます。これにより、手数料エスカレーションがオーバーヘッドのみではなくバッチトランザクション全体のコストに基づいて計算されることが保証されます。

## メタデータ

内部トランザクションは台帳に個別にコミットされるため、個別のメタデータを持ちます。これにより、レガシーシステムがシステムの変更を必要とせずに`Batch`トランザクションをサポートできるよう、より良い後方互換性が保証されます。

例えば、2つの内部トランザクションを含む1つの`Batch`トランザクションのみを持つ台帳は、次のようになります。


```
[
  OuterTransaction,
  InnerTransaction1,
  InnerTransaction2
]
```

### 外部トランザクション

各外部トランザクションには、内部トランザクション処理ではなく、シーケンスと手数料処理のメタデータが含まれます。エラーコードは外部トランザクション処理（例：シーケンスと手数料）のみに基づいており、内部トランザクション処理が失敗しても`tesSUCCESS`エラーを返します。

### 内部トランザクション

各内部トランザクションには、独自の処理のメタデータが含まれます。実際に台帳にコミットされた内部トランザクションのみが含まれます。これにより、レガシーシステムが`Batch`トランザクションを通常のトランザクションのように処理することが容易になります。

親の外部トランザクション（`ParentBatchID`）への逆ポインタもあります。

## 共通のフィールド

この標準はトランザクション共通フィールドに新しいフィールドを追加しませんが、別のグローバルトランザクションフラグを追加します：

| フラグ名 | 値 |
|  --- | --- |
| tfInnerBatchTxn | 0x40000000 |


このフラグは、トランザクションが`Batch`トランザクションの内部トランザクションである場合にのみ使用すべきです。これは、トランザクションが署名されるべきでないことを示します。このフラグを含む通常のトランザクションは拒否されるべきです。

## セキュリティ

バッチトランザクションには追加のセキュリティ考慮事項があります。

### 信頼の前提

`Batch`トランザクションに含まれるアカウントのトランザクション数に関係なく、全てのアカウントがトランザクションのコレクションに署名する必要があります。

#### 単一アカウント

単一アカウントの場合、その単一アカウントは送信する全てのトランザクションを承認する必要があります。他のアカウントは関与しません。

#### マルチアカウント

マルチアカウントの場合はより複雑で、例で最もよく説明できます。

アリスとボブがマルチアカウント`Batch`を介してトラストレススワップを行っており、アリスが1000 XRPを提供し、ボブが1000 USDを提供します。ボブが`Batch`トランザクションを送信するため、アリスはボブに対する1000 XRP送信の情報をボブに提供する必要があります。

アリスが完全に自動入力され署名されたトランザクションをボブに提供した場合、ボブは自分のトランザクションを送信せずに台帳上でアリスのトランザクションを送信し、1000 USDを失うことなく1000 XRPを受け取ることができます。したがって、内部トランザクションは署名されていない必要があります。

アリスがバッチトランザクションの自身の部分のみに署名した場合、ボブは自分のトランザクションを1 USDのみを提供するように変更でき、それによってはるかに安い価格で1000 XRPを取得できます。したがって、バッチトランザクション全体（とその全ての内部トランザクション）は全ての当事者によって署名される必要があります。

### 内部トランザクションの安全性

バッチの内部トランザクションは特殊なケースです。署名や手数料を含みません（これらは両方とも外部トランザクションに含まれているため）。したがって、誰かが外部トランザクションに含めることなく、`Batch`の内部トランザクションを直接送信できないことを保証するために、慎重に処理する必要があります。

内部トランザクションはブロードキャストできません（例えば悪意のあるノードからブロードキャストされた場合、受け入れられません）。代わりに`Batch`の外部トランザクションから生成される必要があります。内部トランザクションは、submit RPCを介して直接送信することはできません。