# Gas 费支付

在大多数区块链系统中，每笔交易都需要发起者支付一笔费用，通常称为“Gas 费”。对于可能没有原生货币来支付这些费用的新用户来说，这可能是一个巨大的障碍。OCAP 客户端引入了 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)文档。
