Sui 的代付 Gas 在协议层是成熟的,但"谁付、怎么付、付多少"这三个问题需要分开处理。最省事的做法是用现成的 Gas Station 服务(如 Shinami 或 Enoki),把预算控制和滥用防护交给服务商;如果你自己搭,核心风险不在签名环节,而在你签完名之后,用户拿着你赞助的交易去做了你没批准的事。
先分清:代付 Gas 和免 Gas 是两件事
Sui 目前有两种让用户不付 Gas 的方式,适用场景不同。
代付 Gas(Sponsored Transaction):你作为赞助方,用自己的 SUI 为用户的交易支付 Gas。用户仍然需要构造交易,但不需要持有 SUI。适用于任何你想补贴用户操作成本的场景,比如新用户首次 swap、游戏内操作、企业为员工报销交易费用。
免 Gas 稳定币转账(Gasless Stablecoin Transfer):这是协议层功能,仅限白名单稳定币(USDC、USDsui 等)的 P2P 转账,金额不低于 0.01,且交易必须完全消耗或转换涉及的代币。不需要任何人付 Gas,包括你。如果你的场景恰好是稳定币转账,优先用这个,成本为零且没有赞助方的资金风险。但它的范围很窄:复杂操作、非白名单代币、低于门槛的金额都不适用。
签名流程:谁先签,决定了你的风险敞口
代付交易的签名结构要求用户和赞助方都签同一份完整的 TransactionData,签名顺序不重要,但必须包含 GasData。两种构造方式对应不同的风险:
用户先构造,你后签(常见于用户发起的操作):用户先构造 GasLessTransactionData(不含 Gas 信息的交易体),发给你。你检查这笔交易要做什么,确认在允许范围内,然后填入自己的 Gas 对象,签上你的名,把签好的完整交易发回给用户。用户签完提交。这里的风险点是:你必须在签名之前验证交易内容。如果你不检查就签,用户可以在交易里调用任何函数,包括把你自己钱包里的资产转走(如果该函数恰好需要你的签名授权)。Sui 文档明确说,赞助方应当"检查交易,验证它在你批准的应用程序范围内"。
你先构造,用户后签(常见于奖励领取、促销活动):你构造一笔包含具体操作和 Gas 数据的交易,先签名,然后通过邮件、短信或应用界面发给用户。用户检查后签名提交。这种方式的控制权在你手里,因为你决定了交易内容。风险在于用户可能不签,你预付的 Gas 对象在交易过期前被锁定。
SDK 层面,onlyTransactionKind: true 用来剥离 Gas 信息,让赞助方后续填入。赞助方用 setGasOwner 把自己的地址设为 Gas 所有者,然后双方分别签名,提交时传两个签名。
预算控制:设在三个地方,不要只靠事后看账单
每个 Gas Station 服务的单笔上限。 第三方服务通常提供自动预算或手动设置。Shinami 的 Gas Station 如果请求中不指定 gasBudget,会使用自动预算功能。Enoki 在开发者后台允许配置每笔或每用户的 Gas 上限。如果你自己搭,SDK 的 GasData 里要显式设置 gasBudget,不要留空或给一个过大的默认值。一笔交易的实际 Gas 消耗可能远低于预算,但恶意构造的交易可以故意烧到预算上限。
时间维度的总消耗上限。 单笔上限挡不住高频滥用。你需要按用户地址、按时间窗口(每小时/每天)设置累计上限。Shinami 提供可筛选的使用指标,可以查看随时间变化的支出,用于调整赞助策略。Enoki 同样有 Developer Portal 的监控。自己搭的话,至少要在服务端记录每个地址的赞助次数和金额,超过阈值就拒绝。
Gas 对象的生命周期管理。 如果你用具体的 SUI coin 对象作为 Gas(而不是地址余额),一个 coin 在被用于赞助后,如果交易没有上链,这个 coin 在过期前不能被其他交易使用。Shinami 的赞助默认设置一小时的过期时间。你需要监控未花费的赞助交易,避免大量 coin 被无效请求锁定,导致可用 Gas 池枯竭。
防滥用:验证交易内容比限流更重要
限流(rate limiting)能挡住脚本小子,但挡不住一个精心构造的恶意交易。核心防护是在签名前解析并验证交易意图。
如果你提供的是"用户提议、你审批"的模式,至少检查三件事:
Move call 的目标地址白名单。 只赞助调用你部署的合约或你信任的合约的交易。用户构造的交易里可以包含任意
moveCall,如果你不限制 target,他可以调用一个把你作为 sender 或 gas owner 的敏感函数。交易中是否有对
tx.gas的引用。 如果用户的交易体里包含splitCoins(tx.gas, ...)之类的操作,意味着用户试图从你的 Gas coin 中分走资金。部分 Gas Station 库对此有allowGasCoinUsage策略开关,默认应关闭。最小支付/交互要求。 如果你的场景是用户支付某种代币、你补贴 Gas,可以在赞助策略里设置
minRequiredPayment,低于阈值的交易直接拒绝,用于挡掉纯薅 Gas 的请求。或者用allowedReceivers限制只有支付给你指定地址的交易才赞助。
自己搭服务时,一个可参考的防护架构是:收到用户的 kind bytes → 解析交易 → 检查 moveCall target 是否在白名单 → 检查是否引用 tx.gas → 检查发送方地址是否在允许列表 → 检查该地址的当日累计消耗 → 通过则填入 Gas 签名返回,否则拒绝。
什么时候该用第三方服务,什么时候自己搭
用第三方(Shinami 或 Enoki):你的团队没有专人维护 Gas 基础设施,或者你想尽快上线。Shinami 按 SUI 计费(因为运营成本主要是 SUI),提供详细的支出指标和 Gas Station 状态查询。Enoki 支持法币计费,如果你不想持有和管理 SUI,这条路更直接。两者的取舍主要看你的财务偏好:愿意持有 SUI 换更细的指标,还是用法币换省心。
自己搭:你的赞助逻辑和业务深度绑定,第三方服务的通用策略不够用;或者你的量足够大,第三方服务的加价不划算。代价是你需要自己实现上述所有验证和限流逻辑,并管理 Gas coin 的补充和过期。
完成标准
不是"用户成功提交了一笔你付了 Gas 的交易",而是:在一段时间内,你的赞助支出与业务目标(新用户激活数、交易笔数、稳定币转账量)的比值在可接受范围内,且没有出现你未批准的 moveCall 被赞助上链的记录。 如果只看"交易成功了",你可能在为别人的套利或垃圾交易买单。先跑一周的小额度赞助,拉出每笔赞助交易的 target 和实际 Gas 消耗,确认没有异常调用,再逐步放开预算。



