最新24小時的base Fee可以在飛狐瀏覽器檢視(https://filfox.info/zh):
2. GasLimit
Gas Limit是指一個交易,願意為交易執行支付的“油量”。一個交易消耗的Gas Limit幾乎是固定的,計算過程請檢視GasEstimateGasLimit函式。簡單的說,當一個交易需要獲取Gas Limit時,在目前區塊高度上,“執行”該交易:
res, err := a.Stmgr.CallWithGas(ctx, &msg, priorMsgs, ts)
CallWithGas,只是為了獲取執行過程消耗的Gas,並不真正改變當前的狀態。
3. GasPremium
Gas Premium是指一個交易,願意為交易執行支付的“油價”。GAS費用是油量乘以油價的結果。油量和交易本身有關,也幾乎是固定的。顯然的是,油價高,GAS費用高,礦工的收入就高,更願意將交易優先打包。從交易傳送者的角度,油價越低越好。Lotus程式碼給出一個計算Gas Premium的方法,請檢視GasEstimateGasPremium函式,分為幾步:
· 檢視之前區塊(4個 = 2*2)中所有交易,並按照Gas Premium從高到低排序
· 計算所有交易的“平均”Gas Premium。平均的意思是,找出一半油量消耗的Gas Premium:
at := build.BlockGasTarget * int64(blocks) / 2
prev1, prev2 := big.Zero(), big.Zero()
for _, price := range prices {
prev1, prev2 = price.price, prev1
at -= price.limit
if at > 0 {
continue
}
}
· 加上千分之五的隨機性
// mean 1, stddev 0.005 => 95% within +-1%
noise := 1 + rand.NormFloat64()*0.005
premium = types.BigMul(premium, types.NewInt(uint64(noise*(1<<precision))+1))
premium = types.BigDiv(premium, types.NewInt(1<<precision))
4. GasFeeCap
除了Gas Premium,交易還需要支付Base Fee。也就是說,一般情況下,交易需要支付的費用是: (Gas Premium + Base Fee) * Gas Limit。問題是,Base Fee是變化的,有可能太大,交易傳送者,不願意支付。Gas Fee Cap(上限),就是設定支付費用的上限。相關的計算邏輯請看GasEstimateFeeCap函式。
· 交易非常可能不是下一個區塊立即被打包,那需要考慮在接下來的多個區塊(10個)才被打包的情況下,Base Fee的變化:
parentBaseFee := ts.Blocks()[0].ParentBaseFee
increaseFactor := math.Pow(1.+1./float64(build.BaseFeeMaxChangeDenom), float64(maxqueueblks))
feeInFuture := types.BigMul(parentBaseFee, types.NewInt(uint64(increaseFactor*(1<<8))))
feeInFuture = types.BigDiv(feeInFuture, types.NewInt(1<<8))
每個區塊Base Fee按照12.5%的漲幅計算。
· 當前賬戶餘額的百分之一,作為支付費用的上限:
maxAccepted := types.BigDiv(act.Balance, types.NewInt(MaxSpendOnFeeDenom))
· 上述兩種情況下的最少值,作為Gas Fee Cap
5. GasLimit設定懲罰
眾所周知,以太坊中的Gas Limit可以設定的非常大。一般情況下,多餘的Gas費用會全數返還。特別注意的是,Filecoin並不完全是這樣。因為Gas Limit參與了Base Fee和Gas Premium的計算,真實的Gas Limit是非常重要的。如果一個交易,設定了不合理的Gas Limit,Filecoin採取了一種懲罰機制。懲罰的Gas費用也被燃燒,計算邏輯看ComputeGasOverestimationBurn函式。
· 允許一定的誤差情況下,計算Gas limit的超出部分
const (
gasOveruseNum = 11
gasOveruseDenom = 10
)
over := gasLimit - (gasOveruseNum*gasUsed)/gasOveruseDenom
Gas消耗的1.1倍以內認為是合理設定。
if over > gasUsed {
over = gasUsed
}
超出部分的上限是Gas的使用量。
· 按照超出(over)的比例,確定懲罰的油量:
gasToBurn := big.NewInt(gasLimit - gasUsed)
gasToBurn = big.Mul(gasToBurn, big.NewInt(over))
gasToBurn = big.Div(gasToBurn, big.NewInt(gasUsed))
簡單的說,懲罰的是over/gasUsed的比例。如果over超過了gasUsed,就是所有罰光。
總結:
Filecoin的Gas模型,引入了BaseFee,用來調節交易的擁堵情況。BaseFee,在區塊擁堵或者區塊交易不夠的情況下,都會按照12.5%進行相應的調節。每筆交易的費用計算公式:(Gas Premium + Base Fee) * Gas Limit。其中BaseFee的部分會被燃燒掉,Gas Premium作為礦工的手續費。特別注意的是,GasLimit不要隨意設定,多餘的Gas Limit會被燃燒。