
我們需要位元遮罩操作碼嗎?AAVE V4 核心合約中有 23.3% 的字節碼用於位元遮罩
這篇文章分析了乙太坊字節碼中用於位元遮罩操作的顯著比例,並提出了新的操作碼建議,以優化合約大小與 Gas 效率。
在所有已部署的以太坊字節碼中,位元遮罩(bitmasking)所佔據的比例驚人。WETH9 有 32.9% 是位元遮罩。最近部署的 AAVE V4 Core 則有 23.3% 的字節碼用於位元遮罩。根據 2025 年收集的 zellic 全球唯一以太坊合約字節碼數據集,僅僅是針對 20 位元組地址進行位元遮罩的最簡單模式,就佔了以太坊所有字節碼的 8.16%。加上接下來三種最常見的模式,總計佔所有字節碼的 10.4%。較新版本的 Solidity 編譯器通常會將位元遮罩與其他指令交錯排列,這意味著要準確追蹤位元遮罩需要對每個合約進行靜態分析。然而,我相信這個比例可能落在所有唯一合約字節碼的 12% 到 20% 之間。
AAVE V4 core 字節碼部分的視覺化。位元遮罩操作以紅色標記:
為什麼位元遮罩在 EVM 部署的字節碼中佔比這麼大?這是因為堆疊(stack)具有固定的 256 位元大小,當將小於該大小的類型載入到堆疊時,載入後需要清除高位元。這適用於來自存儲(storage)或記憶體(memory)的緊湊型數據(packed data),以及來自 calldata 的不可信數據。頻繁使用地址的合約(這是大多數合約)以及優化存儲使用的合約(這是大多數知名團隊的合約)都會受到嚴重影響。
USDC 字節碼部分的視覺化。14.7% 為位元遮罩:
位元遮罩的兩種常見方法是智能合約大小與運行時 Gas 消耗之間權衡的兩面。
最節省 Gas 的方法是直接 PUSH 位元遮罩,然後進行 AND 操作。對於布林值(boolean)來說,這沒問題,3 位元組,6 Gas。對於遮罩一個地址,這需要 22 位元組長,儘管仍是 6 Gas。有時對於來自存儲的緊湊數據,會 PUSH 完整的 32 位元組,耗費 34 位元組,6 Gas。
最節省空間(存儲)的方法是通過位移(shifting)一個位元,然後減去 1 來使所有低位元變為 1,以此計算出遮罩。這可以以固定成本產生任何數量的右對齊位元。這種模式看起來像 PUSH1 1, PUSH1 1, PUSH1 160, SHL, SUB, AND。這使得地址(或任何其他右對齊遮罩)長度為 9 位元組,消耗 18 Gas。
如前所述,Solidity 可能會分散這些操作碼,並將它們與其他操作交錯。
早期部署的 Morpho Blue 合約部分視覺化,使用了高 Gas、低空間的位元遮罩,且沒有太多的存儲緊湊化。6.3% 的遮罩位元組:
如果我們想改進這一點,可以做什麼?
-
最簡單(甚至有點滑稽)的做法是添加一個
MASKADDRESS操作碼,保留堆疊最右側的 20 個位元組。這將產生最大的節省,因為地址遮罩既是最常見的遮罩,也是位元組數最大的遮罩之一,這將使其變為 1 位元組,3 Gas。 -
我們可以添加一個採用立即值(immediate values)的
MASKBITS操作碼,類似 EIP-8024 的風格。這將使地址遮罩變為 2 位元組,3 Gas,但也適用於其他大小的右對齊位元組(例如 128 位元數字)。立即值確實增加了處理字節碼的難度,但如果 EIP-8024 已經就緒,這將可以共享代碼。 -
我們可以添加一個從堆疊中獲取值的
MASKBITS操作碼。其最右側的位元組將是要保留的位元組數,第二個位元組將是遮罩的可選左移量。因此,遮罩一個地址將是 PUSH1 160, MASKBITS,3 位元組,6 Gas。遮罩一個左對齊的 uint128 將是 PUSH2 128 160, MASKBITS,4 位元組,6 Gas。這樣做的優點是具有通用性,且字節碼實現和處理起來很乾淨。 -
在不更改 EVM 的情況下,Solidity 編譯器目前使用的緊湊模式可以得到改進,通過使用
MLOAD選擇預設記憶體切片,從 9 位元組、18 Gas 降至 4 位元組、9 Gas。標準的 Solidity 前導碼(preamble)會將空閒空間指針進一步移動,然後添加 ZERO, NOT, PUSH1, MSTORE,在保留的零記憶體插槽後放置一組全為 1 的 256 位元,接著是另外 256 位元的保留記憶體。這將允許僅通過使用 PUSH1, SLOAD, AND 載入正確範圍的記憶體,來選擇任何位元組對齊、左對齊或右對齊的遮罩。
WETH9 全部的視覺化。Solidity 編譯器決定將許多遮罩加倍:
您對這些有什麼看法?這裡大約有 9% 的有效合約大小改進空間,以及更簡潔的字節碼。或者我們應該維持現狀?
1 則貼文 - 1 位參與者
[閱讀完整主題](https://ethereum-magicians.org/t/do-we-need-a-bitmasking-opcode-23-3-of-aave-v4-core-bytecode-is-bitmasking/28323)
相關文章