在区块链领域,Gas(燃料费) 是用来衡量和支付在网络上执行操作(如交易或智能合约)所需计算资源的一种机制。
它是防止网络滥用和资源浪费的关键组成部分,尤其在以太坊(Ethereum)中最为常见。
#
一、Gas的核心概念
术语 |
含义 |
Gas |
执行某个操作所需的“单位计算资源”。 |
Gas Price(Gas价格) |
用户愿意为每单位Gas支付多少“币”(如Gwei)。 |
Gas Limit |
用户愿意为某笔交易最多支付多少Gas(防止无限消耗)。 |
Gas Used |
实际执行中消耗的Gas数量。 |
#
二、对某笔交易进行分析

观察上面该笔交易, 可以发现程序能够决定的值有:
- GasLimit: gas使用量限制
- GasFeeMax: 每gas的价格限制
- MaxPriority: 支付给矿工的费用
这三个数据对应到DynamicFeeTx类型字段分别为:
- GasLimit -> Gas
- GasFeeMax -> GasFeeCap
- MaxPriority -> GasTipCap
#
程序如何决定这三个值的合理值呢?
#
GasLimit
一般转账固定21000,如果是合约调用,则使用EstimateGas估算limit, 下面是使用EstimateGas的示例。
1
2
3
4
5
6
7
8
9
10
|
// 这是以太坊主网的RPC地址
client, _ := ethclient.DialContext(ctx, "https://mainnet.infura.io/v3/b6bf7d3508c941499b10025c0776eaf8")
gasLimit, _ := client.EstimateGas(ctx, ethereum.CallMsg{
From: publicKey,
To: &toAddr,
GasFeeCap: feeCap,
GasTipCap: tipCap,
Value: value,
Data: data,
})
|
#
MaxPriority
矿工费用可以使用SuggestGasTipCap进行动态估算:
1
2
3
|
// 这是以太坊主网的RPC地址
client, _ := ethclient.DialContext(ctx, "https://mainnet.infura.io/v3/b6bf7d3508c941499b10025c0776eaf8")
maxPriority, _ := client.SuggestGasTipCap(ctx)
|
#
GasFeeMax
每gas的单价限制可以使用和MetaMusk(小狐狸)钱包的计算公式:
基础费用 * 1.25 + 矿工费用(gasFeeBase * 1.25) + gasFeeMaxPriority
,
示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
func main() {
// 这是以太坊主网的RPC地址
client, _ := ethclient.DialContext(ctx, "https://mainnet.infura.io/v3/b6bf7d3508c941499b10025c0776eaf8")
// 获取基础费用()
header, _ := client.HeaderByNumber(ctx, nil)
baseFee := header.BaseFee
// 获取tipCap
tipCap, _ := client.SuggestGasTipCap(ctx)
feeCap := FeeCapCalc(baseFee, tipCap)
}
// FeeCapCalc 计算FeeCap
func FeeCapCalc(baseFee, tipCap *big.Int) *big.Int {
multiplier := big.NewFloat(1.25)
feeCapF := new(big.Float).Add(new(big.Float).SetInt(baseFee), multiplier)
feeCapF.Add(feeCapF, new(big.Float).SetInt(tipCap))
feeCap, _ := feeCapF.Int(nil)
return feeCap
}
|
实际交易的时候,gasPrice的值是根据链上实时的基础费用 + 设定的矿工费用来决定,
如果超过了feeCap(基础费用是动态的),交易可能会处于pending状态直到链上base+tip降低到feeCap或以下,
交易才会被成功打包。
#
三、如何理解三方工具的实时GAS价格呢?

使用三方工具查看GAS的实时价格推荐使用gasnow,
不推荐CoinTool的GAS实现查看面板, 最大优先费用不准确.
可以看到上面比较醒目的数字即为基础费用(gasFeeBase), 在通过代码进行转账,
如果要让代码在基础费用过高的情况下停止工作, 则可以使用baseFee来控制, 下面是示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
func main() {
client, _ := ethclient.DialContext(ctx, "https://mainnet.infura.io/v3/b6bf7d3508c941499b10025c0776eaf8")
// 获取baseFee
header, _ := client.HeaderByNumber(ctx, nil)
baseFee := header.BaseFee
if baseFee.Cmp(evmutils.EtherInt64(1)) >= 0 { // 当网络基础费用超过1Gwei时不进行工作
return kerr.WrapTraceStack(
fmt.Errorf("当前网络基础费用过大, 可以换个时间再重试. 基础费用: %s",
baseFee.String(),
),
)
}
// do something...
}
|