# Gas 支付

在大多數區塊鏈系統中，每筆交易都需要由發起人支付一筆費用，通常稱為「Gas」。對於可能沒有原生貨幣來支付這些費用的新使用者來說，這可能是一個重大的障礙。OCAP Client 引入了 Gas 支付功能，允許應用程式開發者贊助這些費用，為其使用者創造無縫的「免 Gas」體驗。

這個強大的功能使 dApp 能夠將 Gas 的複雜性抽象化，從而改善使用者引導流程和整體應用程式的可用性。


## 運作方式

Gas 支付機制是透過標準的 HTTP 標頭來實現的。當您在客戶端實例上設定 Gas 支付者錢包時，客戶端會自動將兩個特殊的標頭附加到它發送給區塊鏈節點的每個 `sendTx` 變更中：

* `x-gas-payer-pk`：將支付 Gas 費用的錢包的公鑰。
* `x-gas-payer-sig`：由 Gas 支付者私鑰簽署的 JSON Web Token (JWT)。此權杖包含交易的雜湊值，作為贊助者為該特定交易支付費用的可驗證授權。

當區塊鏈節點收到交易時，它會執行兩項關鍵驗證：

1. 驗證交易本身的使用者簽名。
2. 根據交易雜湊值驗證標頭中的 Gas 支付者簽名。

如果兩個簽名都有效，交易將在使用者授權下執行，但相應的 Gas 費用會從 Gas 支付者的帳戶餘額中扣除。

### 工作流程圖

下圖說明了從交易發起到執行的整個 Gas 支付流程：

<!-- DIAGRAM_IMAGE_START:sequence:4:3 -->

![Gas Payment](assets/diagram/core-concepts-gas-payment-01.jpg)

<!-- DIAGRAM_IMAGE_END -->


## 使用範例

若要啟用免 Gas 交易，您只需為贊助帳戶建立一個錢包實例，並使用 `setGasPayer` 方法將其設定在客戶端上。

```javascript Gas 支付者設定與使用 icon=logos:javascript
import Client from '@ocap/client';
import Wallet, { fromRandom } from '@ocap/wallet';

// 1. 初始化客戶端以連接到 Beta 鏈
const client = new Client('https://beta.abtnetwork.io/api');

// 2. 為 Gas 支付者（您的應用程式錢包）建立一個錢包
// 此錢包必須有足夠的原生代幣（TBA）來支付交易費用。
// 您可以從水龍頭獲取測試代幣：https://faucet.abtnetwork.io/
const gasPayerWallet = Wallet.fromJSON({
  sk: '...your_sponsor_secret_key...',
  pk: '...your_sponsor_public_key...',
  address: '...your_sponsor_address...',
});

// 3. 在客戶端實例上設定 Gas 支付者
client.setGasPayer(gasPayerWallet);

// 4. 為終端使用者建立一個錢包。
const userWallet = fromRandom();

// 5. 使用使用者的錢包發送交易。
// 該交易由使用者簽署，但 Gas 費用由 gasPayerWallet 支付。
async function performGaslessTransaction() {
  try {
    // 注意：雖然新帳戶在收到第一筆入帳交易時會在鏈上建立，
    // 但它必須先存在於鏈上才能 *發送* 交易。
    // 您可以透過從水龍頭向其發送少量代幣來進行初始化。

    const receiverAddress = 'z1...'; // 一個有效的接收者地址
    const hash = await client.transfer({
      to: receiverAddress,
      tokens: [{ value: '0.1' }], // 發送 0.1 TBA
      wallet: userWallet,
    });

    console.log('Gasless transaction successful. Hash:', hash);
    console.log(`Review on explorer: https://beta.abtnetwork.io/explorer/txs/${hash}`);
  } catch (error) {
    console.error('Transaction failed:', error);
  }
}

performGaslessTransaction();
```

在此範例中，即使 `userWallet` 的原生代幣餘額為零，它也可以成功發送交易，因為 `gasPayerWallet` 支付了費用。這創造了一種無摩擦的體驗，特別是對於加入您應用程式的新使用者而言。

---

若要了解交易從建立到最終確認的完整過程，請參閱 [交易生命週期](./core-concepts-transaction-lifecycle.md) 文件。
