GasGasGasGasGas
GasGasPriceGas * GasPrice
GasLimitGas

现有一笔如下所示的交易:

Gas
Gas Limit & Usage by TxnGasLimitGasGasLimitGas FeesBaseGasPriceMaxGasPriceMax PriorityGasPriceBurnt & Txn Savings FeesBurntTxn Savings
Txn Type: 2(EIP-1559)EIP-2718EIP-1559

BaseFee

BaseFeeEIP-1559BaseFee
BaseFee
func CalcBaseFee(config *params.ChainConfig, parent *types.Header) *big.Int {
    // If the current block is the first EIP-1559 block, return the InitialBaseFee.
    if !config.IsLondon(parent.Number) {
        return new(big.Int).SetUint64(params.InitialBaseFee)
    }

    parentGasTarget := parent.GasLimit / config.ElasticityMultiplier()
    // If the parent gasUsed is the same as the target, the baseFee remains unchanged.
    if parent.GasUsed == parentGasTarget {
        return new(big.Int).Set(parent.BaseFee)
    }

    var (
        num   = new(big.Int)
        denom = new(big.Int)
    )

    if parent.GasUsed > parentGasTarget {
        // If the parent block used more gas than its target, the baseFee should increase.
        // max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
        num.SetUint64(parent.GasUsed - parentGasTarget)
        num.Mul(num, parent.BaseFee)
        num.Div(num, denom.SetUint64(parentGasTarget))
        num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
        baseFeeDelta := math.BigMax(num, common.Big1)

        return num.Add(parent.BaseFee, baseFeeDelta)
    } else {
        // Otherwise if the parent block used less gas than its target, the baseFee should decrease.
        // max(0, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
        num.SetUint64(parentGasTarget - parent.GasUsed)
        num.Mul(num, parent.BaseFee)
        num.Div(num, denom.SetUint64(parentGasTarget))
        num.Div(num, denom.SetUint64(config.BaseFeeChangeDenominator()))
        baseFee := num.Sub(parent.BaseFee, num)

        return math.BigMax(baseFee, common.Big0)
    }
}
BaseFee
EIP-1559InitialBaseFee1 GweiparentGasTargetGasLimitGasUsedparentGasTargetBaseFeeGasUsedparentGasTargetBaseFee

parentBaseFee + max(1, parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)
GasUsedparentGasTargetBaseFee

max(0, parentBaseFee - parentBaseFee * gasUsedDelta / parentGasTarget / baseFeeChangeDenominator)

其中:

GasUsedGasparentBaseFeeBaseFeegasUsedDeltaparent.GasUsed - parentGasTargetGasparentGasTargetGasLimitBaseFeeChangeDenominator
etherscan

在 18247918 区块中,可以知道

BaseFeegasUsedDelta / parentGasTargetBaseFee
BaseFee

$$ \mathrm{BaseFee = max(0, 6.79 - 6.79 * 0.24 / 8) = 6.5863} $$

与图示一致

MaxPriorityFee

MaxPriorityFeeGasGas
GasPriceBaseFeeMaxPriorityFee

对于交易:

$$ \begin{aligned} \tt{Transaction\ Fee} & = \tt{GasUsed GasPrice} \ &= \tt{GasUsed (BaseFee + MaxPriorityFee)} \ &= 115855 * (7.407585749 + 0.05) \ & = 863998.597\tt{Gwei} \end{aligned} $$

Transaction Fee

MaxFee

MaxFeeGasPrice
BaseFeeMaxPriorityFeeBaseFeeMaxFeeBaseFee
BaseFeeMaxPriorityFeeMaxFeeBaseFeeMaxPriorityFeeMaxFeeBaseFee + MaxPriorityFee
MaxFee

$$ \tt{Max Fee = (2 * BaseFee) + MaxPriorityFee} $$

Gas

Burnt

BaseFee

$$ \mathtt{Burnt = BaseFee * GasUsed} $$

以上图中交易为例计算

$$ \begin{aligned} \tt{Burnt} & = \tt{BaseFee GasUsed} \ & = 7.407585749 115855 \ &= 858205.846950395 \ \tt{Gwei} \end{aligned} $$

Burnt

Txn Savings

交易节省的费用,等于最大可接受交易费用减去实际消耗的交易费用

$$ \tt{Tx Savings Fees = MaxFee GasUsed - (BaseFee + MaxPriorityFee) GasUsed} $$

以上图中交易为例计算

$$ \begin{aligned} \tt{Tx Savings Fees} & = \tt{MaxFee GasUsed - (BaseFee + MaxPriorityFee) GasUsed} \ & = 7.657591636 * 115855 - 863998.597 \ & = 23171.68198878 \tt{Gwei} \ \end{aligned} $$

Txn Savings

JSON-RPC

GashttpJSON-RPC
eth_estimateGaseth_maxPriorityFeePerGaseth_getBlockByNumber

eth_estimateGas

GasGasLimit
// Request Payload
{
  "jsonrpc": "2.0",
  "method": "eth_estimateGas",
  "params": [
    {
      "from": "0xD28C383dd3a1C0154129F67067175884e933cf4e",
      "to": "0x7071D6EF9FaF45aA48c22bae7d4a295aD68DC038",
      "value": "0x186a0"
    }
  ],
  "id": 1
}
// Response
{
  "id":1,
  "jsonrpc": "2.0",
  "result": "0x5208" // 21000
}

eth_maxPriorityFeePerGas

MaxPriorityFee
// Request Payload
{
  "jsonrpc": "2.0",
  "method": "eth_maxPriorityFeePerGas",
  "params": [],
  "id": 1
}
// Response
{
  "jsonrpc": "2.0",
  "result": "0x9b8495", // MaxPriorityFee
  "id": 1
}

eth_getBlockByNumber

BaseFee
// Request Payload
{
  "jsonrpc": "2.0",
  "method": "eth_getBlockByNumber",
  "params": [
    "latest",
    false
  ],
  "id": 1
}
// Response
{
  "jsonrpc": "2.0",
  "result": {
    "baseFeePerGas": "0x1bc47470a", // baseFee
    "difficulty": "0x0",
    "extraData": "0x546974616e2028746974616e6275696c6465722e78797a29",
    "gasLimit": "0x1c9c380",
    "gasUsed": "0xced6fd",
    "hash": "0xbb9b314d0b8208e655a0afc17384f56f44659a63e3ba4e244609105da497a7d9",
    ...
  },
  "id": 1
}
baseFeePerGasBaseFeeMaxPriorityFeeMaxFee
Max Fee = (2 * BaseFee) + MaxPriorityFee