Injective | Documentation
InjectiveGithub
Injective | Documentation
Injective | Documentation
  • About Injective
  • DeFi
    • Wallet
      • Create a wallet
      • Accounts
    • Trading
      • Order Types
      • Trading Fees and Rebates
      • Margin Trading
      • Liquidation
      • Funding Rates
      • Performing Liquidations
      • Derivatives
      • Perpetuals
      • Expiry Futures
      • Pre-Launch Futures
      • Index Perpetual Futures
      • iAssets
    • Token Standards
      • INJ coin
      • Token Factory
      • CW20 Standard
    • Bridge
      • From Ethereum
      • From Solana
      • Using Wormhole
      • Using IBC
    • Staking
    • Governance
    • Auction
    • Transactions
    • Transaction Gas and Fees
    • Open Liquidity Program
      • Introduction
      • Rewards
      • Epochs
      • Eligibility
      • Program Details
      • Scoring Formula/Methodology
      • Formula Parameters
      • Reward Allocations
      • Flexible Reward Allocations
      • Eligible Markets
      • Legacy Reward Allocations
      • Reward Disbursements
      • Performance Tracking
      • Volatility Response Modifications
      • Fee Tiers
    • Injective Hub
    • Injective Explorer
  • Infrastructure
    • Command Line Node Interaction
    • gRPC Node Interaction
    • Go Node Interaction
    • REST Node Interaction
    • Run Node
    • Set up Keyring
    • Join Network
    • Cosmovisor
    • Upgrade Node
    • Mainnet Validator
      • Peggo
      • Canonical Chain Upgrades
      • v1.16.2
      • v1.16.1
      • v1.16.0
      • v1.15.0
      • v1.14.1
      • v1.14.0
      • v1.13.3
      • v1.13.2
      • v1.13.0 - Altaris
      • v1.12.1
      • v1.12.0 - Volan
      • v1.11.0
      • v1.10.0
      • 10009
      • 10008 - Camelot
      • 10007-rc1
      • 10006-rc1
      • 10005-rc1
      • 10004-rc1-patch
      • 10004-rc1
      • 10003-rc1
      • 10002-rc2
      • 10002-rc1
    • Testnet Validator
      • Peggo
    • Public Endpoints
    • Premium Endpoints
    • Archival Setup
    • Indexer API Reference
  • Developers
    • Convert addresses
    • Network Information
    • injectived
      • Install injectived
      • Using injectived
      • injectived Commands
      • Testnet Proposals
    • Concepts
      • Sentry Node
      • Indexer API
      • Trading Account
      • gRPC and Protobuf
      • Token Factory
      • Market min price tick size calculation
      • Market min quantity tick size calculation
      • CosmJs Support
      • Networks
    • Assets
      • Denom
      • Token Metadata
      • Injective List
      • Creating Tokens
    • dApps
      • Nuxt configuration
      • React configuration
      • Running examples
      • Smart contract examples
      • DEX examples
      • Webpack examples
    • Testnet Faucet
    • Chain API Reference
    • Injective TypeScript SDK
    • Injective Go SDK
    • Injective Python SDK
    • Injective CosmWasm SDK
    • Injective Rust SDK
    • The Graph
  • EVM Developers
    • EVM Network Information
    • Your First EVM Smart Contract
      • Compile with Hardhat
      • Test with Hardhat
      • Deploy with Hardhat
      • Verify with Hardhat
      • Interact with Hardhat
      • Compile with Foundry
      • Test with Foundry
      • Deploy with Foundry
      • Verify with Foundry
      • Interact with Foundry
    • Your First EVM dApp
      • Connect with MetaMask
      • Connect with WalletConnect
    • EVM Equivalence
    • MultiVM Token Standard
    • Precompiles
    • Bank Precompile
    • Exchange Precompile
    • ERC20 Module
    • Infrastructure & Tooling
    • EVM Testnet Faucet
    • EVM Testnet Explorer
  • Cosmwasm Developers
    • CosmWasm Smart Contracts
      • Your First CosmWasm Smart Contract
      • Injective Name Service
      • NeptuneService
      • CW20 to Bank & Market Order in One Transaction
    • Local Development Guide
    • Mainnet Deployment Guide
    • Whitelisting Deployment Address Guide
    • Create your Swap Contract Guide
    • Creating UIs Guide
    • Using Injective Queries and Messages
    • CW20 Adapter
    • Injective Test Tube
  • DeFi Developers
    • Min Price Tick Size Calculation
    • Min Quantity Tick Size Calculation
    • Testnet Faucet Integration
    • Launch a Token
    • Launch a Market
    • Denom Metadata
    • Provider Oracle
    • Build a DEX
    • Exchange API Reference
  • Native Developers
    • Wallets
      • Accounts
      • Connections
      • Strategy
      • Offchain Data
    • Bridges
      • Ethereum Bridge
    • Transactions
      • Cosmos Transaction
      • Ledger through Keplr Wallet Transaction
      • Ethereum Transaction
      • Ledger through Keplr Wallet Transaction
      • MsgBroadcaster Transaction
      • Private Key Transaction
      • Web3 Gateway Transaction
    • Transaction Examples
      • Auction
      • AuthZ
      • Bank
      • Distribution
      • Exchange
      • Fee Grant
      • Governance
      • IBC
      • Insurance
      • Peggy
      • Permissions
      • Staking
      • Token Factory
      • Wasm
    • Querying the Chain
      • Auction
      • Auth
      • Bank
      • Distribution
      • Exchange
      • Governance
      • IBC
      • Mint
      • Insurance Fund
      • Oracle
      • Peggy
      • Permissions
      • Staking
      • Tendermint
      • Wasm
      • WasmX
      • Token Factory
    • Querying the Indexer
      • Account
      • Auction
      • Derivatives
      • Explorer
      • Insurance Funds
      • Markets
      • Leaderboard
      • Mito
      • Oracle
      • Portfolio
      • Spot
      • Web3 Gateway Transactions
    • Streaming the Indexer
      • Account
      • Auction
      • Derivatives
      • Oracle
      • Portfolio
      • Spot
      • Explorer
    • Querying Ethereum with GraphQL
    • Injective Modules
      • Auction
        • State
        • Messages
        • EndBlock
        • Events
        • Params
        • Errors
      • Exchange
        • Derivative Markets Concepts
        • Spot Markets Concepts
        • Binary Option Markets Concepts
        • Other Concepts
        • State
        • State Transitions
        • Messages
        • Proposals
        • BeginBlock
        • EndBlock
        • Events
        • Params
        • MsgPrivilegedExecuteContract
        • Errors
      • ERC20
        • Concepts
        • State
        • Messages
        • Events
      • EVM
        • Concepts
        • State
        • State Transitions
        • Transactions
        • ABCI
        • Hooks
        • Events
        • Params
        • Client
      • Insurance
        • State
        • State Transitions
        • Messages
        • EndBlock
        • Events
        • Params
        • Improvements
        • Errors
      • OCR
        • Concepts
        • State
        • Messages
        • Proposals
        • BeginBlock
        • Hooks
        • Events
        • Params
        • Errors
      • Oracle
        • State
        • Keeper
        • Messages
        • Proposals
        • Events
        • Improvements
        • Errors
      • Peggy
        • Definitions
        • Workflow
        • State
        • Messages
        • Slashing
        • EndBlock
        • Events
        • Params
        • Relay Semantics
        • Improvements
        • Errors
      • Permissions
        • Concepts
        • State
        • State Transition
        • Errors
      • TokenFactory
        • Concepts
        • State
        • Messages
        • Events
        • Params
        • Errors
      • WasmX
        • Concepts
        • Data
        • Proposals
        • Messages
        • Params
        • Errors
      • Lanes
      • TxFees
    • Core Modules
      • Auth
      • AuthZ
      • Bank
      • Consensus
      • Crisis
      • Distribution
      • Evidence
      • Feegrant
      • Gov
      • Group
      • Mint
      • NFT
      • Params
      • Slashing
      • Staking
      • Upgrade
      • Circuit
      • Genutil
  • FAQ
  • Glossary
  • References
Powered by GitBook
On this page
Edit on GitHub
Export as PDF
  1. Native Developers
  2. Injective Modules
  3. EVM

Concepts

PreviousEVMNextState

Last updated 1 minute ago

CtrlK
  • EVM
  • State
  • Accounts
  • Architecture
  • State Transitions with Smart Contracts
  • Executing EVM bytecode
  • Ethermint as Geth implementation
  • JSON-RPC
  • StateDB
  • Consensus Engine
  • Transaction Logs
  • Block Bloom

EVM

The Ethereum Virtual Machine (EVM) is a computation engine which can be thought of as one single entity maintained by thousands of connected computers (nodes) running an Ethereum client. As a virtual machine (VM), the EVM is responisble for computing changes to the state deterministically regardless of its environment (hardware and OS). This means that every node has to get the exact same result given an identical starting state and transaction (tx).

The EVM is considered to be the part of the Ethereum protocol that handles the deployment and execution of smart contracts. To make a clear distinction:

  • The Ethereum protocol describes a blockchain, in which all Ethereum accounts and smart contracts live. It has only one canonical state (a data structure, which keeps all accounts) at any given block in the chain.

  • The EVM, however, is the state machine that defines the rules for computing a new valid state from block to block. It is an isolated runtime, which means that code running inside the EVM has no access to network, filesystem, or other processes (not external APIs).

The x/evm module implements the EVM as a Cosmos SDK module. It allows users to interact with the EVM by submitting Ethereum txs and executing their containing messages on the given state to evoke a state transition.

State

The Ethereum state is a data structure, implemented as a Merkle Patricia Trie, that keeps all accounts on the chain. The EVM makes changes to this data structure resulting in a new state with a different State Root. Ethereum can therefore be seen as a state chain that transitions from one state to another by executing transations in a block using the EVM. A new block of txs can be described through its Block header (parent hash, block number, time stamp, nonce, receipts,...).

Accounts

There are two types of accounts that can be stored in state at a given address:

  • Externally Owned Account (EOA): Has nonce (tx counter) and balance

  • Smart Contract: Has nonce, balance, (immutable) code hash, storage root (another Merkle Patricia Trie)

Smart contracts are just like regular accounts on the blockchain, which additionally store executable code in an Ethereum-specific binary format, known as EVM bytecode. They are typically written in an Ethereum high level language such as Solidity which is compiled down to EVM bytecode and deployed on the blockchain, by submitting a tx using an Ethereum client.

Architecture

The EVM operates as a stack-based machine. It's main architecture components consist of:

  • Virtual ROM: contract code is pulled into this read only memory when processing txs

  • Machine state (volatile): changes as the EVM runs and is wiped clean after processing each tx

    • Program counter (PC)

    • Gas: keeps track of how much gas is used

    • Stack and Memory: compute state changes

  • Access to account storage (persistent)

State Transitions with Smart Contracts

Typically smart contracts expose a public ABI, which is a list of supported ways a user can interact with a contract. To interact with a contract and invoke a state transition, a user will submit a tx carrying any amount of gas and a data payload formatted according to the ABI, specifying the type of interaction and any additional parameters. When the tx is received, the EVM executes the smart contracts's EVM bytecode using the tx payload.

Executing EVM bytecode

A contract's EVM bytecode consists of basic operations (add, multiply, store, etc...), called Opcodes. Each Opcode execution requires gas that needs to be payed with the tx. The EVM is therefore considered quasi-turing complete, as it allows any arbitrary computation, but the amount of computations during a contract execution is limited to the amount of gas provided in the tx. Each Opcode's gas cost reflects the cost of running these operations on actual computer hardware (e.g. ADD = 3gas and SSTORE = 100gas). To calculate the gas consumption of a tx, the gas cost is multiplied by the gas price, which can change depending on the demand of the network at the time. If the network is under heavy load, you might have to pay a highter gas price to get your tx executed. If the gas limit is hit (out of gas execption) no changes to the Ethereum state are applied, except that the sender's nonce increments and their balance goes down to pay for wasting the EVM's time.

Smart contracts can also call other smart contracts. Each call to a new contract creates a new instance of the EVM (including a new stack and memory). Each call passes the sandbox state to the next EVM. If the gas runs out, all state changes are discareded. Otherwise they are kept.

For further reading, please refer to:

  • EVM

  • EVM Architecture

  • What is Ethereum

  • Opcodes

Ethermint as Geth implementation

Ethermint is an implementation of the Etherum protocal in Golang (Geth) as a Cosmos SDK module. Geth includes an implementation of the EVM to compute state transitions. Have a look at the go-etheruem source code to see how the EVM opcodes are implemented. Just as Geth can be run as an Ethereum node, Ethermint can be run as a node to compute state transitions with the EVM. Ethermint supports Geth's standard Ethereum JSON-RPC APIs in order to be Web3 and EVM compatible.

JSON-RPC

JSON-RPC is a stateless, lightweight remote procedure call (RPC) protocol. Primarily this specification defines several data structures and the rules around their processing. It is transport agnostic in that the concepts can be used within the same process, over sockets, over HTTP, or in many various message passing environments. It uses JSON (RFC 4627) as a data format.

JSON-RPC Example: eth_call

The JSON-RPC method eth_call allows you to execute messages against contracts. Usually, you need to send a transaction to a Geth node to include it in the mempool, then nodes gossip between each other and eventually the transaction is included in a block and gets executed. eth_call however lets you send data to a contract and see what happens without commiting a transaction.

In the Geth implementation, calling the endpoint roughly goes through the following steps:

  1. The eth_call request is transformed to call the func (s *PublicBlockchainAPI) Call() function using the eth namespace

  2. Call() is given the transaction arguments, the block to call against and optional overides that modify the state to call against. It then calls DoCall()

  3. DoCall() transforms the arguments into a ethtypes.message, instantiates an EVM and applies the message with core.ApplyMessage

  4. ApplyMessage() calls the state transition TransitionDb()

  5. TransitionDb() either Create()s a new contract or Call()s a contract

  6. evm.Call() runs the interpreter evm.interpreter.Run() to execute the message. If the execution fails, the state is reverted to a snapshot taken before the execution and gas is consumed.

  7. Run() performs a loop to execute the opcodes.

The Injective implementation is similar and makes use of the gRPC query client which is included in the Cosmos SDK:

  1. eth_call request is transformed to call the func (e *PublicAPI) Call function using the eth namespace

  2. Call() calls doCall()

  3. doCall() transforms the arguments into a EthCallRequest and calls EthCall() using the query client of the evm module.

  4. EthCall() transforms the arguments into a ethtypes.message and calls `ApplyMessageWithConfig()

  5. ApplyMessageWithConfig() instantiates an EVM and either Create()s a new contract or Call()s a contract using the Geth implementation.

StateDB

The StateDB interface from go-ethereum represents an EVM database for full state querying. EVM state transitions are enabled by this interface, which in the x/evm module is implemented by the Keeper. The implementation of this interface is what makes Ethermint EVM compatible.

Consensus Engine

The application using the x/evm module interacts with the Tendermint Core Consensus Engine over an Application Blockchain Interface (ABCI). Together, the application and Tendermint Core form the programs that run a complete blockchain and combine business logic with decentralized data storage.

Ethereum transactions that are submitted to the x/evm module take part in a this consensus process before being executed and changing the application state. We encourage to understand the basics of the Tendermint consensus engine in order to understand state transitions in detail.

Transaction Logs

On every x/evm transaction, the result contains the Ethereum Logs from the state machine execution that are used by the JSON-RPC Web3 server for filter querying and for processing the EVM Hooks.

The tx logs are stored in the transient store during tx execution and then emitted through cosmos events after the transaction has been processed. They can be queried via gRPC and JSON-RPC.

Block Bloom

Bloom is the bloom filter value in bytes for each block that can be used for filter queries. The block bloom value is stored in the transient store and then emitted through a cosmos event during EndBlock processing. They can be queried via gRPC and JSON-RPC.

::: tip 👉 Note: Since they are not stored on state, Transaction Logs and Block Blooms are not persisted after upgrades. A user must use an archival node after upgrades in order to obtain legacy chain events. :::