Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

零 gas 交易

Gas Waiver 让应用程序可以代表用户承担 gas 费用。用户使用 gasPrice = 0 签署一笔交易,由治理注册的 waiver 将其包装,验证者以零成本为用户执行该调用。本指南将带你完成一笔符合条件的转账,展示如何验证 gas 已被豁免,并解释 waiver 涵盖与不涵盖的范围。

你将构建的内容

一个两脚本流程,通过托管的 Waiver Server 提交一笔 USDT0 转账,获取收据,并确认 gasPrice = 0

演示

step 1. Connect wallet, balance displayed as 0.01 USDT0

step 2. Send transaction via Gas Waiver → [Run]

step 3. Result
        tx:                   0x8f3a...2d41
        Gas fee paid by you:  0.000000 USDT0
        Balance after:        0.01 USDT0

waiver 何时生效

当以下所有条件均满足时,交易符合条件:

  • 用户使用 gasPrice = 0 签署内部交易。
  • 提交者是治理注册的 waiver 地址。
  • 目标 to 地址和方法选择器位于 waiver 的 AllowedTarget 策略中。
  • 包装交易发送到标记地址 0x000000000000000000000000000000000000f333,且 value = 0gasPrice = 0

如果其中任何一项不满足,验证者将拒绝该包装交易,不执行内部调用。未列入 AllowedTarget 的合约调用不在涵盖范围内。无法进行任意的自助 waiver;每个 waiver 都必须通过验证者治理注册。

前置条件

  • Waiver Server 的 API 密钥,由 Stable 团队签发。
  • 已在 waiver 的 AllowedTarget 策略上注册的目标合约地址和方法选择器。
  • 一个测试网上的用户钱包,无需 USDT0 用于支付 gas。

步骤 1:签署符合条件的 InnerTx

用户使用 gasPrice = 0 签署一笔标准交易。在本示例中,该调用是一笔 USDT0 transfer,这是应用程序承担 gas 流程中常见的 AllowedTarget

// config.ts
import { ethers } from "ethers";
import "dotenv/config";
 
export const CONFIG = {
  RPC_URL: "https://rpc.testnet.stable.xyz",
  CHAIN_ID: 2201, // 988 for mainnet
  WAIVER_SERVER: "https://waiver.testnet.stable.xyz",
  USDT0_ADDRESS: "0x78Cf24370174180738C5B8E352B6D14c83a6c9A9",
};
 
export const provider = new ethers.JsonRpcProvider(CONFIG.RPC_URL);
export const userWallet = new ethers.Wallet(process.env.USER_PRIVATE_KEY!, provider);
// signInner.ts
import { ethers } from "ethers";
import { CONFIG, provider, userWallet } from "./config";
 
const usdt0 = new ethers.Contract(CONFIG.USDT0_ADDRESS, [
  "function transfer(address to, uint256 amount) returns (bool)"
], provider);
 
const callData = usdt0.interface.encodeFunctionData("transfer", [
  "0xRecipientAddress",
  ethers.parseUnits("0.001", 18),
]);
 
const gasLimit = await provider.estimateGas({
  from: userWallet.address,
  to: CONFIG.USDT0_ADDRESS,
  data: callData,
});
 
const nonce = await provider.getTransactionCount(userWallet.address);
 
const innerTx = {
  to: CONFIG.USDT0_ADDRESS,
  data: callData,
  value: 0,
  gasPrice: 0,
  gasLimit,
  nonce,
  chainId: CONFIG.CHAIN_ID,
};
 
export const signedInnerTx = await userWallet.signTransaction(innerTx);
console.log("Signed InnerTx:", signedInnerTx);
npx tsx signInner.ts
Signed InnerTx: 0xf8a8...c1

步骤 2:通过 Waiver Server 提交

Waiver Server 会包装已签署的内部交易并广播。你需要一个服务器签发的 API 密钥。

// submit.ts
import { CONFIG } from "./config";
import { signedInnerTx } from "./signInner";
 
const response = await fetch(`${CONFIG.WAIVER_SERVER}/v1/submit`, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${process.env.WAIVER_API_KEY}`,
  },
  body: JSON.stringify({ transactions: [signedInnerTx] }),
});
 
const reader = response.body!.getReader();
const decoder = new TextDecoder();
let txHash = "";
 
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  for (const line of decoder.decode(value).trim().split("\n")) {
    const result = JSON.parse(line);
    if (result.success) {
      txHash = result.txHash;
      console.log(`tx confirmed: ${txHash}`);
    } else {
      console.error(`tx failed: ${result.error.message}`);
    }
  }
}
export { txHash };
npx tsx submit.ts
tx confirmed: 0x8f3a...2d41

步骤 3:验证收据显示零 gas

获取收据并确认 effectiveGasPrice 为 0。这就是用户未支付任何 gas 的密码学证明。

// verify.ts
import { provider } from "./config";
import { txHash } from "./submit";
 
const receipt = await provider.getTransactionReceipt(txHash);
 
const gasUsed = receipt!.gasUsed;
const effectiveGasPrice = receipt!.gasPrice;
const totalFee = gasUsed * effectiveGasPrice;
 
console.log("Gas used:           ", gasUsed.toString());
console.log("Effective gas price:", effectiveGasPrice.toString());
console.log("Gas fee paid:       ", `${totalFee.toString()} USDT0 (wei-equivalent)`);
npx tsx verify.ts
Gas used:            21000
Effective gas price: 0
Gas fee paid:        0 USDT0 (wei-equivalent)

effectiveGasPrice0 确认了该交易在已注册的 waiver 下执行,且用户未被收费。

Gas Waiver 不涵盖的范围

  • AllowedTarget 之外的合约:任意合约调用不在涵盖范围内。每个目标都通过治理按 waiver 进行限定。
  • 用户提交的包装交易:如果用户直接提交到 0x...f333,将会失败。只有已注册的 waiver 地址才能进行包装。
  • 费用提取:验证者不接受内部交易或包装交易上任何非零的 gasPrice

关于完整的策略模型和按 waiver 的范围规则,请参阅 Gas waiver 协议

推荐的后续步骤

  • 集成 Waiver Server — 完整的 API 参考、批量提交、错误码和 NDJSON 流式传输。
  • 自托管 Gas Waiver — 注册你自己的 waiver 地址,无需托管 API 即可广播包装交易。
  • Gas waiver 协议 — 阅读完整规范:标记路由、包装格式、治理控制。