์คํฌ๋ฆฝํธ ์คํ ๋ช
๋ น์ด
#1) ์์๋๋ก ์คํํ๋ค๊ฐ ์คํจํ๋ ํธ๋์ญ์
๋์ค๋ฉด ๋ฐ๋ก ๋น ์ ธ๋์ด
$npx ts-node xrpl/Batch/UntilFailure.ts
#2) ํ๋๋ง ์ฑ๊ณตํ๋ฉด ๋น ์ ธ๋์ค๊ณ ์์ฅ์ ๊ธฐ๋ก๋จ
$npx ts-node xrpl/Batch/OnlyOne.ts
#3) ์คํจ/์ฑ๊ณต ์๊ด์์ด ๋ด๋ถ ํธ๋์ญ์
๋ค์ ๋ชจ๋ ์คํ
$npx ts-node xrpl/Batch/Independent.ts
#4) ๋ด๋ถ ํธ๋์ญ์
๋ค ์ค ํ๋๋ผ๋ ์คํจํ๋ฉด ์์ฅ์ ๊ธฐ๋ก ์๋จ. ๋ชจ๋ ์ฑ๊ณตํด์ผ ์ ์ถ๋๋ Batch ํธ๋์ญ์
$npx ts-node xrpl/Batch/AllOrNothing.ts
Bash
๋ณต์ฌ
1. Batch๋?
Batch๋ ์ฌ๋ฌ ๊ฐ์ XRPL ํธ๋์ญ์
์ ํ๋๋ก ๋ฌถ์ด Outer Transaction(Wrapper) ์์์ ํ ๋ฒ์ ์คํํ ์ ์๊ฒ ํด์ฃผ๋ ๊ธฐ๋ฅ์ด๋ค.
โข
Outer Transaction: TransactionType: "Batch"
โข
Inner Transactions: ์ค์ ์คํ๋๋ ํธ๋์ญ์
๋ค (์ต๋ 8๊ฐ)
Batch ์คํ ๋ชจ๋๋ Outer Transaction์ Flags ๊ฐ์ผ๋ก ๊ฒฐ์ ๋๋ฉฐ, ๊ฐ ๋ชจ๋๋ ํธ๋์ญ์
์ฒ๋ฆฌ ๋ฐฉ์์ ์ ์ํ๋ค.
Batch ์คํ ๋ชจ๋ 4๊ฐ์ง(Flags)
1.1 AllOrNothing (0x00010000)
โข
์ค๋ช
: ๋ชจ๋ Inner๊ฐ tesSUCCESS์ฌ์ผ ์ปค๋ฐ. ํ๋๋ผ๋ ์คํจํ๋ฉด ์ ๋ถ ๋กค๋ฐฑ.
โข
์ฌ์ฉ ์์:
โฆ
NFT ๋ฐํ + ์คํผ ์์ฑ (์คํผ ์คํจ ์ ๋ฐํ ์ทจ์)
โฆ
๋ฉํฐ๊ณ์ ์ค์ (ํ์ชฝ ์คํจ ์ ์ ์ฒด ์ทจ์)
1.2 OnlyOne (0x00020000)
โข
์ค๋ช
: ์ฒซ ๋ฒ์งธ๋ก ์ฑ๊ณตํ๋ Inner๋ง ์คํ, ๋๋จธ์ง๋ ์คํ ์ ํจ.
โข
์ฌ์ฉ ์์:
โฆ
์ฌ๋ฌ ๊ฐ๊ฒฉ์ ์คํผ๋ฅผ ๋์์ ์ ์ถ โ ๊ฐ์ฅ ๋จผ์ ์ฒด๊ฒฐ๋๋ ๊ฒ๋ง ์คํ.
โฆ
์ฌ๋ฌ ๊ฒฝ๋ก์ ์ก๊ธ โ ์ฒซ ์ฑ๊ณต ๊ฒฝ๋ก๋ง ์ฌ์ฉ.
1.3 UntilFailure (0x00040000)
โข
์ค๋ช
: ์์๋๋ก ์คํํ๋ค๊ฐ ์ฒซ ์คํจ๊ฐ ๋์ค๋ฉด ์ดํ๋ ์คํ ์ ํจ.
โข
์ฌ์ฉ ์์:
โฆ
์ฌ๋ฌ ๊ณ์ ์ ์์ฐจ ์ก๊ธํ๋ค๊ฐ ์๊ณ ๋ถ์กฑ ์ ์ค๋จ.
โฆ
์ฌ๋ฌ ๋จ๊ณ ์์
์ค, ํน์ ์์ ๊น์ง๋ ์คํจํด๋ ๊ด์ฐฎ์ง๋ง ์ดํ๋ ์ค๋จ.
1.4 Independent (0x00080000)
โข
์ค๋ช
: ๋ชจ๋ Inner๋ฅผ ์คํ. ์คํจ ์ฌ๋ถ ์๊ด์์ด ์ ๋ถ ์๋.
โข
์ฌ์ฉ ์์:
โฆ
์์ด๋๋/๋ณด์ ์ง๊ธ (๋ช ๊ฐ ์คํจํด๋ ๋๋จธ์ง ๊ณ์ ์ง๊ธ)
โฆ
๋๋ ์คํผ ๋ฑ๋ก (์ค๊ฐ ์คํจ ๋ฌด์)
2. ์ ํ์ํ๊ฐ?
โข
์์์ฑ(Atomic) ๋ณด์ฅ
โฆ
์ฌ๋ฌ ๋จ๊ณ ์์
์ด ๋ชจ๋ ์ฑ๊ณตํด์ผ๋ง ์ปค๋ฐ โ ์ผ๋ถ๋ง ์คํ๋๋ ๋ถ์์ ์ํ ๋ฐฉ์ง.
โข
์ํฌํ๋ก์ฐ ๋จ์ํ
โฆ
NFT ๋ฐํ โ ์คํผ ์์ฑ, ํ ํฐ ๋ฐํ โ ์ ์ก ๋ฑ ๋ณตํฉ ์์
์ ํ๋๋ก ๋ฌถ์.
โข
MultiAccount Transfer
โฆ
์๋ก ๋ค๋ฅธ ๊ณ์ ์ ํธ๋์ญ์
์ ํ๋์ Batch์์ ๋์ ์คํ ๊ฐ๋ฅ.
โข
์์๋ฃ ์ต์ ํ
โฆ
Inner Transaction๋ค์ Fee=0 โ ์ค์ ์์๋ฃ๋ Outer Transaction์์ ํ ๋ฒ์ ๊ฒฐ์ .
3. ์๋๋ฆฌ์ค: batchAllOrNothing โ batchOnlyOne โ batchUntilFailure โ batchIndependent
Step 1. AllOrNothing (์ ๋ถ ์ฑ๊ณต or ์ ๋ถ ๋กค๋ฐฑ)
โข
์ฃผ์ฒด: User
โข
ํ๋: Batch ํธ๋์ญ์
์ ์ก
โข
๋ด์ฉ:
โฆ
Flags: 0x00010000 (AllOrNothing)
โฆ
RawTransactions: Payment 2๊ฑด์ inner๋ก ํฌํจ
โฆ
๊ฐ inner๋ tfInnerBatchTxn(0x40000000) + Fee:"0" + SigningPubKey:"" + Sequence ํ์
โฆ
๋ ์ค ํ๋๋ผ๋ ์คํจํ๋ฉด ๋ ๋ค ๋กค๋ฐฑ
// ํ์ฌ ๊ณ์ ์ ์ต์ ์ํ์ค ๋ฒํธ ์กฐํ
// outer ๋ฐ inner ํธ๋์ญ์
์ Sequence ๊ฐ ๊ณ์ฐ์ ์ฌ์ฉ
const ai = await client.request({ command: "account_info", account: user.address })
const seq = ai.result.account_data.Sequence
const tx: any = {
TransactionType: "Batch",
Account: user.address,
Flags: 0x00010000, // AllOrNothing
RawTransactions: [
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000, // tfInnerBatchTxn
Account: user.address,
Destination: user2.address,
Amount: "5000000", // 5 XRP
Sequence: seq + 1,
Fee: "0",
SigningPubKey: ""
}},
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "10000000", // 10 XRP
Sequence: seq + 2,
Fee: "0",
SigningPubKey: ""
}}
],
Sequence: seq
}
TypeScript
๋ณต์ฌ
โข
๊ฒ์ฆ ํฌ์ธํธ: outer๋ tesSUCCESS๋ผ๋, inner 2๊ฑด์ด ๋ชจ๋ ledger์ ๊ธฐ๋ก๋๋์ง ํ์ธ. ํ๋๋ผ๋ ์คํจ๋ฉด ๋ ๋ค ์์.
Step 2. OnlyOne (์ฒซ ์ฑ๊ณต๋ง ์ ์ฉ)
โข
์ฃผ์ฒด: User
โข
ํ๋: Batch ํธ๋์ญ์
์ ์ก
โข
๋ด์ฉ:
โฆ
Flags: 0x00020000 (OnlyOne)
โฆ
์ฌ๋ฌ inner ์ค ๊ฐ์ฅ ๋จผ์ ์ฑ๊ณตํ 1๊ฑด๋ง ๋ฐ์, ๋๋จธ์ง๋ ์๋ ์ ํ๊ฑฐ๋ ๋ฏธ์ ์ฉ
// ํ์ฌ ๊ณ์ ์ ์ต์ ์ํ์ค ๋ฒํธ ์กฐํ
// outer ๋ฐ inner ํธ๋์ญ์
์ Sequence ๊ฐ ๊ณ์ฐ์ ์ฌ์ฉ
const ai = await client.request({ command: "account_info", account: user.address })
const seq = ai.result.account_data.Sequence
const tx: any = {
TransactionType: "Batch",
Account: user.address,
Flags: 0x00020000, // OnlyOne
RawTransactions: [
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "5000000", // 5 XRP
Sequence: seq + 1,
Fee: "0",
SigningPubKey: ""
}},
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "10000000", // 10 XRP
Sequence: seq + 2,
Fee: "0",
SigningPubKey: ""
}}
],
Sequence: seq
}
TypeScript
๋ณต์ฌ
โข
๊ฒ์ฆ ํฌ์ธํธ: ์ฒซ ๋ฒ์งธ inner๋ง ledger ๋ฐ์. ๋ ๋ฒ์งธ๋ ๋ฏธ์คํ/๋ฏธ๋ฐ์.
Step 3. UntilFailure (์คํจ๊ฐ ๋์ค๊ธฐ ์ ๊น์ง ์์ฐจ ์คํ)
โข
์ฃผ์ฒด: User
โข
ํ๋: Batch ํธ๋์ญ์
์ ์ก
โข
๋ด์ฉ:
โฆ
Flags: 0x00040000 (UntilFailure)
โฆ
์์์๋ถํฐ ์์ฐจ ์ ์ฉ, ์ฒซ ์คํจ๊ฐ ๋์ค๋ฉด ๊ทธ ์ดํ๋ ์ค๋จ
// ํ์ฌ ๊ณ์ ์ ์ต์ ์ํ์ค ๋ฒํธ ์กฐํ
// outer ๋ฐ inner ํธ๋์ญ์
์ Sequence ๊ฐ ๊ณ์ฐ์ ์ฌ์ฉ
const ai = await client.request({ command: "account_info", account: user.address })
const seq = ai.result.account_data.Sequence
const tx: any = {
TransactionType: "Batch",
Account: user.address,
Flags: 0x00040000, // UntilFailure
RawTransactions: [
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "5000000", // 5 XRP
Sequence: seq + 1,
Fee: "0",
SigningPubKey: ""
}
},
// 2๋ฒ์งธ ๋ด๋ถ ํธ๋์ญ์
์์ ์๋์ ์คํจ ์ ๋ (๊ณผ๋ํ ๊ธ์ก ์ ์ก)
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "50000000000", // 50000 XRP (๊ณผ๋ํ ๊ธ์ก)
Sequence: seq + 2,
Fee: "0",
SigningPubKey: ""
}},
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "10000000", // 10 XRP
Sequence: seq + 3,
Fee: "0",
SigningPubKey: ""
}}
],
Sequence: seq
}
TypeScript
๋ณต์ฌ
โข
๊ฒ์ฆ ํฌ์ธํธ: 1๋ฒ์ ์ฑ๊ณต, 2๋ฒ์์ ์คํจ, 3๋ฒ์ ๋ฏธ์คํ.
Step 4. Independent (๋ชจ๋ ์๋, ์ฑ๊ณต/์คํจ ๋ ๋ฆฝ)
โข
์ฃผ์ฒด: User
โข
ํ๋: Batch ํธ๋์ญ์
์ ์ก
โข
๋ด์ฉ:
โฆ
Flags: 0x00080000 (Independent)
โฆ
๋ชจ๋ inner๋ฅผ ์๋. ์ผ๋ถ ์คํจํด๋ ๋๋จธ์ง๋ ๊ณ์ ์งํ
// ํ์ฌ ๊ณ์ ์ ์ต์ ์ํ์ค ๋ฒํธ ์กฐํ
// outer ๋ฐ inner ํธ๋์ญ์
์ Sequence ๊ฐ ๊ณ์ฐ์ ์ฌ์ฉ
const ai = await client.request({ command: "account_info", account: user.address })
const seq = ai.result.account_data.Sequence
const tx: any = {
TransactionType: "Batch",
Account: user.address,
Flags: 0x00080000, // Independent
RawTransactions: [
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "100000000000", // 100000 XRP(๊ณผ๋ํ ๊ธ์ก)
Sequence: seq + 1,
Fee: "0",
SigningPubKey: ""
}},
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "50000000000", // 50000 XRP(๊ณผ๋ํ ๊ธ์ก)
Sequence: seq + 2,
Fee: "0",
SigningPubKey: ""
}},
{ RawTransaction: {
TransactionType: "Payment",
Flags: 0x40000000,
Account: user.address,
Destination: user2.address,
Amount: "5000000", // 5 XRP
Sequence: seq + 3,
Fee: "0",
SigningPubKey: ""
}}
],
Sequence: seq
}
TypeScript
๋ณต์ฌ
โข
๊ฒ์ฆ ํฌ์ธํธ: ์คํจํ inner๊ฐ ์์ด๋ ๋ค๋ฅธ inner๋ค์ ์ ์ ๋ฐ์.
4. ๊ตฌํ ์ ์ ์์ฌํญ
โข
Inner Transaction ์ ํ
โฆ
Fee: "0"์ด์ด์ผ ํจ (Outer๊ฐ ์์๋ฃ ๋ถ๋ด)
โฆ
์๋ช
์์ (SigningPubKey: "", TxnSignature ์๋ต)
โฆ
Flags์ tfInnerBatchTxn (0x40000000) ํ์
โข
Outer Transaction
โฆ
๋ชจ๋ Inner๋ฅผ ํฌํจํ๊ณ , ํ์ํ ๊ฒฝ์ฐ BatchSigners๋ก ๋ค์ค ๊ณ์ ์๋ช
ํฌํจ
โข
Inner Transaction ์
โฆ
์ต๋ 8๊ฐ (ํฅํ ์ํ ๊ฐ๋ฅ)

