> ## Documentation Index
> Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
> Use this file to discover all available pages before exploring further.

# 交易與手續費

> 了解 Solana 交易結構、交易限制，以及 Solana 網路手續費與 Raydium 協議手續費這兩個不同類別的手續費如何堆疊在典型交換中。

<Info>
  **本頁內容由 AI 自動翻譯，所有內容以英文版本為準。**

  [查看英文版 →](/solana-fundamentals/transactions-and-fees)
</Info>

<Info>
  Solana 交易是以原子方式執行的指令列表。了解交易結構——指令、帳戶、簽署者、計算預算——是使用 Raydium 進行任何開發、除錯或最佳化的前提條件。本頁涵蓋了交易結構、限制條件，以及兩個手續費類別（Solana 網路手續費、Raydium 協議手續費）如何在實際交換中堆疊。
</Info>

## 交易解剖

Solana 交易有三個核心元件：

* **訊息**：指令的有序列表、它們參考的帳戶，以及最近的區塊雜湊。
* **簽名**：每個簽署者一個，認證交易獲得授權。
* **最近的區塊雜湊**：證明交易是最近的；具有陳舊區塊雜湊（>150 個槽位舊）的交易會被拒絕。

### 指令

一個指令指定：

* `program_id` — 要呼叫的程式。
* `accounts` — 程式可能觸及的帳戶（及其可寫入/簽署者旗標）。
* `data` — 程式解釋的不透明位元組。

單一交易可包含多個指令。它們按順序執行；如果任何指令失敗，所有先前的指令都會被回滾（原子性）。

典型的 Raydium 交換交易包括：

1. `ComputeBudget::SetComputeUnitLimit` — 提高預設 CU 限額。
2. `ComputeBudget::SetComputeUnitPrice` — 設定優先費用。
3. 可選的 `CreateAssociatedTokenAccount` — 如果使用者沒有輸出 ATA，建立它。
4. `Raydium::SwapBaseInput` — 執行交換。
5. 可選的 `CloseAccount` — 關閉 wrapped SOL ATA。

SDK 透過 `raydium.trade.swap()` 自動打包這些指令。

## 交易中的帳戶

交易中任何指令觸及的每個帳戶都必須列在交易的帳戶鑰匙中。每個帳戶都有旗標：

* **簽署者 / 非簽署者**：帳戶的擁有者必須簽署交易嗎？
* **可寫入 / 唯讀**：交易可以修改帳戶嗎？

執行時強制執行這些旗標：程式嘗試寫入不可寫入帳戶會失敗，執行時會拒絕缺少必需簽署者的交易。

對於 CPMM 交換，帳戶列表有約 13 個條目（參閱 [`solana-fundamentals/account-model`](/zh-Hant/solana-fundamentals/account-model)）。具有多個刻度陣列交叉的 CLMM 交換可能有 20+。

## 交易大小限制

Solana 將交易上限設為 **1232 位元組**，包括簽名、訊息和標頭。這是複雜交易最常見的障礙——Raydium 的 CLMM 與多路由路由經常推著這個限制。

典型 \~1000 位元組 Raydium 交換的分解：

| 元件                   | 大小           |
| -------------------- | ------------ |
| 簽名                   | 64 B         |
| 簽名計數                 | 1 B          |
| 訊息標頭                 | 3 B          |
| 區塊雜湊                 | 32 B         |
| 帳戶鑰匙 (13 × 32 B)     | 416 B        |
| 指令 (4 × \~100-150 B) | 400–600 B    |
| **總計**               | \~900–1100 B |

### 位址查閱表 (ALT)

ALT 讓交易透過已發佈表中的 1 位元組索引參考帳戶，而不是完整的 32 位元組公鑰。這大幅壓縮交易：

* 直接參考 20 個帳戶的交易：\~640 B 的公鑰。
* 同一筆交易使用 ALT：\~20 B 的索引 + ALT 參考。

Raydium 在主網上為 CPMM/CLMM 交換路徑維護 ALT。SDK 自動使用它們。構建多路由的聚合商大量依賴它們。

```ts theme={null}
import { VersionedTransaction } from "@solana/web3.js";

// SDK builds a v0 (versioned) tx with ALT references
const { transaction } = await raydium.trade.swap({ /* ... */ });
// transaction is a VersionedTransaction, not a legacy Transaction.
```

## 計算預算

每筆交易都有一個**計算單位 (CU) 預算**。超過預算會終止執行並使交易失敗。

* **預設值**：每筆交易 200,000 CU。
* **最大值**：每筆交易 1,400,000 CU（透過 `ComputeBudget::SetComputeUnitLimit` 提高）。
* **每區塊上限**：每區塊 48M CU（協議層級）。

典型 Raydium CU 消耗（完整表格參閱 [`integration-guides/priority-fee-tuning`](/zh-Hant/integration-guides/priority-fee-tuning)）：

| 指令               | CU        |
| ---------------- | --------- |
| CPMM 交換          | \~140,000 |
| CLMM 交換（無刻度交叉）   | \~170,000 |
| CLMM 交換（4 次刻度交叉） | \~320,000 |
| Farm v6 質押       | \~130,000 |
| CPMM 池建立         | \~250,000 |

總是透過 `ComputeBudget` 設定明確的 CU 限額；否則你會得到 200k 預設值，對大多數 Raydium 指令來說太低了。

```ts theme={null}
import { ComputeBudgetProgram } from "@solana/web3.js";

tx.add(
  ComputeBudgetProgram.setComputeUnitLimit({ units: 300_000 }),
);
```

如果你設定的 CU 限額太低，交易在達到上限時會失敗；設定過高你會冒著在壅塞下被降級優先度的風險（根據定價模式，你可能為從未使用的計算付費）。

## 優先費用

除了基礎交易費用（每個簽名 5000 lamports），驗證者越來越多地優先處理支付**優先費用**的交易：每 CU 的微 lamport 小費。

```
priority_fee = compute_unit_price (micro-lamports) × compute_unit_limit
```

例子：10,000 µL/CU × 300,000 CU = 3,000,000 µL = 0.003 SOL。

優先費用是本地的——它們只影響區塊內的排序；它們不會改善你被納入而非不被納入的機會。在壅塞期間設定合理的優先費用至關重要。

```ts theme={null}
tx.add(
  ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10_000 }),
);
```

參閱 [`integration-guides/priority-fee-tuning`](/zh-Hant/integration-guides/priority-fee-tuning) 了解如何動態調整這一點。

## 指令計數與帳戶計數限制

除了 1232 位元組的總限制之外：

* **每筆交易的最大帳戶數**：128。
* **每個指令的最大帳戶數 (CPI)**：64。
* **每筆交易的最大指令數**：無硬性限制，僅受大小限制限制。
* **最大 CPI 深度**：4（一個程式可以呼叫另一個程式，它可以呼叫另一個程式，4 層深）。

交叉多個刻度陣列的 Raydium CLMM 交換可能會嚴重推著帳戶限制——單次交換觸及池、輸入/輸出金庫、輸入/輸出 ATA、多個刻度陣列、可能是傳輸鉤子程式的額外帳戶，加上強制計算預算 / 系統 / token 程式參考。透過 CPI 組成 Raydium 的設計（例如自動複合器）需要考慮到這一點。

## Raydium 交換中的手續費類別

使用者交換交易在兩個類別中支付手續費：

### Solana 網路手續費

支付給驗證者的 SOL。

* **基礎簽名費**：每個簽名 5000 lamports。幾乎總是 1 個簽名 = 0.000005 SOL。
* **優先費用**：CU 價格 × CU 限額（以微 lamport 計）。隨壅塞變化；參閱 [`integration-guides/priority-fee-tuning`](/zh-Hant/integration-guides/priority-fee-tuning)。

這些費用進入驗證者，與 Raydium 無關，甚至對失敗的交易也會收取（除了某些優先費用邊界情況）。

### Raydium 協議手續費

從交換金額中扣除。

* **交換費**：輸入的百分比（CPMM 典型 0.25%，CLMM 0.01%–1% 每層）。分割給流動性提供者和協議目標地址。參閱 [`ray/protocol-fees`](/zh-Hant/ray/protocol-fees)。

這些費用是 Raydium 帳務內部的——使用者看到的是比零費用池產生的輸出量更小的金額。

### 範例：\$1000 USDC → SOL 透過 CPMM 0.25% 層

| 手續費類別                   | 金額                        | 流向      |
| ----------------------- | ------------------------- | ------- |
| 基礎簽名費                   | 0.000005 SOL (\~\$0.0007) | 驗證者     |
| 優先費用 (10k µL × 300k CU) | 0.003 SOL (\~\$0.45)      | 驗證者     |
| CPMM 交換費 (0.25%)        | \$2.50                    | LP + 協議 |
| **使用者總成本**              | \~\$2.95                  |         |

滑點（價格影響 + 市場波動）不是手續費，但會影響相同的最終結果。

## 版本化交易

Solana 有兩種交易格式：

* **遺留**：原始格式，不支援 ALT。
* **v0 (版本化)**：支援 ALT，可擴展至未來版本。

所有現代 Solana 工具都使用 v0。Raydium SDK 預設發出 v0 交易。

```ts theme={null}
// Building a v0 tx directly
import { VersionedTransaction, TransactionMessage } from "@solana/web3.js";

const msg = new TransactionMessage({
  payerKey:        owner.publicKey,
  recentBlockhash: blockhash,
  instructions:    [ /* ... */ ],
}).compileToV0Message([lookupTableAccount]);

const tx = new VersionedTransaction(msg);
tx.sign([owner]);
```

## 區塊雜湊新鮮度

交易必須包含來自最後約 150 個槽位（約 60 秒）內的區塊雜湊。超出該視窗，驗證者會拒絕它。

對於重試迴圈，在每次重試時取得新的區塊雜湊：

```ts theme={null}
async function sendWithRetry(tx, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
    tx.message.recentBlockhash = blockhash;
    tx.sign([owner]);
    try {
      return await connection.sendRawTransaction(tx.serialize());
    } catch (e) {
      if (i === maxRetries - 1) throw e;
    }
  }
}
```

參閱 [`integration-guides/priority-fee-tuning`](/zh-Hant/integration-guides/priority-fee-tuning) 了解完整的逐步升級費用重試模式。

## 平行執行

Solana 在多核驗證者上平行執行不衝突的交易。兩筆交易衝突當且僅當它們都寫同一個帳戶。

對 Raydium 的影響：

* 同一池上的兩筆交換無法平行執行——兩者都寫池狀態。
* 池 A 上的交換和池 B 上的交換在帳戶列表不重疊時平行執行。
* 唯讀交易從不阻止同一帳戶的寫入者（唯讀與自己併發，但與寫入不併發）。

這就是為什麼 Solana 儘管有單池序列化，仍能維持高 DEX 吞吐量。

## 交易確認層級

提交交易時，你選擇一個確認層級：

| 層級          | 等待       | 最終性        |
| ----------- | -------- | ---------- |
| `processed` | \~400 ms | 未最終確認；可能回滾 |
| `confirmed` | \~1 s    | 超級多數投票     |
| `finalized` | \~13 s   | 超級多數根源化    |

對於交換 UX，`confirmed` 是標準。對於處理大價值的操作（池建立、獎勵補充），`finalized` 更安全。

```ts theme={null}
await connection.sendAndConfirmTransaction(tx, [owner], {
  commitment: "confirmed",
});
```

## 模擬

Solana 支援在提交前模擬交易：

```ts theme={null}
const sim = await connection.simulateTransaction(tx);
console.log(sim.value.logs);
console.log(sim.value.unitsConsumed);
```

Raydium SDK 在計算 `getBestSwapInfo` 時內部使用模擬來驗證選定的路由確實成功。模擬並非免費的——它消耗 RPC 容量——但它在支付前捕捉錯誤。

## 指標

* [`solana-fundamentals/account-model`](/zh-Hant/solana-fundamentals/account-model) — 交易中的帳戶。
* [`solana-fundamentals/pdas-and-cpis`](/zh-Hant/solana-fundamentals/pdas-and-cpis) — 程式如何相互呼叫。
* [`integration-guides/priority-fee-tuning`](/zh-Hant/integration-guides/priority-fee-tuning) — 調整 CU 限額和優先費用。
* [`ray/protocol-fees`](/zh-Hant/ray/protocol-fees) — Raydium 協議手續費結構。

來源：

* [Solana Transaction docs](https://docs.solana.com/developing/programming-model/transactions).
* [Address Lookup Tables proposal](https://docs.solana.com/developing/lookup-tables).
* [Compute budget documentation](https://docs.solana.com/developing/programming-model/runtime).
