Gas 豁免协议
本文档规定了 Gas 豁免机制:交易格式、标记路由、治理控制和豁免服务器 API。
摘要
Gas 豁免通过允许一小组经治理批准的地址(“豁免者”)提交 gasPrice = 0 的交易,从而在 Stable 上实现免 Gas 的终端用户交易。Stable 目前运营一个豁免服务(“豁免服务器”),您可以与之集成以提供免 Gas UX,而无需实现协议特定的包装器逻辑。
范围
本规范涵盖:
- 免 Gas 交易的协议级规则
- 包装器交易机制和标记地址
- 治理控制的授权和允许的目标
- 用于提交已签名用户交易的豁免服务器接口
定义
- 豁免者:通过验证者治理在链上注册的以太坊地址,被授权提交免 Gas 交易。
- InnerTx:终端用户签名的
gasPrice = 0的交易。 - WrapperTx:由豁免者签名,将用户的
InnerTx传输到链上并授权执行的交易。 - 标记地址:用于标识豁免包装器交易的哨兵地址:
0x000000000000000000000000000000000000f333。 - AllowedTarget:将豁免者限制为特定合约地址和方法选择器的策略。
概述
Gas 豁免使用包装器交易模式:
- 用户用
gasPrice = 0签署一个InnerTx。 - 豁免者将
InnerTx包装到WrapperTx中并广播。 - 验证者检测标记交易,验证豁免者授权和策略约束,然后执行嵌入的
InnerTx。
Stable 运营一个豁免服务(豁免服务器),该服务在链上注册为授权豁免者。您与豁免服务器 API 集成以提交已签名的 InnerTx 有效载荷。
协议规范
标记地址路由
当且仅当满足以下条件时,交易才被视为豁免包装器交易:
to == 0x000000000000000000000000000000000000f333。
协议将交易的 data 字段解释为编码的内部交易有效载荷,并使用下面的豁免验证规则进行处理。
授权和策略检查
对于每个候选包装器交易,验证者必须强制执行:
-
豁免者授权
WrapperTx.from必须是通过治理在链上注册的豁免者地址。
-
Gas 豁免
WrapperTx.gasPrice必须等于0。InnerTx.gasPrice必须等于0。
-
目标允许列表
InnerTx.to以及从InnerTx.data中提取的方法选择器必须被豁免者的AllowedTarget策略允许。
-
价值限制
WrapperTx.value必须等于0。
如果任何检查失败,验证者将拒绝包装器交易并且不执行内部交易。
执行语义
如果所有检查都通过:
- 协议以用户身份执行
InnerTx,保留用户的from、nonce和调用语义。 - Gas 核算由豁免机制处理:用户不支付 Gas,豁免交易根据功能定义使用
gasPrice = 0。 - 包装器交易必须提供足够的
gasLimit来覆盖InnerTx的执行(包括解包和验证的开销)。
交易格式
WrapperTx
包装器交易由豁免者签名并发送到标记地址。
WrapperTx {
from: waiver_address,
to: 0x000000000000000000000000000000000000f333,
value: 0, // 必须为零
data: RLP(InnerTx), // RLP 编码的内部交易
gasPrice: 0, // 必须为零
gasLimit: sufficient_for_inner, // 必须覆盖内部执行 + 开销
nonce: waiver_nonce
}InnerTx
内部交易由终端用户签名。
InnerTx {
from: user_address,
to: target_contract,
value: value,
data: call_data,
gasPrice: 0, // 必须为零
gasLimit: execution_gas,
nonce: user_nonce
}治理控制的访问
豁免者授权由链上验证者治理控制。
治理控制提供:
- 豁免者地址的可审查授权
- 豁免者注册和更新的链上透明度
- 撤销能力
- 通过
AllowedTarget进行的每个豁免者范围限制
安全模型
终端用户签名完整性
用户签署 InnerTx。豁免者无法修改内部交易有效载荷而不使签名失效。您仍然必须确保用户只签署预期的交易有效载荷。
信任边界
如果合作伙伴通过豁免服务器路由提交,Gas 豁免会引入服务依赖性:
- 服务的可用性影响提交免 Gas 交易的能力。
- 授权仍然在链上;只有注册的豁免者地址才能产生有效的包装器提交。
集成
三种路径会产生相同的链上结果,不同之处在于谁持有豁免密钥。请参阅选择集成路径。
针对托管豁免服务器:
- 从用户那里收集已签名的
InnerTx(gasPrice = 0)。 - 将已签名的内部交易提交给豁免服务器 API。
- 处理流式结果并将交易哈希显示给终端用户。
从您自己注册的豁免地址,@stablechain/enterprise 在一次调用中构建、签名和广播 WrapperTx。请参阅使用 Gas 豁免进行中继,或自托管 Gas 豁免以直接构建包装器。
豁免服务器
概述
豁免服务器将已签名的用户 InnerTx 有效载荷包装并广播为豁免者授权的包装器交易。您无需构建包装器交易或操作豁免地址。
端点和基本 URL
基本 URL:
- 主网:待定
- 测试网:
https://waiver.testnet.stable.xyz
认证
除健康检查外,所有端点都需要持有者令牌认证:
Authorization: Bearer <your-api-key>API
GET /v1/health
健康检查端点。
认证:无。
POST /v1/submit
提交一批已签名的内部交易。
认证:需要 (Bearer)。
请求正文:
{
"transactions": ["0x<signedInnerTx1>", "0x<signedInnerTx2>"]
}响应以 NDJSON(换行符分隔的 JSON)流式传输。每行对应一个提交的交易索引。
示例:
{"index":0,"id":"abc123","success":true,"txHash":"0x..."}
{"index":1,"id":"def456","success":false,"error":{"code":"VALIDATION_FAILED","message":"invalid signature"}}GET /v1/submit
用于流式提交的 WebSocket 接口。
认证:需要 (Bearer)。
集成示例
const WAIVER_SERVER = "https://waiver.testnet.stable.xyz";
async function submitGaslessTransaction(signedInnerTxHex, apiKey) {
const response = await fetch(`${WAIVER_SERVER}/v1/submit`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${apiKey}`,
},
body: JSON.stringify({
transactions: [signedInnerTxHex],
}),
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
const lines = decoder.decode(value).trim().split("\n");
for (const line of lines) {
const result = JSON.parse(line);
console.log(result);
}
}
}创建用户 InnerTx
您负责构建 gasPrice = 0 的 InnerTx,然后收集用户签名。
示例:
import { ethers } from "ethers";
async function createInnerTx(userWallet, contractAddress, callData, nonce) {
const innerTx = {
to: contractAddress,
data: callData,
value: value,
gasPrice: 0, // 豁免必须为 0
gasLimit: 100000,
nonce: nonce,
chainId: 2201, // 主网为 988,测试网为 2201
};
return await userWallet.signTransaction(innerTx);
}错误代码
PARSE_ERROR:解析交易失败INVALID_REQUEST:请求正文格式错误BATCH_SIZE_EXCEEDED:批处理大小超过允许的最大值VALIDATION_FAILED:交易验证失败BROADCAST_FAILED:广播到链失败RATE_LIMITED:速率限制已超出QUEUE_FULL:服务器队列已满TIMEOUT:请求超时
下一步建议
- 零 Gas 交易:以演示为中心的演练,显示零 Gas 费的收据。
- 启用免 Gas 交易:完整的托管 API 集成指南,包括批量提交和错误处理。
- 自托管 Gas 豁免:运行您自己的豁免基础设施,无需托管 API。
- 使用 Gas 豁免进行中继:使用类型化的 Enterprise SDK 客户端从您自己的豁免赞助 Gas。

