xDeFiLabs:以太坊 Gas 面面观

xDeFiLabs 如何优化 gas?

得益于 DeFi 的普及和 Crypto 行业的牛市,大量 DeFi Token 投资者在 2020-2021 年普遍斩获颇丰,人均净值迅速增加。但如果你问他们“最近在以太坊上使用 DeFi 和 NFT 等产品”的体验如何时,回答可就不那么乐观了。因为使用成本水涨船高,打消了长尾用户频繁使用 Ethereum 主网的积极性。

1. 以太坊区块链 Gas 的消耗逻辑:GasPrice 和 GasLimit

在 ETH 区块链系统上,不论进行何种操作,gasPrice 和 gaslimit 都是你在操作时必须付出的、不可不了解的代价。

gasPrice 的单位经常是 gwei,因为 1wei = 10^-18 eth,是 eth 原生的最小单位。1gwei = 10^9wei = 10^-9eth,是每次在 eth 进行操作时所有希望进行操作的人对一个块中打包交易资源竞争得到的值:也就是价高者打包,否则无法打包。

xDeFiLabs:以太坊 Gas 面面观

ETH 的区块在 2017 年底 1C0 狂热和 2020 年初 312 大崩溃时经历了了两次暂时的“满块”,就是用户使用时需要为了区块空间进行竞争,用户过多,导致报价过低的用户无法打包交易,一定时间后交易失败,但是因为 2019 年 ERC-20USDT 的广泛使用和 2020 年 Uniswap 的广泛使用,导致了常态性的满块(总的 gas 消耗 gasLimit 超过了一个块所能承受的 12500000)。

xDeFiLabs:以太坊 Gas 面面观

GasLimit 不仅仅是针对 ETH 的一个块说的,也可以针对一笔交易。比如,metamask 插件一般会在用户使用时,告诉用户 gasLimit,这是一个预估,不是精确值。如果实际使用超过了这个值,调用本身会失败。如果没超过这个值,只会消耗 gas*gasPrice 这个值,最后在一个块里打包的交易总的 gas 也不会超过 12500000 (至少 2020 年 6 月 gasLimit 上限提升,运行到 2021 年 2 月成稿之日看是这样)。

2. 在 Solidity 编程计算层面如何保证更低的 Gas

Solidity 的书写风格有些像 javascript,具体执行层面依赖于编译成 EVM 可运行的操作码。我们先不论他被编译成什么样的操作码能够节省 gas,至少在 Solidity 这一层面做计算,你可以找机会节省尽可能多的 gas。

A、整数计算思维
Solidity 并没有 IEEE-754 所定义的浮点数:这类浮点数计算本来是指导了 CPU 的寄存器设计,若为了共识的“通用性、确定性、一致性”考虑,最常见的数据类型是 uint256,以及用整数先模拟小数,再模拟浮点数的行为,但整体来看,需要编程者有整数思维。

假设你有方便的数学库,你会发现 a.p(2) 其实是不如 a>>1 来的快,因为数学库的乘除法依然是调用此类消耗较小的操作完成的。好在 ETH 开发的先驱者(比如 openzeppellin,gnosis,balancer 等)在实现项目的过程中产出了一些数学库方便别人使用,这些操作包括四则运算、乘方开方,以及指数对数操作。

这里有一篇不错的四则运算以外的计算方案 https://medium.com/coinmonks/math-in-solidity-part-5-exponent-and-logarithm-9aef8515136e

B、规避循环,除非你清楚你的计算复杂度

当循环条件是开放的时候,比如 for 循环第二个条件为空,或者 while 语句判断条件为真的时候,很容易无法估计循环体内计算对 gas 是怎样的消耗,会让 gas 消耗不可接受,或者 metamask (以及其他工具)无法正确估计 gasLimit 导致 ETH 合约调用失败。

除此之外,如果特别熟悉 solidity 合约书写的科学家能够在数学上花点功夫的话,建议参考《Hacker’s Delight》,相信不仅对理解数学库,而且对于简化代码 gas 消耗方面大有益处。比如在计算机发展过程中,我们看到了雷神 3 算法对牛顿法的应用 https://en.wikipedia.org/wiki/Fast_inverse_square_root

尽管这个算法依然仅是对 IEEE-754 标准浮点数有效,但是在 solidity 中,一直有专业的算法优化者将暴力计算缩减为损耗非常小的算法,比如: https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/libraries/Math.sol

3. 在 EVM 层面如何保证更低的 Gas

根据 https://medium.com/coinmonks/on-efficient-ethereum-addresses-3fef0596e263 给出的线索,以太坊黄皮书给出了详细的费用明细。

xDeFiLabs:以太坊 Gas 面面观

这篇文章中提到了 Gtxdatazero 和 Gtxdatanonzero 的费用差别,这个核心差别的逻辑就是:ETH 地址里面的 00 越多(注意,是成对出现的 0),不管这个地址是合约的,还是普通人转入转出地址,都或多或少的节省 0.4-5% 的 gas 费用。

除此以外,参考各种操作对应于 EVM 上的操作码,你也可以尽可能的规避高 gas 操作,使用低 gas 操作,构建 solidity 代码。

对普通人来说,拥有一个 0x00 开头的地址是很容易的,一个最实用的工具是(https://github.com/johguse/profanity),可以为你生成 0x00 开头的地址。你甚至还可以加--contract 参数,从而你得到的私钥下创建的第一个智能合约就拥有了这类地址。

4. GasToken 家族:另一种实操

这是一种针对销毁行为构建可 refund gas 的实际操作案例。GST 和 GST2 是一些科研人员根据 Gsclear 和 Gssuicide 退还 gas 费用的特性建立的,其中 GST 是基于释放存储的(Gsclear 的 refund)而 GST2 是基于释放合约的(Gssuicide),普遍而言,人们会认为 GST2 第二代会更合理,但在技术发展的过程中,其实未必 GST2 会比 GST 一直更有优势:如果 ETH 1.x 技术路线里出现了对于状态存储的优化,GST 也可能迎来复兴。

1inch 的 CHI gastoken 在 GST2 之上,增加了 token 地址中包含的 00 数量,但因为 1inch 更加积极的商业化运营,也让这种操作正逐渐变的广为人知。单纯作为一种补贴手段,市场上也出现了 uGAS,UNDG 等例子。

5. 案例 xDeFiLabs 如何优化 gas

考虑到上百万美金的 zksnarks layer2 方案审计成本,xDeFiLabs 团队暂时选择了先验证产品逻辑。

在产品优化过程中,用户的交易已经涉及了 a**b 的逻辑,其中 b 是用 uint256 表示的 decimal 变相承担小数的作用。在金融产品设计过程中,对池的平衡性设计可以将 b 的取值 [1,49] 之间任意的小数,迅速的缩减到{1,2,3,4,6,8,12}等一组正整数上,节省数千到数万 gas 成本。在调用数学库时,Balancer 数学库 bpow 的小数部分并没有被真正调用,而只有 bpowi 被调用了。

在 XDEX 的代币发行的过程中,xDeFiLabs 根据 Chapter3 提到的方式,确保了自己 0x00 地址的竞争力(计算出 12 个 0 是现在唯一可行的方案,超过了 TokenLon 使用的 11 个 0,ETH2.0 打款地址的 8 个 0,以及 GST2 的 6 个 0,和 1inch CHI 的 12 个 0 保持一致)。

在设计 xHalfLife 的设计过程中,为了确认用户可以提取多少 vesting 账户中的收益,原始版本使用了循环计算的方式,循环的数量在极端情况下涉及到块高度差。我们可以知道一周的时间覆盖了数千到数万个块高度差,如果每个循环体都是上百的 gas 消耗,那么在某个用户提款时,单笔合约调用千万级 gas 的消耗显然是不可接受的(大概是转账成本的数百倍)。因此从 fundStream,BalanceOf,Withdraw 三个函数里,把循环去掉,继续采用了一种 a**b 的化简方式。此时,我们为了保留更清楚的逻辑,把简化掉的循环代码留在了 github 代码注释里。在调用时,考虑到用户的体验(Sushi 的收益每个块都在跳,而 xHalfLife 初版代码未必能做到这一点),保留了 b 是小数的可能性。

更多 xDeFiLabs 官方动态

请关注

官网:https://xdefi.com

项目白皮书

https://docs.xdefi.com/en/whitepaper

您可关注 Discord 官方频道

https://discord.gg/E5Y8 hpb

您可关注 Medium 官方频道

https://medium.com/@xdefilab

在 Twitter 上关注 @xdefilab,跟踪最新动态。

如果对项目代码感兴趣可访问:

https://github.com/xdefilab

Telegram 电报群:

中文 https://t.me/xdeficn

英文 https://t.me/xdefilab

欢迎添加 xDeFi 小助手微信 xdefilab。小助手可以随时为您提供有关 xDeFi 帮助,还可以邀请您进入 xDeFi 官方微信群,一起交流 xDeFi 项目最新进展!