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 項目最新進展!