> ## 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 在 SIMD-0437 下分五個步驟將質押豁免最低額度降低 90%。在各步驟前建立的帳戶持有超過所需的餘額——本文說明超額部分是什麼、哪些程式會退還它，以及如何找到並回收它。

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

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

<Info>
  質押是可退款的保證金，不是費用。SIMD-0437 分五個獨立控制的步驟降低每個帳戶必須持有的保證金。在某個步驟前建立的帳戶會保留其原始資金額，因此每個步驟都會讓這些帳戶超額資金化。SPL Token 和 Token-2022 程式可以透過 `WithdrawExcessLamports` 退還這個差額，而無需關閉帳戶或觸及其代幣餘額。沒有過期時間——超額部分會保留在你自己的帳戶中，直到你選擇移動它。
</Info>

如果你是 Solana 帳戶資金模式的新手，請先閱讀[帳戶模型](/zh-Hant/solana-fundamentals/account-model)。

## 質押實際上是什麼

Solana 上的每個帳戶都持有一筆 SOL 保證金，其大小由帳戶佔用的空間決定。這筆錢不會被花費——當帳戶關閉時會全額退還。公式如下：

```
minimum_balance(data_len) = (ACCOUNT_STORAGE_OVERHEAD + data_len) × lamports_per_byte
```

`ACCOUNT_STORAGE_OVERHEAD` 是每個帳戶都要支付的固定 128 位元組，無論其內容如何。`lamports_per_byte` 是 SIMD-0437 改變的全網常數。

因此，標準 165 位元組的 SPL 代幣帳戶一直需要 `(128 + 165) × 6,960 = 2,039,280` lamports——即你在錢包開啟關聯代幣帳戶時看到扣除的約 0.00203928 SOL。

## SIMD-0437 改變了什麼

SIMD-0437 將 `lamports_per_byte` 從 6,960 降低到 696——降低 90%——透過五個獨立的功能閘門推出，讓驗證者能逐步吸收狀態增長的影響。

| 步驟 | `lamports_per_byte` | 相對原始值的降幅 | 165 位元組代幣帳戶的質押 |
| - | - | - | - |
| —（原始） | 6,960 | — | 2,039,280 lamports |
| 1 | 6,333 | 9% | 1,855,569 lamports |
| 2 | 5,080 | 27% | 1,488,440 lamports |
| 3 | 2,575 | 63% | 754,475 lamports |
| 4 | 1,322 | 81% | 387,346 lamports |
| 5 | 696 | 90% | 203,928 lamports |

步驟 1 於 2026 年 9 月 3 日在主網上啟動。步驟 2 同日到達測試網，預計於 2026 年 9 月中旬上線主網；步驟 3–5 保留給 Agave 4.4，預計於 2026 年 11 月左右推出。將時程表視為可能變更——基金會表示如果狀態增長表現不佳會暫停推出——並從叢集讀取實時值，而不是硬編碼。

<Note>
  SIMD-0437 依賴 SIMD-0194，後者棄用質押豁免閾值「以避免在功能啟動時設定質押參數時進行不必要的浮點運算」。實際上，`Rent` sysvar 現在攜帶 `lamports_per_byte_year = 6,333` 和 `exemption_threshold = 1.0`，而不是產生 6,960 的舊 `3,480 × 2` 分割。不要自己乘以這兩個欄位——呼叫 `getMinimumBalanceForRentExemption` 並讓叢集回答。
</Note>

## 為什麼現有帳戶持有過多

降低常數改變了帳戶*需要*的金額。它不改變帳戶*擁有*的金額。在 6,960 lamports 每位元組時資金化的帳戶在步驟 1 啟動後會保留該餘額，因此超額資金化為：

```
excess = (128 + data_len) × (old_rate − new_rate)
```

對於步驟 1 後的 165 位元組 SPL 代幣帳戶，這是 `293 × (6,960 − 6,333) = 183,711` lamports，或每個帳戶約 0.000184 SOL。攜帶擴展的 Token-2022 帳戶更大，因此持有的比例更多——182 位元組帳戶超額資金化 `310 × 627 = 194,370` lamports。

單獨來看這是微不足道的。多年來與數百個代幣互動過的錢包持有的是這個金額的有意義倍數，到步驟 5 時，每個 165 位元組帳戶在其最低額度上方持有 1,835,352 lamports（約 0.00184 SOL）。

## 哪些帳戶可以退還

程式擁有帳戶中的超額 lamports 只能由該程式移動。因此，你是否可以在不關閉帳戶的情況下回收質押完全取決於哪個程式擁有它。

<CardGroup cols={2}>
  <Card title="SPL Token 和 Token-2022" icon="circle-check">
    兩者都公開 `WithdrawExcessLamports`。帳戶保持開啟，保留其代幣餘額，只是降至目前最低額度。
  </Card>

  <Card title="其他所有程式" icon="circle-xmark">
    沒有等效指令。質押只有在帳戶關閉時才會釋放——這是一個具有自身前置條件的破壞性操作，不是質押掃描。
  </Card>
</CardGroup>

具體來說，對於 Raydium 使用者持有的帳戶類型：

| 帳戶 | 擁有者 | 可以就地退還超額嗎？ |
| - | - | - |
| SPL 代幣帳戶 | `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` | 是——`WithdrawExcessLamports` |
| Token-2022 代幣帳戶 | `TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb` | 是——`WithdrawExcessLamports` |
| 包裝 SOL（原生）代幣帳戶 | 任一代幣程式 | 否——見下文 |
| CLMM 頭寸 | Raydium CLMM | 否——質押在頭寸關閉時退還 |
| OpenBook v1 開放訂單 | OpenBook v1 | 否——僅 `CloseOpenOrders` |
| OpenBook v2 開放訂單 | OpenBook v2 | 否——僅 `close_open_orders_account` |
| 質押帳戶 | 質押程式 | 否——SIMD-0490 將 `rent_exempt_reserve` 固定在 2,282,880 lamports |

包裝 SOL 帳戶是唯一的代幣程式例外：它們的 lamport 餘額*就是*它們的代幣餘額，所以兩個程式都以 `TokenError::NativeNotSupported` 拒絕它們。**兩個**程式都改為公開 `UnwrapLamports`（判別式 45）用於該情況——它在 `spl-token-interface` 中與 `WithdrawExcessLamports` 並列，所以舊版程式也有它，不只是 Token-2022——而 `@solana/spl-token` 自 0.4.15 起提供 `createUnwrapLamportsInstruction`。在普通質押掃描中跳過原生帳戶並有意處理它們；安全執行此操作的模式是 Raydium 自己的程式使用的模式，[下文](#what-the-raydium-programs-sweep-on-their-own-side)。

## `WithdrawExcessLamports` 指令

兩個代幣程式指令列舉中的判別式 **38**。來自 `spl-token-interface`：

```rust theme={null}
/// This instruction is to be used to rescue SOL sent to any TokenProgram
/// owned account by sending them to any other account, leaving behind only
/// lamports for rent exemption.
///
/// 0. `[writable]` Source Account owned by the token program
/// 1. `[writable]` Destination account
/// 2. `[signer]` Authority
/// 3. `..3+M` `[signer]` M signer accounts
WithdrawExcessLamports,
```

三個特性使其可以安全地對錢包中的每個帳戶執行：

* **它不需要金額。** 程式自己計算 `source.lamports − rent.minimum_balance(source.data_len())`，所以它永遠無法將帳戶降至目前最低額度以下，並且隨著後續步驟啟動保持正確。
* **它不關閉任何東西。** 帳戶保留其資料、其擁有者和其代幣餘額。
* **它是冪等的。** 對已在最低額度的帳戶執行它會移動零 lamports 並成功。

凍結的代幣帳戶仍然符合條件：凍結限制代幣移動，不限制 lamports。

### 建立指令

`@solana/spl-token` 不匯出其建構器。截至 `0.4.15`，列舉項目仍被註解掉——注意上游拼寫識別符為 `WithdrawalExcessLamports`，帶有額外的「al」，所以搜尋那個：

```ts theme={null}
// packages/spl-token/src/instructions/types.ts
export enum TokenInstruction {
    // ...
    TransferHookExtension = 36,
    // ConfidentialTransferFeeExtension = 37,
    // WithdrawalExcessLamports = 38,   // ← not exposed
    MetadataPointerExtension = 39,
    // ...
}
```

直接編碼它。有效負載是單個判別式位元組：

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

export function createWithdrawExcessLamportsInstruction(params: {
  source: PublicKey;        // the token account holding excess lamports
  destination: PublicKey;   // where the excess goes — usually the wallet itself
  authority: PublicKey;     // owner of `source`, or the multisig account
  multiSigners?: PublicKey[];
  programId: PublicKey;     // TOKEN_PROGRAM_ID or TOKEN_2022_PROGRAM_ID
}): TransactionInstruction {
  const { source, destination, authority, multiSigners = [], programId } = params;
  return new TransactionInstruction({
    programId,
    keys: [
      { pubkey: source, isSigner: false, isWritable: true },
      { pubkey: destination, isSigner: false, isWritable: true },
      { pubkey: authority, isSigner: !multiSigners.length, isWritable: false },
      ...multiSigners.map((pubkey) => ({ pubkey, isSigner: true, isWritable: false })),
    ],
    data: Buffer.from([38]),
  });
}
```

為每個帳戶傳遞其自己的 `programId`。SPL Token 和 Token-2022 指令可以共享一個交易，但每個都必須發送到擁有其源帳戶的程式。

在主網上測量，該指令在 SPL Token 程式上花費 270 個計算單位，在 Token-2022 上花費 1,414 個——任何一種方式都可以忽略不計。真正的限制是交易大小，而不是計算。

## 尋找可回收帳戶

不要從硬編碼的速率推導超額。詢問叢集每個帳戶現在需要什麼，這樣相同的程式碼在所有五個步驟中都能繼續工作：

```ts theme={null}
const [tokenResp, token2022Resp] = await Promise.all([
  connection.getTokenAccountsByOwner(owner, { programId: TOKEN_PROGRAM_ID }),
  connection.getTokenAccountsByOwner(owner, { programId: TOKEN_2022_PROGRAM_ID }),
]);
const raw = [...tokenResp.value, ...token2022Resp.value];

// one lookup per distinct account size — a wallet normally has two or three
const spaces = Array.from(new Set(raw.map(({ account }) => account.data.length)));
const minimums = new Map(
  await Promise.all(
    spaces.map(async (space) => [space, await connection.getMinimumBalanceForRentExemption(space)] as const),
  ),
);

const reclaimable = raw.filter(({ account }) => {
  // wrapped SOL carries its token balance as lamports — both programs refuse it.
  // The `is_native` COption tag sits at offset 109 in the token account layout,
  // which Token-2022 preserves before its extension data.
  if (account.data.readUInt32LE(109) === 1) return false;
  return account.lamports > minimums.get(account.data.length)!;
});
```

`getMinimumBalanceForRentExemption(0)` 是一個有用的旁路：它返回恰好 `128 × lamports_per_byte`，所以除以 128 可以告訴你叢集在哪個推出步驟上，而無需解析 `Rent` sysvar。

## 批處理：一個交易中能放多少

每個 `WithdrawExcessLamports` 指令貢獻一個唯一的可寫帳戶金鑰——編譯訊息中 32 位元組——加上約 7 位元組的指令編碼。目的地、授權和費用支付者都是同一個錢包，所以它們之間只花費一個金鑰。

針對 1,232 位元組的交易限制，計算預算指令和區塊雜湊後，大約 25 個指令能放入。**每個交易 20 個**是安全的工作數字，也是 Raydium 自己的實現使用的。因此，擁有 116 個可回收帳戶的錢包在六個交易中掃描，每個交易一個 5,000 lamport 基本費用。

注意經濟學：費用按交易收取，而不是按帳戶。回收更少帳戶不會花費更少，這就是為什麼部分掃描很少值得額外往返。

## 透過 Raydium 回收

[raydium.io/reclaim-rent](https://raydium.io/reclaim-rent) 頁面掃描連接錢包的 SPL Token 和 Token-2022 帳戶，顯示按程式分割的總額，並在批處理交易中掃描所有內容。掃描是唯讀的——在你按下**回收所有質押**之前沒有簽名。

該頁面刻意僅涵蓋代幣帳戶。只能透過關閉來釋放質押的帳戶類型被排除而不是列為不可用，因為關閉帳戶是一個不同的、破壞性的操作。

## 從 SDK 演示回收

<Info>
  **版本橫幅。** 這些演示針對 `@raydium-io/raydium-sdk-v2@0.2.64-alpha` 針對 Solana mainnet-beta，驗證於 2026 年 9 月；`raydium-sdk-V2-demo` 儲存庫本身目前安裝 `0.2.62-alpha`，兩者在此可互換。`WithdrawExcessLamports` 是手工編碼的，獨立於 SDK 版本——SDK 僅用於交易建立和批處理。
</Info>

[`raydium-sdk-V2-demo/src/rent`](https://github.com/raydium-io/raydium-sdk-V2-demo/tree/master/src/rent) 中的兩個指令碼：

```bash theme={null}
# read-only: what can this wallet reclaim, and what would it be worth after all five steps
yarn dev src/rent/checkReclaimableRent.ts
yarn dev src/rent/checkReclaimableRent.ts <any wallet address>

# build, simulate (DRY_RUN = true by default), then send the batched sweep
yarn dev src/rent/reclaimRent.ts
```

`reclaimRent.ts` 以每個交易 20 個帳戶的速率批處理，並在一次通過中簽署所有批次：

```ts theme={null}
const batches = chunk(report.accounts, ACCOUNTS_PER_TX);

const builtTxs = await Promise.all(
  batches.map(async (batch) => {
    const builder = new TxBuilder({
      connection,
      feePayer: owner.publicKey,
      cluster: raydium.cluster,
      owner: raydium.owner,
    });
    builder.addInstruction({
      instructions: batch.map((account) =>
        createWithdrawExcessLamportsInstruction({
          source: account.pubkey,
          destination: owner.publicKey,
          authority: owner.publicKey,
          programId: account.programId,
        }),
      ),
    });
    return builder.versionBuild({ txVersion });
  }),
);

// versionMultiBuild puts the calling builder's transaction first and appends
// extraPreBuildData after it, so batch 1 drives and batches 2..n follow in order
const [firstTx, ...restTxs] = builtTxs;
const { execute } = await firstTx.builder.versionMultiBuild({ txVersion, extraPreBuildData: restTxs });
const { txIds } = await execute({ sequentially: true });
```

在發送前模擬。使用 `accounts.addresses` 的 `simulateTransaction` 返回執行後的 lamport 餘額，這是確認算術與叢集實際執行內容相符的最便宜方式。

## Raydium 程式在自己一側掃描的內容

你的錢包不是唯一被降低釋放 lamports 的地方。每個池都持有質押——金庫、LP 鑄幣廠和程式擁有的狀態帳戶，都在舊速率下資金化。該質押屬於協議，而不是 LP：它由建立帳戶的人支付，不是任何池儲備的一部分，也從未進入曲線。

三個程式在 2026 年 9 月 9 日獲得了管理員指令來退還它，CLMM 在 2026 年 9 月 30 日跟進：

| 程式 | 指令 | 簽署者 |
| - | - | - |
| AMM v4 | `WithdrawExcessLamports`（標籤 18） | 僅一個專用收集 lamports 錢包 |
| CPMM | `CollectExcessLamports` | 程式管理員或專用收集 lamports 錢包 |
| LaunchLab | `CollectExcessLamports` | 程式管理員或專用收集 lamports 錢包 |
| CLMM | `CollectExcessLamports` | 程式管理員或專用收集 lamports 錢包 |

地址在 [`reference/program-addresses`](/zh-Hant/reference/program-addresses#excess-lamports-collection-wallets) 中。穩定 AMM 沒有等效項。

**這裡沒有任何東西影響 LP 或交易者。** 這些指令移動 lamports，僅此而已。代幣餘額、帳戶資料、擁有者、池狀態、LP 供應、費用計數器和曲線都未觸及，它們都無法關閉帳戶。池的交換報價在掃描前後相同。沒有使用者端操作、沒有選擇加入，也沒有截止日期。

### 每個程式處理的三種帳戶形狀

所有四個都遵循相同的分派，在源帳戶的擁有者上：

* **由程式授權 PDA 擁有的代幣帳戶或鑄幣廠**：程式 CPI 代幣程式的 `WithdrawExcessLamports`（判別式 38），作為該 PDA 簽署。在 CLMM 中，該 PDA 是 `PoolState` 本身，所以一個呼叫涵蓋一個池的金庫。
* **包裝 SOL 金庫**——`WithdrawExcessLamports` 拒絕原生帳戶，所以程式首先 `SyncNative`（將捐贈的超額折疊到包裝的 `amount` 中），精確測量包裝金額增長了多少，`UnwrapLamports` 該增量，然後斷言包裝餘額回到其掃描前值。如果該檢查失敗，整個指令以 `LamportsCalculateError` 回復。這就是為什麼 SOL 端池金庫在掃描中保持其完整流動性。
* **程式擁有的狀態帳戶**——`AmmInfo`、`PoolState`、`AmmConfig`、`ObservationState`、`PlatformConfig`、CLMM `TickArrayState` 等。程式可以直接扣除其自己的帳戶，所以它將餘額降至 `rent.minimum_balance(data_len)`，完全沒有 CPI。

由任何其他東西擁有的帳戶被無聲地跳過，所以傳遞不相關的帳戶是無害的而不是致命的。

包裝 SOL 序列值得複製，如果你持有自己的原生帳戶：它是在不改變帳戶報告為其代幣餘額的情況下從 wSOL 帳戶取出超額的唯一方式。

<Note>
  **這些路徑取決於部署的代幣程式，而不是 crate 版本。** 所有四個程式都手工編碼代幣指令——`WithdrawExcessLamports` 的單個 `38` 位元組，`UnwrapLamports` 的 `45` 加上 `COption<u64>`——並將它們發送到擁有源帳戶的任何代幣程式。兩個指令都存在於目前主網 SPL Token 和 Token-2022 程式中。執行較舊捆綁 SPL Token 建置的本地驗證器或測試工具不實現它們，針對它的掃描在未知判別式上失敗，而不是在 Raydium 程式中的任何東西上。針對主網複製的代幣程式測試這些路徑。
</Note>

### 仍然無法就地回收的內容

你仍然無法就地回收 CLMM 頭寸的質押。它在頭寸關閉時回來，如上表所述。CLMM 的自己的 `CollectExcessLamports` 不檢查誰資金化了帳戶，所以它可以從 `PersonalPositionState` 或 `LimitOrderState` 取出*超額*。帳戶保持在其質押最低額度，那就是關閉退款的。LaunchLab 基礎鑄幣廠也一樣：初始化指令在鑄造供應的同一呼叫中撤銷 `MintTokens`，所以沒有金鑰能簽署該鑄幣廠的 `WithdrawExcessLamports`，其質押按設計被困。

## 你應該現在回收還是等待？

兩者都很好，差異無論如何都很小：

* **超額不會去任何地方。** 它保留在你自己的帳戶中。沒有過期時間、沒有掃描、沒有截止日期。
* **等待會複利。** 每個步驟從相同帳戶釋放更多，步驟 5 後的一次掃描花費與今天一次掃描相同的費用。
* **現在回收不會放棄後續步驟。** 你今天掃描的帳戶只是在目前最低額度；下一步再次使其超額資金化，你可以再次掃描它。

現在回收的唯一真實成本是基本費用，等待的唯一真實成本是 lamports 保持不動一段時間更長。

## 進一步閱讀

<CardGroup cols={2}>
  <Card title="SIMD-0437" icon="file-code" href="https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0437-incremental-rent-reduction.md">
    提案本身——五個功能閘門和分步降低的理由。
  </Card>

  <Card title="降低質押" icon="book" href="https://solana.com/upgrades/reduced-rent">
    Solana 的推出頁面：目前步驟、時程表和新帳戶的變更。
  </Card>

  <Card title="質押降低：資料支持的分析" icon="chart-line" href="https://solana.com/news/rent-reduction-deep-dive">
    經濟學，以及分步推出旨在管理的狀態增長風險。
  </Card>

  <Card title="帳戶模型" icon="database" href="/zh-Hant/solana-fundamentals/account-model">
    Solana 帳戶如何被資金化、擁有和關閉——上述所有內容的背景。
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.