You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

go-ethereum SimulatedBackend报max fee per gas低于block base fee错误如何解决

问题根因

  • 报错确实和以太坊伦敦升级引入的EIP1559机制相关:新版本的go-ethereum SimulatedBackend默认启用了base fee规则,所有交易的maxFeePerGas必须大于等于当前区块的base fee才能被打包。
  • 你设置auth.GasFeeCap不生效的核心原因是:你没有使用auth对象构造交易,而是手动调用types.NewTransaction创建了legacy类型的交易,auth的配置完全没有被用到。
  • 当前你构造的legacy交易中,gasPrice仅为1 wei,远低于区块的base fee(875000000 wei),所以触发panic。

修复方案

这里给出两种可正常运行的实现方式:

方式1:直接使用TransactOpts发送交易(更简便)

不用手动构造交易,直接用bind包的TransactOpts相关逻辑,配置会自动生效:

package eth

import (
	"context"
	"math/big"
	"testing"

	"github.com/ethereum/go-ethereum/accounts/abi/bind"
	"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/crypto"
)

func TestSimulatedBackend(t *testing.T) {
	privateKey, err := crypto.GenerateKey()
	if err != nil {
		t.Fatalf("failed to generate key: %v", err)
	}

	auth, err := bind.NewKeyedTransactorWithChainID(privateKey, big.NewInt(1337))
	if err != nil {
		t.Fatalf("failed to generate transactor: %v", err)
	}
	// 这里配置的GasFeeCap才会生效
	auth.GasFeeCap = big.NewInt(1000000000) // 1gwei,高于base fee即可
	auth.GasTipCap = big.NewInt(1000000000)
	auth.GasLimit = 21000

	balance := new(big.Int)
	balance.SetString("10000000000000000000", 10) // 10 eth in wei

	address := auth.From
	genesisAlloc := map[common.Address]core.GenesisAccount{
		address: {
			Balance: balance,
		},
	}

	blockGasLimit := uint64(4712388)
	client := backends.NewSimulatedBackend(genesisAlloc, blockGasLimit)

	toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
	// 直接用TransactOpts构造转账交易
	tx, err := bind.SendEther(auth, client, toAddress, big.NewInt(1000000000000000000), nil)
	if err != nil {
		t.Fatalf("failed to send transaction: %v", err)
	}

	t.Logf("tx sent: %s\n", tx.Hash().Hex())

	client.Commit()

	receipt, err := client.TransactionReceipt(context.Background(), tx.Hash())
	if err != nil {
		t.Fatalf("failed to get transaction receipt: %v", err)
	}
	if receipt == nil {
		t.Fatal("receipt is empty")
	}

	t.Logf("status: %v\n", receipt.Status) // status: 1
}

方式2:手动构造EIP1559类型交易

如果你需要手动构造交易,改用DynamicFeeTx类型即可,只需要替换原有交易构造部分的代码:

nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
if err != nil {
	t.Fatalf("failed to get nonce: %v", err)
}

value := big.NewInt(1000000000000000000) // 1 eth
gasLimit := uint64(21000)
toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
// 构造EIP1559交易参数
tx := types.NewTx(&types.DynamicFeeTx{
	ChainID:   big.NewInt(1337),
	Nonce:     nonce,
	GasTipCap: big.NewInt(1000000000), // 优先级费
	GasFeeCap: big.NewInt(1000000000), // 最高付费,高于base fee即可
	Gas:       gasLimit,
	To:        &toAddress,
	Value:     value,
	Data:      nil,
})
// 签名使用LondonSigner即可
signedTx, err := types.SignTx(tx, types.NewLondonSigner(big.NewInt(1337)), privateKey)
if err != nil {
	t.Fatalf("failed to sign transaction: %v", err)
}

内容的提问来源于stack exchange,提问作者Arjan van Eersel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 21:15:01