#ifndef EVMC_H
#define EVMC_H
#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 6)
#define EVMC_DEPRECATED __attribute__((deprecated))
#else
#define EVMC_DEPRECATED
#endif
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#if __cplusplus
extern "C" {
#endif
enum
{
EVMC_ABI_VERSION = 7
};
typedef struct evmc_bytes32
{
uint8_t bytes[32];
} evmc_bytes32;
typedef struct evmc_bytes32 evmc_uint256be;
typedef struct evmc_address
{
uint8_t bytes[20];
} evmc_address;
enum evmc_call_kind
{
EVMC_CALL = 0,
EVMC_DELEGATECALL = 1,
EVMC_CALLCODE = 2,
EVMC_CREATE = 3,
EVMC_CREATE2 = 4
};
enum evmc_flags
{
EVMC_STATIC = 1
};
struct evmc_message
{
enum evmc_call_kind kind;
uint32_t flags;
int32_t depth;
int64_t gas;
evmc_address destination;
evmc_address sender;
const uint8_t* input_data;
size_t input_size;
evmc_uint256be value;
evmc_bytes32 create2_salt;
};
struct evmc_tx_context
{
evmc_uint256be tx_gas_price;
evmc_address tx_origin;
evmc_address block_coinbase;
int64_t block_number;
int64_t block_timestamp;
int64_t block_gas_limit;
evmc_uint256be block_difficulty;
evmc_uint256be chain_id;
};
struct evmc_host_context;
typedef struct evmc_tx_context (*evmc_get_tx_context_fn)(struct evmc_host_context* context);
typedef evmc_bytes32 (*evmc_get_block_hash_fn)(struct evmc_host_context* context, int64_t number);
enum evmc_status_code
{
EVMC_SUCCESS = 0,
EVMC_FAILURE = 1,
EVMC_REVERT = 2,
EVMC_OUT_OF_GAS = 3,
EVMC_INVALID_INSTRUCTION = 4,
EVMC_UNDEFINED_INSTRUCTION = 5,
EVMC_STACK_OVERFLOW = 6,
EVMC_STACK_UNDERFLOW = 7,
EVMC_BAD_JUMP_DESTINATION = 8,
EVMC_INVALID_MEMORY_ACCESS = 9,
EVMC_CALL_DEPTH_EXCEEDED = 10,
EVMC_STATIC_MODE_VIOLATION = 11,
EVMC_PRECOMPILE_FAILURE = 12,
EVMC_CONTRACT_VALIDATION_FAILURE = 13,
EVMC_ARGUMENT_OUT_OF_RANGE = 14,
EVMC_WASM_UNREACHABLE_INSTRUCTION = 15,
EVMC_WASM_TRAP = 16,
EVMC_INTERNAL_ERROR = -1,
EVMC_REJECTED = -2,
EVMC_OUT_OF_MEMORY = -3
};
struct evmc_result;
typedef void (*evmc_release_result_fn)(const struct evmc_result* result);
struct evmc_result
{
enum evmc_status_code status_code;
int64_t gas_left;
const uint8_t* output_data;
size_t output_size;
evmc_release_result_fn release;
evmc_address create_address;
uint8_t padding[4];
};
typedef bool (*evmc_account_exists_fn)(struct evmc_host_context* context,
const evmc_address* address);
typedef evmc_bytes32 (*evmc_get_storage_fn)(struct evmc_host_context* context,
const evmc_address* address,
const evmc_bytes32* key);
enum evmc_storage_status
{
EVMC_STORAGE_UNCHANGED = 0,
EVMC_STORAGE_MODIFIED = 1,
EVMC_STORAGE_MODIFIED_AGAIN = 2,
EVMC_STORAGE_ADDED = 3,
EVMC_STORAGE_DELETED = 4
};
typedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_host_context* context,
const evmc_address* address,
const evmc_bytes32* key,
const evmc_bytes32* value);
typedef evmc_uint256be (*evmc_get_balance_fn)(struct evmc_host_context* context,
const evmc_address* address);
typedef size_t (*evmc_get_code_size_fn)(struct evmc_host_context* context,
const evmc_address* address);
typedef evmc_bytes32 (*evmc_get_code_hash_fn)(struct evmc_host_context* context,
const evmc_address* address);
typedef size_t (*evmc_copy_code_fn)(struct evmc_host_context* context,
const evmc_address* address,
size_t code_offset,
uint8_t* buffer_data,
size_t buffer_size);
typedef void (*evmc_selfdestruct_fn)(struct evmc_host_context* context,
const evmc_address* address,
const evmc_address* beneficiary);
typedef void (*evmc_emit_log_fn)(struct evmc_host_context* context,
const evmc_address* address,
const uint8_t* data,
size_t data_size,
const evmc_bytes32 topics[],
size_t topics_count);
typedef struct evmc_result (*evmc_call_fn)(struct evmc_host_context* context,
const struct evmc_message* msg);
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;
};
struct evmc_vm;
typedef void (*evmc_destroy_fn)(struct evmc_vm* vm);
enum evmc_set_option_result
{
EVMC_SET_OPTION_SUCCESS = 0,
EVMC_SET_OPTION_INVALID_NAME = 1,
EVMC_SET_OPTION_INVALID_VALUE = 2
};
typedef enum evmc_set_option_result (*evmc_set_option_fn)(struct evmc_vm* vm,
char const* name,
char const* value);
enum evmc_revision
{
EVMC_FRONTIER = 0,
EVMC_HOMESTEAD = 1,
EVMC_TANGERINE_WHISTLE = 2,
EVMC_SPURIOUS_DRAGON = 3,
EVMC_BYZANTIUM = 4,
EVMC_CONSTANTINOPLE = 5,
EVMC_PETERSBURG = 6,
EVMC_ISTANBUL = 7,
EVMC_BERLIN = 8,
EVMC_MAX_REVISION = EVMC_BERLIN
};
typedef struct evmc_result (*evmc_execute_fn)(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);
enum evmc_capabilities
{
EVMC_CAPABILITY_EVM1 = (1u << 0),
EVMC_CAPABILITY_EWASM = (1u << 1),
EVMC_CAPABILITY_PRECOMPILES = (1u << 2)
};
typedef uint32_t evmc_capabilities_flagset;
typedef evmc_capabilities_flagset (*evmc_get_capabilities_fn)(struct evmc_vm* vm);
struct evmc_vm
{
const int abi_version;
const char* name;
const char* version;
evmc_destroy_fn destroy;
evmc_execute_fn execute;
evmc_get_capabilities_fn get_capabilities;
evmc_set_option_fn set_option;
};
#if EVMC_DOCUMENTATION
struct evmc_vm* evmc_create_example_vm(void);
#endif
#if __cplusplus
}
#endif
#endif