Element Gas优化方法

最省Gas的交易合约

一、Element聚合器合约Gas优化

合约代码优化

  1. 对主要市场合约地址进行常量化处理,以减少对合约存储空间的访问。

  2. 减少依赖外部Libray库,减少跨合约调用函数开销

  3. 在核心函数里使用Assembly汇编代码,比Solidity更高效

智能路由算法

  1. 对要购买的NFTs按市场归类,通过智能路由算法,选取最优的智能合约入口函数,每个入口函数都经过了优化,减少循环、条件判断、分支预测等。如:

    • buyOneWithETH

    • batchBuyFromSingleMarketWithETH

    • batchBuyWithETH

    • buyOneWithERC20s

    • batchBuyWithERC20s

  2. 对原生支持批量购买的交易协议,如SeaPort, ElementEx,把单次循环购买单个NFT,合并为一次批量购买NFTs调用。

二、ElementEx Protocol交易协议Gas优化

Element除了支持聚合器,也拥有自己的独立交易协议。ElementEx支持非常多的高级特性,也吸取了主流交易协议如Seaport,0xV4的优点。团队从宏观架构层、到微观代码层做了大量优化工作,ElementEx在所有交易协议里做到了Gas最低。

按照ERC721、ERC1155资产类别拆分合约

ERC721/1155标准不同,交易逻辑也不完全相同,大部分市场都是放在一个交易合约处理。Element Team考虑到98%的主流NFT都是ERC721标准,我们把处理ERC721交易的部分做成独立合约,达到效率最优。 ERC1155也有独立的合约来处理交易。

按照买入、卖出方向拆分入口函数

买入NFT即BuyNow、卖出NFT即AcceptOffer,两者逻辑不同。大部分市场都是在一个入口函数里处理买、卖两个交易行为,这里面存在冗余。 通过大数据分析,80%的成交都是主动买入。以ERC721类型举例,ElementEx把买入做成buyERC721入口,卖出做成sellERC721入口。这样就减少了交易撮合中的冗余判断,减少输入参数。

按照基础、高级特性拆分入口函数

ElementEx合约支持很多高级特性,如ETH/WETH混合支付、合集Offer、实时版税、荷兰拍、英拍、预约上架、批量撤单、指定Taker购买等。 上面两段也讲了90%的用户其实只用最基础的BuyNow,习惯用ETH支付。 所以Element又把买入分成了2个入口函数: buyERC721(基础特性购买入口:逻辑简单,Gas低), buyERC721Ex(带高级特性的购买入口:参数复杂,逻辑复杂,Gas高)。这样既保留了丰富的交易合约特性,又能最大程度节省Gas。

订单结构拆分为买单、卖单

大部分市场的订单只有一种结构Order,里面再根据orderType区分是那种订单。 上面段落讲到了Element买入、卖出已经分成了两个入口,这里我们又把Order拆分了BuyOrder, SellOrder两个类型。像合集Offer这些高级特性的数据,只会出现在SellOrder数据里。 这样在基础订单结构了,既较少了orderType分叉,又保持BuyOrder最精简,带来的好处就是最常见的BuyNow操作,没有浪费Gas。

对订单结构中的字段按位复用

ElementEx虽然支持拍卖、预约上架等高级特性,但是这些特性使用频率不高。所以我们把诸如uint256 expiry按位拆成三个更细粒度的字段,只占用一个EMV存储一个256位插槽空间。

订单状态按位存储

为了防止订单被重复执行,大部分市场都会把成交/撤销的订单,通过keccak生成256位的nonce,再写入到EVM存储区的Mapping插槽中。 在这里ElementEx引入了0xProtocol V4的做法,把256位中的前248位作为Bucket存储状态,后8位作为偏移量。从而实现不必每笔订单状态都写入一个全新的256位插槽,而是复用插槽,直到每完成256笔订单才启用一个新插槽。

from 0x v4 document

合约代码优化

对核心路径的代码改为用Assembly汇编实现,

Last updated