0g-chain/precompiles/common/common.go
2024-12-31 23:21:43 +08:00

63 lines
1.6 KiB
Go

package common
import (
"errors"
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/core/vm"
"github.com/evmos/ethermint/x/evm/statedb"
)
type PrecompileCommon interface {
Abi() *abi.ABI
IsTx(string) bool
KVGasConfig() storetypes.GasConfig
}
func InitializePrecompileCall(
p PrecompileCommon,
evm *vm.EVM,
contract *vm.Contract,
readonly bool,
) (
ctx sdk.Context,
stateDB *statedb.StateDB,
method *abi.Method,
initialGas storetypes.Gas,
args []interface{},
err error,
) {
// parse input
if len(contract.Input) < 4 {
return sdk.Context{}, nil, nil, uint64(0), nil, vm.ErrExecutionReverted
}
method, err = p.Abi().MethodById(contract.Input[:4])
if err != nil {
return sdk.Context{}, nil, nil, uint64(0), nil, vm.ErrExecutionReverted
}
args, err = method.Inputs.Unpack(contract.Input[4:])
if err != nil {
return sdk.Context{}, nil, nil, uint64(0), nil, err
}
// readonly check
if readonly && p.IsTx(method.Name) {
return sdk.Context{}, nil, nil, uint64(0), nil, errors.New(ErrWriteOnReadOnly)
}
// get state db and context
stateDB, ok := evm.StateDB.(*statedb.StateDB)
if !ok {
return sdk.Context{}, nil, nil, uint64(0), nil, errors.New(ErrGetStateDB)
}
ctx, err = stateDB.GetCachedContextForPrecompile()
if err != nil {
return sdk.Context{}, nil, nil, uint64(0), nil, err
}
// initial gas
initialGas = ctx.GasMeter().GasConsumed()
ctx = ctx.WithKVGasConfig(p.KVGasConfig())
return ctx, stateDB, method, initialGas, args, nil
}