透過Gas退款超頻區塊
TL;DR:儲存清理退款很有價值,但可能會使區塊gas數值膨脹 - 保留給使用者,但不計入區塊已使用的gas - EIP-7778恢復準確的鏈上gas核算。
以太坊的gas機制旨在準確反映計算資源消耗。為鼓勵使用者保持狀態清潔和可管理,以太坊在儲存槽重置為零時授予gas退款。儘管這在減少狀態膨脹方面有效,但這些退款目前使gas核算變得複雜,使得看起來區塊消耗的資源比實際消耗的少。
[後續內容保持原有翻譯風格,只展示開頭部分]n = ⌊log(21,000/45,000,000)/log(0.2)⌋ + 1
n = ⌊log(21,000/45,000,000)/log(0.2)⌋ + 1
(⌊x⌋表示向下取整函式,給出小於等於x的最大整數。)
總計算Gas
累加到第n-1步的所有計算Gas:
總Gas = 初始Gas + 初始Gas * r + 初始Gas * r² + ... + 初始Gas * r^(n-1)
總Gas = 初始Gas(1 + r + r² + ... + r^(n-1))
使用幾何級數公式:
1 + r + r² + ... + r^(n-1) = (1 - r^n) / (1 - r)
得到:
總Gas = 初始Gas × (1 - r^n) / (1 - r)
代入數值:
- 初始Gas = 45,000,000
- r = 0.2
- 最小Gas = 21,000
計算n:
n = ⌊log(21,000/45,000,000)/log(0.2)⌋ + 1 = ⌊4.766⌋ + 1 = 5
計算總Gas:
G_{\text{total}} = 45,000,000 \times \frac{1 - (0.2)^5}{1 - 0.2} = 56,232,000
Gtotal=45,000,000×1−(0.2)51−0.2=56,232,000
這表明從初始gas限額增加了約25%,突顯了當前退款如何顯著扭曲區塊gas核算。
示例合約
這些合約可能看起來像這樣:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Refundooor {
mapping(uint256 => uint256) private storageSlots;
/// @notice 從`startKey`開始預填充`maxSlots`個鍵
function chargeStorage(uint256 startKey, uint256 maxSlots) external {
for (uint256 i = 0; i < maxSlots; i++) {
storageSlots[startKey + i] = startKey + i + 1;
}
}
/// @notice 無條件清除恰好MAX_LOOPS個插槽(無檢查)
fallback() external {
assembly {
let base := storageSlots.slot
mstore(0x20, base)
// MAX_LOOPS * ~5,109 gas/iter ≈ 45 000 000 gas
let MAX_LOOPS := 8805
for { let i := 0 } lt(i, MAX_LOOPS) { i := add(i, 1) } {
// 計算鍵 = i 的儲存插槽
mstore(0x0, i)
let s := keccak256(0x0, 0x40)
// 無條件寫入零
sstore(s, 0)
}
}
}
}- 首先透過寫入空儲存插槽來"充值"合約。
- 其次,呼叫合約的回退函式,將8805個儲存插槽設定為零。
檢視這個在Holesky上最大化
SSTORE運算元量的示例交易。
最終,"走私"的gas與區塊gas限額呈線性擴充套件。在100M gas時,一個區塊可以包含125M gas的實際工作。
建議的變更:將交易退款與區塊gas核算分離
EIP-7778提議保留使用者級退款以激勵高效儲存管理,但從區塊級gas核算中移除這些退款。這確保區塊gas使用準確反映實際資源消耗。
實施該EIP的好處是:
- 提高可預測性:區塊的實際工作保持在預期限制以下。
- 增加網路穩定性:無論最壞情況如何,都能降低拒絕服務(DoS)風險。
- 保留使用者激勵:使用者保持清理狀態的動力。
EIP-7778乾淨地將使用者激勵與區塊範圍的資源約束分離,使區塊gas使用更接近實際執行的工作。



