Skip to main content
3 of 3
edited body

Mat,

As far as I understand you don't need "gas price" (whatever that means) to create new EIP1559 transaction.

New dynamic transaction require 3 gas-related params: GasTipCap, GasFeeCap, Gas

tx := types.NewTx(&types.DynamicFeeTx{
    ChainID:   chainID,
    Nonce:     nonce,
    GasTipCap: gasParams.GasTipCap, // <- We need this
    GasFeeCap: gasParams.GasFeeCap, // <- and also this
    Gas:       gasParams.Gas,       // <- and finally this
    To:        to,
    Value:     value,
    Data:      data,
})

I made a function which requests/calculates these 3 params, and this approach works great for me:

Params we need (gathered in one structure for usability and consistency):

type Gas1559Params struct {
    GasTipCap *big.Int // a.k.a. maxPriorityFeePerGas
    GasFeeCap *big.Int // a.k.a. maxFeePerGas
    Gas       uint64
}

And finally function, that returns these three params together:

const GAS_TIP_CAP = 2_000_000_000 // Hardcoded Tip = 2Gwei, make adjustable?

func GetGasParameters(ethClient *ethclient.Client, from common.Address, to *common.Address, value *big.Int, data []byte) (Gas1559Params, error) {
    header, err := ethClient.HeaderByNumber(context.Background(), nil)

    if err != nil {
        return Gas1559Params{}, fmt.Errorf("failed to request last block header: %s", err)
    }

    baseFee := header.BaseFee
    gasTipCap := big.NewInt(GAS_TIP_CAP)              // Calculate the gas tip cap (e.g., 2 Gwei)
    gasFeeCap := new(big.Int).Add(baseFee, gasTipCap) // Calculate the max fee per gas (baseFee + gasTipCap)

    gasLimit, err := estimateGas(ethClient, from, to, value, data)

    if err != nil {
        return Gas1559Params{}, err
    }

    return Gas1559Params{
        GasTipCap: gasTipCap,
        GasFeeCap: gasFeeCap,
        Gas:       gasLimit,
    }, nil
}

func estimateGas(ethClient *ethclient.Client, from common.Address, to *common.Address, value *big.Int, data []byte) (gasLimit uint64, err error) {
    msg := ethereum.CallMsg{
        From:  from,
        To:    to,
        Value: value,
        Data:  data,
    }

    gasLimit, err = ethClient.EstimateGas(context.Background(), msg)

    if err != nil {
        return 0, fmt.Errorf("failed to estimate gas limit for given operation: %s", err)
    }

    return gasLimit, nil
}

I hope this helps :)