### Query Base Fee Example Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md An example of how to execute the base-fee query command. ```bash ethermintd query feemarket base-fee ... ``` -------------------------------- ### Query Block Gas Example Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md An example of how to execute the block-gas query command. ```bash ethermintd query feemarket block-gas ... ``` -------------------------------- ### Install Nix (No Daemon) Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/README.md Installs Nix on Linux without using the daemon. This is an alternative installation method for Linux systems. ```shell sh <(curl -L https://nixos.org/nix/install) --no-daemon ``` -------------------------------- ### Query Module Params Example Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md An example of querying the 'ElasticityMultiplier' parameter within the 'feemarket' subspace. ```bash ethermintd query params subspace feemarket ElasticityMultiplier ... ``` -------------------------------- ### Install Nix (Multi-user) Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/README.md Installs Nix using the multi-user mode. Ensure to source the Nix profile in your shell profile after installation. ```shell sh <(curl -L https://nixos.org/nix/install) --daemon ``` -------------------------------- ### Start Local Hardhat Node Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/hardhat/README.md Start a local blockchain node for development and testing. ```shell npx hardhat node ``` -------------------------------- ### Table Driven Test Example Source: https://github.com/evmos/ethermint/blob/main/CONTRIBUTING.md Illustrates the format for table-driven tests, emphasizing clear error messages for debugging. This example shows how to structure test cases and loop through them, providing specific indices for failures. ```go for tcIndex, tc := range cases { for i := 0; i < tc.numTxsToTest; i++ { require.Equal(t, expectedTx[:32], calculatedTx[:32], "First 32 bytes of the txs differed. tc #%d, i #%d", tcIndex, i) ``` -------------------------------- ### Run Integration Tests (First Time) Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/README.md Executes the integration tests for the first time. This command may take a significant amount of time due to initial setup and downloads. ```shell make run-integration-tests ``` -------------------------------- ### Install Cachix and Use Ethermint Cache Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/README.md Installs the Cachix binary and configures it to use the Ethermint binary cache. This speeds up test execution by leveraging pre-built binaries. ```shell nix-env -iA cachix -f https://cachix.org/api/v1/install cachix use ethermint ``` -------------------------------- ### Module Params Query Output Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md Example output format for querying module parameters, showing subspace, key, and value. ```text key: ElasticityMultiplier subspace: feemarket value: "2" ``` -------------------------------- ### Base Fee Query Output Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md Example output format for the base fee query, showing the calculated base fee. ```text base_fee: "512908936" ``` -------------------------------- ### JSON-RPC eth_call Example Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/01_concepts.md Demonstrates how the eth_call JSON-RPC method is used to execute messages against contracts without committing a transaction. It outlines the internal steps in both Geth and Ethermint implementations. ```go package main import ( "context" "encoding/json" "github.com/cosmos/cosmos-sdk/types/query" "github.com/evmos/ethermint/x/evm/types" ) func main() { // Example usage of EthCall // This is a simplified example and requires a running Evmos node and client setup. // Assume 'ctx' is a valid context.Context and 'client' is an initialized EVM gRPC query client. // var ctx context.Context // var client types.QueryClient // Example parameters for eth_call request := &types.EthCallRequest{ Args: []byte("0x..."), // Replace with actual call data Gas: 100000, GasPrice: "1000000000", // Example gas price in Wei From: "0x...", // Replace with sender address To: &[]byte{}, // Replace with contract address or nil for contract creation Value: "0", // Value to send with the call Data: []byte("0x..."), // Method signature and arguments } // Make the gRPC call to EthCall // resp, err := client.EthCall(ctx, request) // if err != nil { // // Handle error // return // } // Process the response // fmt.Printf("EthCall Response: %s\n", resp.Ret) // Example of how to use pagination for EthCall (if applicable for other methods) // pageReq := &query.PageRequest{ // Key: nil, // Offset: 0, // Limit: 10, // CountTotal: true, // } // _, err = client.EthCall(ctx, request, grpc.WithDefaultCallOptions(grpc.CallContentSubtype("proto"))) // Example with pagination, adjust as needed // Example of marshaling the request for JSON-RPC (not directly used in gRPC client) // jsonReq, _ := json.Marshal(request) // fmt.Println(string(jsonReq)) } // Note: This is a conceptual example. Actual implementation requires setting up the gRPC client and context. ``` -------------------------------- ### Get Storage Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Retrieves all coin balances for a single account, including storage details. ```APIDOC ## GET /ethermint/evm/v1/storage/{address}/{key} ### Description Get the balance of all coins for a single account. ### Method GET ### Endpoint /ethermint/evm/v1/storage/{address}/{key} ### Parameters #### Path Parameters - **address** (string) - Required - The account address. - **key** (string) - Required - The storage key. ``` -------------------------------- ### Registering EVM Hook in App.go Source: https://github.com/evmos/ethermint/blob/main/docs/architecture/adr-002-evm-hooks.md Demonstrates how to register the custom `BankSendHook` with the `EvmKeeper` in the application's main setup file (`app.go`). ```go evmKeeper.SetHooks(NewBankSendHook(bankKeeper)); ``` -------------------------------- ### Block Gas Query Output Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md Example output format for the block gas query, showing the gas used. ```text gas: "21000" ``` -------------------------------- ### Get EVM Module Parameters Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Retrieves the current parameters of the x/evm module. ```APIDOC ## GET /ethermint/evm/v1/params ### Description Get the parameters of x/evm module. ### Method GET ### Endpoint /ethermint/evm/v1/params ``` -------------------------------- ### Get Code Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Retrieves the code associated with an account address. ```APIDOC ## GET /ethermint/evm/v1/codes/{address} ### Description Get the balance of all coins for a single account. ### Method GET ### Endpoint /ethermint/evm/v1/codes/{address} ### Parameters #### Path Parameters - **address** (string) - Required - The account address. ``` -------------------------------- ### Run Deployment Script Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/hardhat/README.md Execute a script to deploy your smart contracts to the network. ```shell npx hardhat run scripts/deploy.js ``` -------------------------------- ### Query Feemarket Module Help Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md Displays help information for all feemarket module query commands. ```bash ethermintd query feemarket --help ``` -------------------------------- ### Display Help Information Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/hardhat/README.md Run this command to display available Hardhat tasks and their descriptions. ```shell npx hardhat help ``` -------------------------------- ### HTTP GET Params Endpoint Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md The HTTP GET endpoint to retrieve the feemarket module's parameters. ```http /feemarket/evm/v1/params ``` -------------------------------- ### HTTP GET BlockGas Endpoint Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md The HTTP GET endpoint to retrieve the gas used within the current block. ```http /feemarket/evm/v1/block_gas ``` -------------------------------- ### HTTP GET BaseFee Endpoint Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md The HTTP GET endpoint to retrieve the current block's base fee. ```http /feemarket/evm/v1/base_fee ``` -------------------------------- ### NewEVM Function for EVM Initialization Source: https://github.com/evmos/ethermint/blob/main/docs/architecture/adr-001-state.md Creates a new Ethereum Virtual Machine (EVM) instance with the provided message and chain configuration. Sets up block and transaction contexts. ```go func (k *Keeper) NewEVM(msg core.Message, config *params.ChainConfig) *vm.EVM { blockCtx := vm.BlockContext{ CanTransfer: core.CanTransfer, Transfer: core.Transfer, GetHash: k.GetHashFn(), Coinbase: common.Address{}, // there's no beneficiary since we're not mining GasLimit: gasLimit, BlockNumber: blockHeight, Time: blockTime, Difficulty: 0, // unused. Only required in PoW context } txCtx := core.NewEVMTxContext(msg) vmConfig := k.VMConfig() return vm.NewEVM(blockCtx, txCtx, k, config, vmConfig) } ``` -------------------------------- ### Get Ethereum Account Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Retrieves an Ethereum account using its address. ```APIDOC ## GET /ethermint/evm/v1/account/{address} ### Description Get an Ethereum account. ### Method GET ### Endpoint /ethermint/evm/v1/account/{address} ### Parameters #### Path Parameters - **address** (string) - Required - The address of the Ethereum account. ``` -------------------------------- ### Initialize Test Node Source: https://github.com/evmos/ethermint/blob/main/tests/solidity/README.md This script initializes the Ethermint test node, making specific Ethereum accounts available for testing. ```sh ./init-test-node.sh ``` -------------------------------- ### Get EVM Balance Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Retrieves the balance of the EVM denomination for a specific Ethereum account. ```APIDOC ## GET /ethermint/evm/v1/balances/{address} ### Description Get the balance of a the EVM denomination for a single EthAccount. ### Method GET ### Endpoint /ethermint/evm/v1/balances/{address} ### Parameters #### Path Parameters - **address** (string) - Required - The Ethereum account address. ``` -------------------------------- ### Get Cosmos Account Address Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Retrieves the Cosmos Address associated with an Ethereum account. ```APIDOC ## GET /ethermint/evm/v1/cosmos_account/{address} ### Description Get an Ethereum account's Cosmos Address. ### Method GET ### Endpoint /ethermint/evm/v1/cosmos_account/{address} ### Parameters #### Path Parameters - **address** (string) - Required - The Ethereum account address. ``` -------------------------------- ### Run Contract Tests Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/hardhat/README.md Execute the test suite for your smart contracts. ```shell npx hardhat test ``` -------------------------------- ### Get Validator Account Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Retrieves an Ethereum account's details from a validator's consensus address. ```APIDOC ## GET /ethermint/evm/v1/validator_account/{cons_address} ### Description Get an Ethereum account's from a validator consensus Address. ### Method GET ### Endpoint /ethermint/evm/v1/validator_account/{cons_address} ### Parameters #### Path Parameters - **cons_address** (string) - Required - The validator's consensus address. ``` -------------------------------- ### Enter Nix Shell and Run Tests Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/README.md Enters the Nix shell environment for integration tests and then runs the tests using pytest. This is the command to use after the initial test run. ```shell nix-shell tests/integration_tests/shell.nix cd tests/integration_tests pytest -s -vv ``` -------------------------------- ### Get Ethereum Accounts Source: https://github.com/evmos/ethermint/blob/main/tests/solidity/README.md Retrieves a list of unlocked Ethereum accounts available via the JSON-RPC API. ```sh curl localhost:8545 -H "Content-Type:application/json" -X POST --data '{"jsonrpc":"2.0","method":"eth_accounts","params":[],"id":1}' ``` -------------------------------- ### Run Tests with Gas Report Source: https://github.com/evmos/ethermint/blob/main/tests/integration_tests/hardhat/README.md Run contract tests and generate a gas usage report. ```shell GAS_REPORT=true npx hardhat test ``` -------------------------------- ### EVM State Transition with Hooks Source: https://github.com/evmos/ethermint/blob/main/docs/architecture/adr-002-evm-hooks.md Illustrates the modification to the EVM state transition method 'ApplyTransaction' to incorporate the EvmHooks. It includes snapshotting, applying the message, and conditionally calling the PostTxProcessing hook, with logic to revert the transaction if the hook returns an error. ```go // Need to create a snapshot explicitly to cover both tx processing and post processing logic var revision int if k.hooks != nil { revision = k.Snapshot() } res, err := k.ApplyMessage(evm, msg, ethCfg, false) if err != nil { return err } ... if !res.Failed() { // Only call hooks if tx executed successfully. err = k.hooks.PostTxProcessing(k.ctx, txHash, logs) if err != nil { // If hooks return error, revert the whole tx. k.RevertToSnapshot(revision) res.VmError = "failed to process native logs" res.Ret = []byte(err.Error()) } } ``` -------------------------------- ### Query Base Fee Command Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md Shows the command structure for querying the block base fee. Use '...' for flags. ```bash ethermintd query feemarket base-fee [flags] ``` -------------------------------- ### Configure VSCode for Protobuf Path Source: https://github.com/evmos/ethermint/blob/main/CONTRIBUTING.md Set the protobuf path in VSCode's settings.json to ensure proper import compilation within your IDE. ```json { "protoc": { "options": [ "--proto_path=${workspaceRoot}/proto", "--proto_path=${workspaceRoot}/third_party/proto" ] } } ``` -------------------------------- ### Query Module Params Command Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md Shows the command structure for querying module parameters using subspace and key. Use '...' for flags. ```bash ethermintd query params subspace [subspace] [key] [flags] ``` -------------------------------- ### Query EVM Storage by Key and Height via CLI Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md This command allows querying the storage value associated with a specific key for an account at a given block height. The key and address must be valid. ```bash ethermintd query evm storage ADDRESS KEY [flags] ``` ```bash # Example $ ethermintd query evm storage 0x0f54f47bf9b8e317b214ccd6a7c3e38b893cd7f0 0 --height 0 # Output value: "0x0000000000000000000000000000000000000000000000000000000000000000" ``` -------------------------------- ### Feemarket CLI Queries Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md Users can query the feemarket module's state using various CLI commands. These commands allow retrieval of the current base fee, block gas usage, and module parameters. ```APIDOC ## CLI Queries ### Base Fee Query the base fee for the current block. #### Method CLI #### Endpoint ethermintd query feemarket base-fee [flags] ### Block Gas Query the gas used for the current block. #### Method CLI #### Endpoint ethermintd query feemarket block-gas [flags] ### Params Query the module parameters. #### Method CLI #### Endpoint ethermintd query params subspace feemarket [key] [flags] ### Example Output **Base Fee:** ```json { "base_fee": "512908936" } ``` **Block Gas:** ```json { "gas": "21000" } ``` **Params:** ```json { "key": "ElasticityMultiplier", "subspace": "feemarket", "value": "2" } ``` ``` -------------------------------- ### Submit Raw EVM Transaction via CLI Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Use this command to build and submit a Cosmos transaction from a raw Ethereum transaction hex string. Ensure the TX_HEX is valid. ```bash ethermintd tx evm raw TX_HEX [flags] ``` ```bash # Example $ ethermintd tx evm raw 0xf9ff74c86aefeb5f6019d77280bbb44fb695b4d45cfe97e6eed7acd62905f4a85034d5c68ed25a2e7a8eeb9baf1b84 # Output value: "0x0000000000000000000000000000000000000000000000000000000000000000" ``` -------------------------------- ### gRPC Query Params Method Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md The gRPC method to retrieve the feemarket module's parameters. ```protobuf ethermint.feemarket.v1.Query/Params ``` -------------------------------- ### Query Params Source: https://github.com/evmos/ethermint/blob/main/docs/api/proto-docs.md Retrieves the parameters for the x/feemarket module. This includes configuration details for the feemarket module. ```APIDOC ## GET /ethermint/feemarket/v1/params ### Description Params queries the parameters of x/feemarket module. ### Method GET ### Endpoint /ethermint/feemarket/v1/params ### Parameters #### Query Parameters None ### Request Example None ### Response #### Success Response (200) - **params** (ethermint.feemarket.v1.Params) - params define the evm module parameters. #### Response Example ```json { "params": { "params": "..." } } ``` ``` -------------------------------- ### Query EVM Smart Contract Code via CLI Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/09_client.md Use this command to retrieve the bytecode of a smart contract deployed at a specific address. Ensure the address is correctly formatted. ```bash ethermintd query evm code ADDRESS [flags] ``` ```bash # Example $ ethermintd query evm code 0x7bf7b17da59880d9bcca24915679668db75f9397 # Output code: "0xef616c92f3cfc9e92dc270d6acff9cea213cecc7020a76ee4395af09bdceb4837a1ebdb5735e11e7d3adb6104e0c3ac55180b4ddf5e54d022cc5e8837f6a4f971b" ``` -------------------------------- ### Go Hook Implementation for Handling BankSend Event Source: https://github.com/evmos/ethermint/blob/main/docs/architecture/adr-002-evm-hooks.md Implements a `BankSendHook` in Go that listens for the `__CosmosNativeBankSend` log emitted by smart contracts. It decodes the log data and uses the bank keeper to perform the native token transfer. Includes contract whitelisting for security. ```go var ( // BankSendEvent represent the signature of // `event __CosmosNativeBankSend(address recipient, uint256 amount, string denom)` BankSendEvent abi.Event ) func init() { addressType, _ := abi.NewType("address", "", nil) uint256Type, _ := abi.NewType("uint256", "", nil) stringType, _ := abi.NewType("string", "", nil) BankSendEvent = abi.NewEvent( "__CosmosNativeBankSend", "__CosmosNativeBankSend", false, abi.Arguments{abi.Argument{ Name: "recipient", Type: addressType, Indexed: false, }, abi.Argument{ Name: "amount", Type: uint256Type, Indexed: false, }, abi.Argument{ Name: "denom", Type: stringType, Indexed: false, }}, ) } type BankSendHook struct { bankKeeper bankkeeper.Keeper } func NewBankSendHook(bankKeeper bankkeeper.Keeper) *BankSendHook { return &BankSendHook{ bankKeeper: bankKeeper, } } func (h BankSendHook) PostTxProcessing(ctx sdk.Context, txHash common.Hash, logs []*ethtypes.Log) error { for _, log := range logs { if len(log.Topics) == 0 || log.Topics[0] != BankSendEvent.ID { continue } if !ContractAllowed(log.Address) { // Check the contract whitelist to prevent accidental native call. continue } unpacked, err := BankSendEvent.Inputs.Unpack(log.Data) if err != nil { log.Warn("log signature matches but failed to decode") continue } contract := sdk.AccAddress(log.Address.Bytes()) recipient := sdk.AccAddress(unpacked[0].(common.Address).Bytes()) coins := sdk.NewCoins(sdk.NewCoin(unpacked[2].(string), sdk.NewIntFromBigInt(unpacked[1].(*big.Int)))) err = h.bankKeeper.SendCoins(ctx, contract, recipient, coins) if err != nil { return err } } } return nil } ``` -------------------------------- ### Query Block Gas Command Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/08_client.md Shows the command structure for querying the block gas usage. Use '...' for flags. ```bash ethermintd query feemarket block-gas [flags] ``` -------------------------------- ### Initialize Swagger UI Source: https://github.com/evmos/ethermint/blob/main/client/docs/swagger-ui/index.html This snippet shows the basic JavaScript code required to initialize Swagger UI on a webpage. It specifies the URL of the OpenAPI specification and the DOM element where the UI should be rendered. ```javascript window.onload = function() { // Build a system const ui = SwaggerUIBundle({ url: "./swagger.yaml", dom_id: '#swagger-ui', deepLinking: true, presets: [ SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset ], plugins: [ SwaggerUIBundle.plugins.DownloadUrl ], layout: "StandaloneLayout" }) window.ui = ui } ``` -------------------------------- ### Base Fee Calculation Logic Source: https://github.com/evmos/ethermint/blob/main/x/feemarket/spec/03_begin_block.md This pseudocode illustrates the dynamic calculation of the base fee based on the previous block's gas usage relative to the parent gas target. It handles scenarios where gas used is equal to, greater than, or less than the target, adjusting the base fee accordingly. ```pseudocode parent_gas_target = parent_gas_limit / ELASTICITY_MULTIPLIER if EnableHeight == block.number base_fee = INITIAL_BASE_FEE else if parent_gas_used == parent_gas_target: base_fee = parent_base_fee else if parent_gas_used > parent_gas_target: gas_used_delta = parent_gas_used - parent_gas_target base_fee_delta = max(parent_base_fee * gas_used_delta / parent_gas_target / BASE_FEE_MAX_CHANGE_DENOMINATOR, 1) base_fee = parent_base_fee + base_fee_delta else: gas_used_delta = parent_gas_target - parent_gas_used base_fee_delta = parent_base_fee * gas_used_delta / parent_gas_target / BASE_FEE_MAX_CHANGE_DENOMINATOR base_fee = parent_base_fee - base_fee_delta ``` -------------------------------- ### QueryParams Source: https://github.com/evmos/ethermint/blob/main/docs/api/proto-docs.md Queries the current parameters of the x/evm module. This includes configuration settings for the EVM module. ```APIDOC ## GET /evmos/ethermint/v1/params ### Description Queries the current parameters of the x/evm module. This includes configuration settings for the EVM module. ### Method GET ### Endpoint /evmos/ethermint/v1/params ### Response #### Success Response (200) - **params** (Params) - The parameters for the evm module. ### Response Example ```json { "params": { "evm_denom": "eth", "enable_create": true, "enable_call": true, "gas_price_hard_limit": "10000000000000000", "min_gas_price": "0" } } ``` ``` -------------------------------- ### Params Source: https://github.com/evmos/ethermint/blob/main/docs/api/proto-docs.md Params queries the parameters of x/evm module. This method retrieves the current configuration parameters for the EVM module. ```APIDOC ## GET /ethermint/evm/v1/params ### Description Params queries the parameters of x/evm module. ### Method GET ### Endpoint /ethermint/evm/v1/params ### Response #### Success Response (200) - **params** (Params) - The EVM module parameters. ``` -------------------------------- ### EVM GenesisState Definition Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/02_state.md Defines the state required for initializing the EVM module from a previous exported height. It includes genesis accounts and module parameters. ```go type GenesisState struct { // accounts is an array containing the ethereum genesis accounts. Accounts []GenesisAccount `protobuf:"bytes,1,rep,name=accounts,proto3" json:"accounts" // params defines all the parameters of the module. Params Params `protobuf:"bytes,2,opt,name=params,proto3" json:"params" } ``` -------------------------------- ### EVM Module Architecture Source: https://github.com/evmos/ethermint/blob/main/x/evm/spec/README.md Outlines the directory structure and key components of the EVM module within a Cosmos SDK project. This includes client, keeper, and types subdirectories. ```shell evm/ ├── client │ └── cli │ ├── query.go # CLI query commands for the module │ └── tx.go # CLI transaction commands for the module ├── keeper │ ├── keeper.go # ABCI BeginBlock and EndBlock logic │ ├── keeper.go # Store keeper that handles the business logic of the module and has access to a specific subtree of the state tree. │ ├── params.go # Parameter getter and setter │ ├── querier.go # State query functions │ └── statedb.go # Functions from types/statedb with a passed in sdk.Context ├── types │   ├── chain_config.go │   ├── codec.go # Type registration for encoding │   ├── errors.go # Module-specific errors │   ├── events.go # Events exposed to the Tendermint PubSub/Websocket │   ├── genesis.go # Genesis state for the module │   ├── journal.go # Ethereum Journal of state transitions │   ├── keys.go # Store keys and utility functions │   ├── logs.go # Types for persisting Ethereum tx logs on state after chain upgrades │   ├── msg.go # EVM module transaction messages │   ├── params.go # Module parameters that can be customized with governance parameter change proposals │   ├── state_object.go # EVM state object │   ├── statedb.go # Implementation of the StateDb interface │   ├── storage.go # Implementation of the Ethereum state storage map using arrays to prevent non-determinism │   └── tx_data.go # Ethereum transaction data types ├── genesis.go # ABCI InitGenesis and ExportGenesis functionality ├── handler.go # Message routing └── module.go # Module setup for the module manager ``` -------------------------------- ### ChainConfig Source: https://github.com/evmos/ethermint/blob/main/docs/api/proto-docs.md Specifies Ethereum ChainConfig parameters using sdk.Int values, detailing various hard fork activation blocks. ```APIDOC ## ChainConfig ### Description ChainConfig defines the Ethereum ChainConfig parameters using *sdk.Int values instead of *big.Int. ### Fields - `homestead_block` (string) - Homestead switch block (nil no fork, 0 = already homestead) - `dao_fork_block` (string) - TheDAO hard-fork switch block (nil no fork) - `dao_fork_support` (bool) - Whether the nodes supports or opposes the DAO hard-fork - `eip150_block` (string) - EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) EIP150 HF block (nil no fork) - `eip150_hash` (string) - EIP150 HF hash (needed for header only clients as only gas pricing changed) - `eip155_block` (string) - EIP155Block HF block - `eip158_block` (string) - EIP158 HF block - `byzantium_block` (string) - Byzantium switch block (nil no fork, 0 = already on byzantium) - `constantinople_block` (string) - Constantinople switch block (nil no fork, 0 = already activated) - `petersburg_block` (string) - Petersburg switch block (nil same as Constantinople) - `istanbul_block` (string) - Istanbul switch block (nil no fork, 0 = already on istanbul) - `muir_glacier_block` (string) - Eip-2384 (bomb delay) switch block (nil no fork, 0 = already activated) - `berlin_block` (string) - Berlin switch block (nil = no fork, 0 = already on berlin) - `london_block` (string) - London switch block (nil = no fork, 0 = already on london) - `arrow_glacier_block` (string) - Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated) - `gray_glacier_block` (string) - EIP-5133 (bomb delay) switch block (nil = no fork, 0 = already activated) - `merge_netsplit_block` (string) - Virtual fork after The Merge to use as a network splitter ``` -------------------------------- ### ApplyMessage Function for EVM State Updates Source: https://github.com/evmos/ethermint/blob/main/docs/architecture/adr-001-state.md Computes the new state by applying a message against the existing state. Handles contract creation and calls, returning VM errors without affecting consensus if the message fails. ```go func (k *Keeper) ApplyMessage(evm *vm.EVM, msg core.Message, cfg *params.ChainConfig) (*types.MsgEthereumTxResponse, error) { var ( ret []byte // return bytes from evm execution vmErr error // vm errors do not effect consensus and are therefore not assigned to err ) sender := vm.AccountRef(msg.From()) contractCreation := msg.To() == nil // transaction gas meter (tracks limit and usage) gasConsumed := k.ctx.GasMeter().GasConsumed() leftoverGas := k.ctx.GasMeter().Limit() - k.ctx.GasMeter().GasConsumedToLimit() // NOTE: Since CRUD operations on the SDK store consume gas we need to set up an infinite gas meter so that we only consume // the gas used by the Ethereum message execution. // Not setting the infinite gas meter here would mean that we are incurring in additional gas costs k.WithContext(k.ctx.WithGasMeter(sdk.NewInfiniteGasMeter())) // NOTE: gas limit is the GasLimit defined in the message minus the Intrinsic Gas that has already been // consumed on the AnteHandler. // ensure gas is consistent during CheckTx if k.ctx.IsCheckTx() { // check gas consumption correctness } if contractCreation { ret, _, leftoverGas, vmErr = evm.Create(sender, msg.Data(), leftoverGas, msg.Value()) } else { ret, leftoverGas, vmErr = evm.Call(sender, *msg.To(), msg.Data(), leftoverGas, msg.Value()) } // refund gas prior to handling the vm error in order to set the updated gas meter if err := k.RefundGas(msg, leftoverGas); err != nil { // return error } if vmErr != nil { if errors.Is(vmErr, vm.ErrExecutionReverted) { // return error with revert reason } // return execution error } return &types.MsgEthereumTxResponse{ Ret: ret, Reverted: false, }, nil } ``` -------------------------------- ### Keeper Implements StateDB Interface Source: https://github.com/evmos/ethermint/blob/main/docs/architecture/adr-001-state.md This code snippet demonstrates that the Keeper type now fully implements the vm.StateDB interface. It shows the type definition for Keeper, highlighting its role as the EVM module state keeper and its reliance on KVStores and external Keepers. ```go var _ vm.StateDB = (*Keeper)(nil) // Keeper defines the EVM module state keeper for CRUD operations. // It also implements the go-ethereum vm.StateDB interface. Instead of using // a trie and database for querying and persistence, the Keeper uses KVStores // and external Keepers to facilitate state transitions for accounts and balance // accounting. type Keeper struct { // store key and encoding codec // external module keepers (account, bank, etc) and params subspace // cache fields and sdk.Context (reset every block) // other CommitStateDB fields (journal, accessList, etc) } ```