一文对比两种区块链网络Gas手续费代付(元交易)的实现方式

区块链应用饱为诟病的原因,就是高门槛。比如每发送一笔交易,都需要消耗一定数量的Gas费用,而很多拥有ERC20 代币的用户去使用Dapp,必须先在钱包中保存一定数量的ETH用以支付Gas费用。

Ethereum以太坊的实现方式——元交易合约

如果能够为新用户代付Gas费用,将会大大降低Dapp的使用门槛。而以太坊没有提供原生方法来实现这一点。于是就有了元交易,让没有持有ETH的帐户可以和区块链进行交互,并可能使用ERC20代币去支付Gas。所谓元交易(Meta transaction),就是让用户用自己的密钥来签名发起交易,但不需要用户来支付交易手续费(即 Gas 费用),而由 “中继者(relay)” 来为 TA 支付 Gas 费。中继者作为发送方,将交易提交至网络,并支付 Gas 费用。交易的目标合约可以确定原始用户及其意图,并相应地处理合约的调用。

元交易比较典型的是守卫代理(Bouncer Proxy),它包含4个基本部分:

  1. 用户帐户:未持有ETH的一对公私钥,这个帐户能够为消息签名。
  2. 矿工账户:持有ETH的一对公私钥,能够为用户支付Gas费用,也即代付Gas的元交易矿工
  3. 守卫代理合约(Bouncer Proxy):合约可以接收第三方的签名消息作为输入
  4. 合约接收方:用户真正想与之交互的Dapp相关的合约## NetCloth区块链网络手续费代付

一个元交易的守卫代理合约,可以参考这里

元交易的使用场景

元交易的使用场景,参演是这样的:

  1. 一个用户,没有ETH的账户。
  2. 用户是守卫代理合约的所有者,只有当输入消息由用户自己或者白名单账户签名时,守卫代理合约才能进一步执行转发调用。
  3. 守卫代理合约需要持有ETH或者ERC20代币,这些代币用于对矿工(中继者)进行奖励。

元交易的流程

  1. 用户创建一个不需要支付任何费用的交易,包含以下部分:
  • 用户地址
  • 守卫代理合约地址
  • 交易的合约接收地址,用户真正想调用的Dapp合约
  • 用户交易的value字段
  • 用户交易的data字段,即合约调用的payload
  • 用于奖励给元交易矿工的资产地址
  • 用户奖励给元交易矿工的资产数量
  • 守卫代理合约的nonce,跟踪帐户进行交易的次数,以防止重放攻击并且保持交易顺序
  • 哈希签名,用户用私钥对上述字段的签名
  1. 矿工接收到用户的元交易消息后,调用守卫代理合约的forward函数,进行转发调用,并支付本次调用的Gas费用。 forward的函数输入为:
  • 用户地址
  • 交易的合约接收地址
  • 用户交易的value 字段
  • 用户交易的data字段,即合约调用的payload
  • 用于奖励给元交易矿工的资产地址
  • 用户奖励给元交易矿工的资产数量
  • 用户的哈希签名

守卫代理合约的forward函数,通过验证哈希签名的方式,确认只有用户或者白名单账户签名的元交易,才能被守卫代理合约转发,且元交易的矿工才能被奖励。
当签名验证通过后,相应数量的奖励会从守卫代理合约转移到矿工的帐户上。
然后守卫代理合约,带上用户指定的参数,调用用户指定的合约,并负责Gas的支付。

这样,就实现了一个用户账户,它没有持有ETH但实现了自身交易的提交,并且可能使用ERC20代币来支付Gas。

优缺点

这样的实现方式也有缺点,如果元交易的合约接收地址,是基于msg.sender的应用逻辑,那么整个交互流程将不会顺畅,因为msg.sender标识的是合约的调用者,而元交易的情况下变为代理合约的地址,而不是元交易的用户地址。

如果是第三方帮用户代付Gas费用的话,部署一个守卫代理合约倒没问题。而如果是用户使用ERC20支付Gas的话,那么每个用户需要能够部署自己的代理合约,并且奖励给矿工的代币必须由代理合约持有,每个用户需要能够管理和充值自己在代理合约中的代币。

NetCloth区块链网络手续费代付

ETH用合约解决元交易问题,那自然有项目会实现原生的元交易。NetCloth链不久前升级了最新的功能,以原生的方式,支持了第三方的Gas代付。实现原理是:当一笔交易消息体中包含多个signatures时,NetCloth区块链网络将按交易签名顺序,选择排第一位的收取交易费用。

NetCloth手续费代付技术文档,参考这里

手续费代付原理

NetCloth链上的交易结构:

{
  "type": "nch/StdTx", // 交易type,固定为nch/StdTx
  "value": { // 交易value
    "msg": [], // msg数组
    "fee": {}, // 交易费用
    "signatures": [], // 交易签名,和msg一一对应
    "memo": "" // 交易附带的memo
  }
}

当一个第三方愿意帮用户支付Gas费用时,可以和用户协作生成一笔交易,同时将自己的交易签名放第一位。由于msg和 signatures是一一对应的,所以第三方需要生成一笔由自己发起的交易,放msg数组中的第一位。

交互流程如下:

在这里插入图片描述

流程

Gas费用代付流程

  1. 用户生成一笔交易,先不签名,发送给第三方
  2. 第三方修改交易,增加自己的msg,并签名后,其中msg和签名均放在交易中的第一个位置,返还给用户
  3. 用户对收到的交易,使用自己的私钥签名
  4. 用户将最终的交易发送到网络,链上执行交易的时候,将向交易中的第三方收取Gas费用

优点

1.交易是基于各自签名的,用户和第三方之间无需信任
2.第三方代付的Gas费用,可以通过链外结算方式向用户收取
3.即使合约有基于msg.sender的应用逻辑,用户也可以正常使用
4.整个流程参与只有3个角色,没有合约层面的交互

总结

单纯从实现上来说,很难评判合约实现与原生实现孰优孰劣。不过对于非熟练区块链开发者而言,理解合约和正确使用合约,并规避安全问题,是比较高的门槛。如果能有比较好的原生支持手段,不论是对于开发者使用,还是集成至客户端给小白用户使用,都会极大降低小白用户使用Dapp和区块链应用的门槛。

参考:
[1]: https://medium.com/@andreafspeziale/understanding-ethereum-meta-transaction-d0d632da4eb2
[2]: https://docs.netcloth.org/advanced/fee-payment.html

发布了208 篇原创文章 · 获赞 33 · 访问量 82万+
App 阅读领勋章
微信扫码 下载APP
阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览