AppLayer
  • Welcome to AppLayer Docs
  • Introducing AppLayer
    • A Primer on Smart Contracts
    • The Problem With EVMs
    • What is AppLayer?
  • How AppLayer works
    • Validators
    • Sentinels
    • Application Chains
    • Bridging
      • AppLayer-to-AppLayer Data Bridging
      • AppLayer-to-AppLayer Token Bridging
      • AppLayer-to-External Bridging (Ethereum, Solana, etc.)
  • Understanding rdPoS
    • Blockchains overview
    • How rdPoS works
    • Validator implementations
    • Slashing
  • BDK implementation
    • The utils folder
    • The contract folder
    • The core folder
    • Transactions and Blocks
    • Database
    • Contract call handling
    • RLP (Recursive-Length Prefix)
    • P2P Overview
    • P2P Encoding
  • Understanding contracts
    • Solidity ABI
    • Internal and external contract calls
    • Setting up the development environment
    • Contract Tester
  • Precompiled contracts
    • Types of pre-compiled contracts
    • Dynamic and Protocol Contracts
    • SafeVariables and commit/revert logic
    • How to code a precompiled contract
    • Creating a Dynamic Contract (Simple)
      • Simple Contract Header
      • Simple Contract Source
      • Deploying and testing
    • Creating a Dynamic Contract (Advanced)
    • Creating a Protocol Contract (Advanced)
  • EVM contracts
    • State management and VM instance creation
    • Seamless C++/EVM integration
    • C++ to other contract calls
    • EVM to other contract calls
    • Executing contract calls via EVMC
    • Calling EVM contracts from C++
    • Calling C++ contracts from EVM
  • Getting started with AppLayer Testnet
  • Join our Community
  • Get in Touch
  • Glossary
Powered by GitBook
On this page
  1. EVM contracts

Executing contract calls via EVMC

How to use AppLayer's EVM directly to call contracts.

To execute a contract call within AppLayer's EVM environment, we use the evmc_execute() function from the EVMC library. This function orchestrates the execution of contract bytecode, interfacing directly with the Ethereum Virtual Machine:

static inline struct evmc_result evmc_execute(
  struct evmc_vm* vm, const struct evmc_host_interface* host,
  struct evmc_host_context* context, enum evmc_revision rev,
  const struct evmc_message* msg, uint8_t const* code, size_t code_size
);

It's crucial to understand that the VM itself is stateless—it does not maintain any information about the contracts' states or their data. The VM's role is strictly to interpret and execute bytecode according to the Ethereum protocol specifications.

To enable the stateless VM to interact with the state (such as storage keys, account balances, or initiating further contract calls), we must provide it with access to the state through the evmc_host_interface and evmc_host_context structs. The evmc_host_interface struct contains a set of callback functions that the VM can use to query or modify the state:

struct evmc_host_interface {
  evmc_account_exists_fn account_exists;
  evmc_get_storage_fn get_storage;
  evmc_set_storage_fn set_storage;
  evmc_get_balance_fn get_balance;
  evmc_get_code_size_fn get_code_size;
  evmc_get_code_hash_fn get_code_hash;
  evmc_copy_code_fn copy_code;
  evmc_selfdestruct_fn selfdestruct;
  evmc_call_fn call;
  evmc_get_tx_context_fn get_tx_context;
  evmc_get_block_hash_fn get_block_hash;
  evmc_emit_log_fn emit_log;
  evmc_access_account_fn access_account;
  evmc_access_storage_fn access_storage;
  evmc_get_transient_storage_fn get_transient_storage;
  evmc_set_transient_storage_fn set_transient_storage;
};

Within AppLayer's BDK, we use evmc_execute() like this:

evmc::Result result (evmc_execute(this->vm_, &this->get_interface(), this->to_context(),
evmc_revision::EVMC_LATEST_STABLE_REVISION, &msg, recipientAcc.code.data(), recipientAcc.code.size()));

ContractHost is casted into evmc_host_interface to provide the VM with the necessary state access functions. This allows the VM to interact with the state and execute contract calls within AppLayer's environment.

PreviousEVM to other contract callsNextCalling EVM contracts from C++

Last updated 1 year ago