前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >发现一种gas优化的新方法

发现一种gas优化的新方法

作者头像
Tiny熊
发布2022-02-22 18:19:57
5420
发布2022-02-22 18:19:57
举报
文章被收录于专栏:深入浅出区块链技术

本文作者:jackson[1]

发现:

最近看到一个很有意思的项目 FORT,说他有意思,一个是其产品的逻辑新颖,折现计算机和无限流动性,这些看起来很技术化的概念有意思。另外一个是其合约的写法有很多有意思的地方。在其中就看到了一种通过对数据进行编码的 gas 优化方法,下面对这种方法做一个简单的分析。

问题:

我们知道,以太坊上 gas 消耗最大的跟存储相关的指令,因此针对存储进行优化是一个重要的方向。而在做项目的时候,一些数据,像价格,余额等,通常都用 uint256 来表示,这是一个以太坊存储槽的大小,也就是说,一个价格就需要单独占用一个存储槽。因为不同的代币,精度和价格相差极大,导致我们不能简单的用更小的数据类型来表示价格,而这个问题,在 FORT 的代码里面有一种很简单高效的解决方法,下面是从其 github 上的代码:

如上图所示,其通过_encodeFloat()方法将 uint256 编码成一个 uint56,通过_decodeFloat()两个方法,将编码的 uint56 解码成 uint。从而让原本需要占用 256 位的数据压缩到了 56 位,这个压缩比还是很高的。那么,这是什么原理呢?

分析:

  1. _encodeFloat()方法是将原来的 uint256 表示成一种类似科学计数法的形式,这类似计算机中的浮点表示形式,形式如 fraction * 16 ^ exponent。编码时循环对目标数据除以 16,直到其值在 fraction 可表示的范围内,此处是 50 位二进制,因此其值范围是 0 ~ 0x3FFFFFFFFFFFF。而指数用 6 位存储,底数是 16。计算发现,这种表示方法能够表示的数据范围可以覆盖 uint256 能够表示的范围。
  2. _decodeFloat()则是按照这种浮点表示法还原原始值,只要确保输入是经过_encodeFloat()得到的,就可以保证还原得到的值符合要求。

效率:

  1. 效率也会影响 gas 消耗,在_encodeFloat()编码时循环对目标数据除以 16,直到其值在 fraction 可表示的范围内,根据原始值大小的不同,需要循环的次数也不尽相同,绝大部分值只要少量或者不需要循环就可以完成编码,最大循环次数不会超过 51 次。
  2. _decodeFloat()的实现则更高效,只需要进行 4 次位运算就可以完成还原。

精度:

这种方法采用 50 位存储 fraction,这决定了数据的精度,经过计算可知,这可以达到 15 位 10 进制有效数字的精度,这是一个极高的精度,用于表示价格这样的数据,在通常情况下是完全足够的。

应用:

这种表示方法能够表示超大的数据范围,同时提供极高的精度,具体精度可以通过调整 fraction 占用的位数来按需调整。这是一种通用方法,当目标数据符合此特征时,可以采用此方法表示,从而大大节省存储空间,优化 gas 消耗。

结语:

FORT 合约代码里面有很多类似的技巧,可以看出,开发者在节省 gas 上是煞费苦心,其中很多技巧是通用解决方案,我准备后续继续写一系列的文章来解读这些技巧,另外,为了更好的理解合约,我也会研究合约的结构并记录下来。

参考资料

[1]

jackson: https://learnblockchain.cn/people/245

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 深入浅出区块链技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 发现:
  • 问题:
  • 分析:
  • 效率:
  • 精度:
  • 应用:
  • 结语:
    • 参考资料
    相关产品与服务
    区块链
    云链聚未来,协同无边界。腾讯云区块链作为中国领先的区块链服务平台和技术提供商,致力于构建技术、数据、价值、产业互联互通的区块链基础设施,引领区块链底层技术及行业应用创新,助力传统产业转型升级,推动实体经济与数字经济深度融合。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档