Eip-1559
如何計算新區塊的“每 Gas 基本費用”?
有很多文章描述了在 EIP1559 之後的塊
baseFeePerGas
是基於之前的塊baseFeePerGas
,gasUsed
並且gasLimit
它可以在每個塊之間變化最大 ±12.5%。但是計算下一個塊的確切公式是什麼
baseFeePerGas
?例如:如何baseFeePerGas
計算塊 13031168 的?Block 13031167: Gas Used: 23798810 (79.10%) +58% Gas Target Gas Limit: 30087944 Base Fee Per Gas: 47.209136185 Gwei Block 13031168: Gas Used: 892841 (2.96%) -94% Gas Target Gas Limit: 30117325 Base Fee Per Gas: 50.643305194 Gwei
您可以在 EIP 1559 規範中找到確切的公式:
https://eips.ethereum.org/EIPS/eip-1559
# check if the base fee is correct if INITIAL_FORK_BLOCK_NUMBER == block.number: expected_base_fee_per_gas = INITIAL_BASE_FEE elif parent_gas_used == parent_gas_target: expected_base_fee_per_gas = parent_base_fee_per_gas elif parent_gas_used > parent_gas_target: gas_used_delta = parent_gas_used - parent_gas_target base_fee_per_gas_delta = max(parent_base_fee_per_gas * gas_used_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR, 1) expected_base_fee_per_gas = parent_base_fee_per_gas + base_fee_per_gas_delta else: gas_used_delta = parent_gas_target - parent_gas_used base_fee_per_gas_delta = parent_base_fee_per_gas * gas_used_delta // parent_gas_target // BASE_FEE_MAX_CHANGE_DENOMINATOR expected_base_fee_per_gas = parent_base_fee_per_gas - base_fee_per_gas_delta assert expected_base_fee_per_gas == block.base_fee_per_gas, 'invalid block: base fee not correct'
或者在官方來源:
// CalcBaseFee calculates the basefee of the header. 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) } var ( parentGasTarget = parent.GasLimit / params.ElasticityMultiplier parentGasTargetBig = new(big.Int).SetUint64(parentGasTarget) baseFeeChangeDenominator = new(big.Int).SetUint64(params.BaseFeeChangeDenominator) ) // 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) } if parent.GasUsed > parentGasTarget { // If the parent block used more gas than its target, the baseFee should increase. gasUsedDelta := new(big.Int).SetUint64(parent.GasUsed - parentGasTarget) x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta) y := x.Div(x, parentGasTargetBig) baseFeeDelta := math.BigMax( x.Div(y, baseFeeChangeDenominator), common.Big1, ) return x.Add(parent.BaseFee, baseFeeDelta) } else { // Otherwise if the parent block used less gas than its target, the baseFee should decrease. gasUsedDelta := new(big.Int).SetUint64(parentGasTarget - parent.GasUsed) x := new(big.Int).Mul(parent.BaseFee, gasUsedDelta) y := x.Div(x, parentGasTargetBig) baseFeeDelta := x.Div(y, baseFeeChangeDenominator) return math.BigMax( x.Sub(parent.BaseFee, baseFeeDelta), common.Big0, ) } }