2016-06-24 09:35:33 +00:00
|
|
|
/// EVM-C -- C interface to Ethereum Virtual Machine
|
|
|
|
///
|
|
|
|
/// ## High level design rules
|
|
|
|
/// 1. Pass function arguments and results by value.
|
|
|
|
/// This rule comes from modern C++ and tries to avoid costly alias analysis
|
|
|
|
/// needed for optimization. As the result we have a lots of complex structs
|
|
|
|
/// and unions. And variable sized arrays of bytes cannot be passed by copy.
|
|
|
|
/// 2. The EVM operates on integers so it prefers values to be host-endian.
|
|
|
|
/// On the other hand, LLVM can generate good code for byte swaping.
|
|
|
|
/// The interface also tries to match host application "natural" endianess.
|
|
|
|
/// I would like to know what endianess you use and where.
|
|
|
|
///
|
|
|
|
/// @defgroup EVMC EVM-C
|
|
|
|
/// @{
|
2016-08-23 18:04:08 +00:00
|
|
|
#ifndef EVM_H
|
|
|
|
#define EVM_H
|
2016-06-24 09:35:33 +00:00
|
|
|
|
|
|
|
#include <stdint.h> // Definition of int64_t, uint64_t.
|
|
|
|
#include <stddef.h> // Definition of size_t.
|
|
|
|
|
|
|
|
#if __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2016-08-31 10:01:28 +00:00
|
|
|
// BEGIN Python CFFI declarations
|
|
|
|
|
2017-04-24 11:54:05 +00:00
|
|
|
enum {
|
|
|
|
/// The EVM-C ABI version number of the interface declared in this file.
|
|
|
|
EVM_ABI_VERSION = 0
|
|
|
|
};
|
2016-08-25 14:03:22 +00:00
|
|
|
|
2017-01-18 22:26:48 +00:00
|
|
|
/// Opaque struct representing execution enviroment managed by the host
|
|
|
|
/// application.
|
|
|
|
struct evm_env;
|
|
|
|
|
2016-08-31 09:40:02 +00:00
|
|
|
/// Big-endian 256-bit integer.
|
2016-06-24 09:35:33 +00:00
|
|
|
///
|
2016-08-31 09:40:02 +00:00
|
|
|
/// 32 bytes of data representing big-endian 256-bit integer. I.e. bytes[0] is
|
|
|
|
/// the most significant byte, bytes[31] is the least significant byte.
|
|
|
|
/// This type is used to transfer to/from the VM values interpreted by the user
|
|
|
|
/// as both 256-bit integers and 256-bit hashes.
|
|
|
|
struct evm_uint256be {
|
|
|
|
/// The 32 bytes of the big-endian integer or hash.
|
|
|
|
uint8_t bytes[32];
|
2016-06-24 09:35:33 +00:00
|
|
|
};
|
|
|
|
|
2016-08-22 17:26:37 +00:00
|
|
|
/// Big-endian 160-bit hash suitable for keeping an Ethereum address.
|
2016-08-31 09:40:02 +00:00
|
|
|
struct evm_uint160be {
|
2016-06-24 09:35:33 +00:00
|
|
|
/// The 20 bytes of the hash.
|
2016-07-26 12:00:59 +00:00
|
|
|
uint8_t bytes[20];
|
2016-06-24 09:35:33 +00:00
|
|
|
};
|
|
|
|
|
2017-01-12 15:45:14 +00:00
|
|
|
struct evm_message {
|
|
|
|
struct evm_uint160be address;
|
|
|
|
struct evm_uint160be sender;
|
|
|
|
struct evm_uint256be value;
|
|
|
|
const uint8_t* input;
|
|
|
|
size_t input_size;
|
|
|
|
int64_t gas;
|
|
|
|
int32_t depth;
|
|
|
|
};
|
|
|
|
|
2017-01-17 11:22:53 +00:00
|
|
|
struct evm_tx_context {
|
|
|
|
struct evm_uint256be tx_gas_price;
|
|
|
|
struct evm_uint160be tx_origin;
|
|
|
|
struct evm_uint160be block_coinbase;
|
|
|
|
int64_t block_number;
|
|
|
|
int64_t block_timestamp;
|
|
|
|
int64_t block_gas_limit;
|
|
|
|
struct evm_uint256be block_difficulty;
|
|
|
|
};
|
|
|
|
|
2017-01-18 21:58:30 +00:00
|
|
|
typedef void (*evm_get_tx_context_fn)(struct evm_tx_context* result,
|
|
|
|
struct evm_env* env);
|
|
|
|
|
2017-01-19 21:39:21 +00:00
|
|
|
typedef void (*evm_get_block_hash_fn)(struct evm_uint256be* result,
|
|
|
|
struct evm_env* env,
|
|
|
|
int64_t number);
|
|
|
|
|
2016-08-25 11:44:34 +00:00
|
|
|
/// The execution result code.
|
|
|
|
enum evm_result_code {
|
2016-08-25 10:48:54 +00:00
|
|
|
EVM_SUCCESS = 0, ///< Execution finished with success.
|
|
|
|
EVM_FAILURE = 1, ///< Generic execution failure.
|
2016-08-24 11:30:45 +00:00
|
|
|
EVM_OUT_OF_GAS = 2,
|
|
|
|
EVM_BAD_INSTRUCTION = 3,
|
|
|
|
EVM_BAD_JUMP_DESTINATION = 4,
|
|
|
|
EVM_STACK_OVERFLOW = 5,
|
|
|
|
EVM_STACK_UNDERFLOW = 6,
|
2017-04-24 11:54:05 +00:00
|
|
|
EVM_REVERT = 7, ///< Execution terminated with REVERT opcode.
|
2017-04-25 15:01:46 +00:00
|
|
|
|
|
|
|
/// EVM implementation internal error.
|
|
|
|
///
|
|
|
|
/// FIXME: We should rethink reporting internal errors. One of the options
|
|
|
|
/// it to allow using any negative value to represent internal errors.
|
|
|
|
EVM_INTERNAL_ERROR = -1,
|
2016-08-23 21:58:39 +00:00
|
|
|
};
|
|
|
|
|
2016-12-20 15:50:23 +00:00
|
|
|
struct evm_result; ///< Forward declaration.
|
2016-09-27 15:14:19 +00:00
|
|
|
|
|
|
|
/// Releases resources assigned to an execution result.
|
|
|
|
///
|
|
|
|
/// This function releases memory (and other resources, if any) assigned to the
|
|
|
|
/// specified execution result making the result object invalid.
|
|
|
|
///
|
|
|
|
/// @param result The execution result which resource are to be released. The
|
|
|
|
/// result itself it not modified by this function, but becomes
|
|
|
|
/// invalid and user should discard it as well.
|
|
|
|
typedef void (*evm_release_result_fn)(struct evm_result const* result);
|
|
|
|
|
2016-08-25 10:11:24 +00:00
|
|
|
/// The EVM code execution result.
|
2016-06-24 09:35:33 +00:00
|
|
|
struct evm_result {
|
2016-08-25 11:44:34 +00:00
|
|
|
/// The execution result code.
|
|
|
|
enum evm_result_code code;
|
2016-08-23 21:58:39 +00:00
|
|
|
|
2016-08-25 10:11:24 +00:00
|
|
|
/// The amount of gas left after the execution.
|
|
|
|
///
|
2017-04-24 11:54:05 +00:00
|
|
|
/// The value is valid only if evm_result::code is ::EVM_SUCCESS
|
|
|
|
/// or ::EVM_REVERT. In other cases all provided gas is assumed to have been
|
|
|
|
/// used.
|
2016-07-04 22:54:51 +00:00
|
|
|
int64_t gas_left;
|
|
|
|
|
2017-04-24 11:54:05 +00:00
|
|
|
/// The reference to output data.
|
|
|
|
///
|
|
|
|
/// The output contains data coming from RETURN opcode (iff evm_result::code
|
|
|
|
/// field is ::EVM_SUCCESS) or from REVERT opcode (iff evm_result::code
|
2017-04-24 16:23:19 +00:00
|
|
|
/// field is ::EVM_REVERT).
|
|
|
|
///
|
|
|
|
/// In case the evm_result::code field signals
|
|
|
|
/// a failure the output MAY contain optional explanation of the failure
|
|
|
|
/// for debugging or tracing purposes. In case the explanation is provided
|
2017-04-25 15:02:49 +00:00
|
|
|
/// and contains human-readable text then UTF-8 encoding SHOULD be used.
|
2017-04-24 11:54:05 +00:00
|
|
|
///
|
|
|
|
/// The memory containing the output data is owned by EVM and has to be
|
|
|
|
/// freed with evm_result::release().
|
2016-12-20 14:28:43 +00:00
|
|
|
uint8_t const* output_data;
|
|
|
|
|
|
|
|
/// The size of the output data.
|
|
|
|
size_t output_size;
|
2016-07-20 12:15:04 +00:00
|
|
|
|
2017-04-25 17:05:49 +00:00
|
|
|
/// The pointer to a function releasing all resources associated with
|
|
|
|
/// the result object.
|
2016-09-28 11:19:02 +00:00
|
|
|
///
|
2017-04-25 17:05:49 +00:00
|
|
|
/// This function pointer is optional (MAY be NULL) and MAY be set by
|
|
|
|
/// the EVM implementation. If set it MUST be used by the user to
|
|
|
|
/// release memory and other resources associated with the result object.
|
|
|
|
/// After the result resources are released the result object
|
|
|
|
/// MUST NOT be used any more.
|
|
|
|
///
|
|
|
|
/// The suggested code pattern for releasing EVM results:
|
|
|
|
/// @code
|
|
|
|
/// struct evm_result result = ...;
|
|
|
|
/// if (result.release)
|
|
|
|
/// result.release(&result);
|
|
|
|
/// @endcode
|
2017-04-24 16:10:30 +00:00
|
|
|
///
|
|
|
|
/// @note
|
|
|
|
/// It works similarly to C++ virtual destructor. Attaching the release
|
|
|
|
/// function to the result itself allows EVM composition.
|
2016-09-28 11:19:02 +00:00
|
|
|
evm_release_result_fn release;
|
2016-07-04 22:54:51 +00:00
|
|
|
|
2017-04-25 17:05:49 +00:00
|
|
|
/// The optional pointer to an internal EVM context.
|
|
|
|
///
|
|
|
|
/// This field MAY be used by _EVM implementations_ to store additional
|
|
|
|
/// result context (e.g. memory buffers). The pointer value MUST NOT
|
|
|
|
/// be accessed nor changed by EVM users.
|
|
|
|
void* context;
|
2016-06-24 09:35:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// The query callback key.
|
|
|
|
enum evm_query_key {
|
2016-07-29 09:25:40 +00:00
|
|
|
EVM_SLOAD = 0, ///< Storage value of a given key for SLOAD.
|
2016-12-06 12:47:57 +00:00
|
|
|
EVM_CODE_BY_ADDRESS = 10, ///< Code by an address for EXTCODECOPY.
|
|
|
|
EVM_CODE_SIZE = 11, ///< Code size by an address for EXTCODESIZE.
|
|
|
|
EVM_BALANCE = 12, ///< Balance of a given address for BALANCE.
|
|
|
|
EVM_ACCOUNT_EXISTS = 14, ///< Check if an account exists.
|
2016-06-24 09:35:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Variant type to represent possible types of values used in EVM.
|
|
|
|
///
|
|
|
|
/// Type-safety is lost around the code that uses this type. We should have
|
|
|
|
/// complete set of unit tests covering all possible cases.
|
|
|
|
/// The size of the type is 64 bytes and should fit in single cache line.
|
|
|
|
union evm_variant {
|
|
|
|
/// A host-endian 64-bit integer.
|
|
|
|
int64_t int64;
|
|
|
|
|
2016-08-31 09:40:02 +00:00
|
|
|
/// A big-endian 256-bit integer or hash.
|
|
|
|
struct evm_uint256be uint256be;
|
2016-06-28 09:05:15 +00:00
|
|
|
|
2016-06-24 09:35:33 +00:00
|
|
|
struct {
|
|
|
|
/// Additional padding to align the evm_variant::address with lower
|
|
|
|
/// bytes of a full 256-bit hash.
|
2016-07-26 12:00:59 +00:00
|
|
|
uint8_t address_padding[12];
|
2016-06-24 09:35:33 +00:00
|
|
|
|
|
|
|
/// An Ethereum address.
|
2016-08-31 09:40:02 +00:00
|
|
|
struct evm_uint160be address;
|
2016-06-24 09:35:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// A memory reference.
|
2016-07-20 12:15:04 +00:00
|
|
|
struct {
|
|
|
|
/// Pointer to the data.
|
2016-07-26 12:00:59 +00:00
|
|
|
uint8_t const* data;
|
2016-07-20 12:15:04 +00:00
|
|
|
|
|
|
|
/// Size of the referenced memory/data.
|
|
|
|
size_t data_size;
|
|
|
|
};
|
2016-06-24 09:35:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Query callback function.
|
|
|
|
///
|
|
|
|
/// This callback function is used by the EVM to query the host application
|
|
|
|
/// about additional data required to execute EVM code.
|
|
|
|
/// @param env Pointer to execution environment managed by the host
|
2016-07-14 14:06:41 +00:00
|
|
|
/// application.
|
2016-06-24 09:35:33 +00:00
|
|
|
/// @param key The kind of the query. See evm_query_key and details below.
|
|
|
|
/// @param arg Additional argument to the query. It has defined value only for
|
|
|
|
/// the subset of query keys.
|
|
|
|
///
|
|
|
|
/// ## Types of queries
|
2016-09-01 02:18:11 +00:00
|
|
|
///
|
|
|
|
/// - ::EVM_GAS_PRICE
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::uint256be The transaction gas price.
|
|
|
|
///
|
|
|
|
/// - ::EVM_ADDRESS
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::address The address of the current contract.
|
|
|
|
///
|
|
|
|
/// - ::EVM_CALLER
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::address The address of the caller.
|
|
|
|
///
|
|
|
|
/// - ::EVM_ORIGIN
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::address The address of the transaction initiator.
|
|
|
|
///
|
|
|
|
/// - ::EVM_COINBASE
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::address The address of the beneficiary of the block fees.
|
|
|
|
///
|
|
|
|
/// - ::EVM_DIFFICULTY
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::uint256be The block difficulty.
|
|
|
|
///
|
|
|
|
/// - ::EVM_GAS_LIMIT
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::uint256be The block gas limit.
|
|
|
|
///
|
|
|
|
/// - ::EVM_NUMBER
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::int64 The block number.
|
|
|
|
///
|
|
|
|
/// - ::EVM_TIMESTAMP
|
|
|
|
/// @param arg n/a
|
|
|
|
/// @result evm_variant::int64 The block timestamp.
|
|
|
|
///
|
|
|
|
/// - ::EVM_CODE_BY_ADDRESS
|
|
|
|
/// @param arg evm_variant::address The address to look up.
|
|
|
|
/// @result evm_variant::data The appropriate code for the given address or NULL if not found.
|
|
|
|
///
|
2016-12-06 12:47:57 +00:00
|
|
|
/// - ::EVM_CODE_SIZE
|
|
|
|
/// @param arg evm_variant::address The address to look up.
|
|
|
|
/// @result evm_variant::data The appropriate code size for the given address or 0 if not found.
|
|
|
|
///
|
2016-09-01 02:18:11 +00:00
|
|
|
/// - ::EVM_BALANCE
|
|
|
|
/// @param arg evm_variant::address The address to look up.
|
|
|
|
/// @result evm_variant::data The appropriate balance for the given address or 0 if not found.
|
|
|
|
///
|
|
|
|
/// - ::EVM_BLOCKHASH
|
|
|
|
/// @param arg evm_variant::int64 The block number to look up.
|
|
|
|
/// @result evm_variant::uint256be The hash of the requested block or 0 if not found.
|
|
|
|
///
|
|
|
|
/// - ::EVM_SLOAD
|
|
|
|
/// @param arg evm_variant::uint256be The index of the storage entry.
|
|
|
|
/// @result evm_variant::uint256be The current value of the storage entry.
|
|
|
|
///
|
2017-01-20 12:38:11 +00:00
|
|
|
typedef void (*evm_query_state_fn)(union evm_variant* result,
|
|
|
|
struct evm_env* env,
|
|
|
|
enum evm_query_key key,
|
|
|
|
const struct evm_uint160be* address,
|
|
|
|
const struct evm_uint256be* storage_key);
|
2016-06-24 09:35:33 +00:00
|
|
|
|
2016-07-29 09:25:40 +00:00
|
|
|
/// The update callback key.
|
2016-07-04 22:03:25 +00:00
|
|
|
enum evm_update_key {
|
2016-07-29 09:25:40 +00:00
|
|
|
EVM_SSTORE = 0, ///< Update storage entry
|
|
|
|
EVM_LOG = 1, ///< Log.
|
|
|
|
EVM_SELFDESTRUCT = 2, ///< Mark contract as selfdestructed and set
|
|
|
|
/// beneficiary address.
|
2016-07-04 22:03:25 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-08-21 18:08:42 +00:00
|
|
|
/// Update callback function.
|
|
|
|
///
|
|
|
|
/// This callback function is used by the EVM to modify contract state in the
|
|
|
|
/// host application.
|
|
|
|
/// @param env Pointer to execution environment managed by the host
|
|
|
|
/// application.
|
|
|
|
/// @param key The kind of the update. See evm_update_key and details below.
|
|
|
|
///
|
2016-08-29 07:30:19 +00:00
|
|
|
/// ## Kinds of updates
|
|
|
|
///
|
|
|
|
/// - ::EVM_SSTORE
|
2016-08-31 09:40:02 +00:00
|
|
|
/// @param arg1 evm_variant::uint256be The index of the storage entry.
|
|
|
|
/// @param arg2 evm_variant::uint256be The value to be stored.
|
2016-08-29 07:30:19 +00:00
|
|
|
///
|
|
|
|
/// - ::EVM_LOG
|
|
|
|
/// @param arg1 evm_variant::data The log unindexed data.
|
|
|
|
/// @param arg2 evm_variant::data The log topics. The referenced data is an
|
2016-08-31 09:40:02 +00:00
|
|
|
/// array of evm_uint256be[] of possible length
|
2016-08-29 07:30:19 +00:00
|
|
|
/// from 0 to 4. So the valid
|
|
|
|
/// evm_variant::data_size values are 0, 32, 64
|
|
|
|
/// 92 and 128.
|
|
|
|
///
|
|
|
|
/// - ::EVM_SELFDESTRUCT
|
|
|
|
/// @param arg1 evm_variant::address The beneficiary address.
|
2016-09-01 02:08:24 +00:00
|
|
|
/// @param arg2 n/a
|
2017-01-20 13:02:35 +00:00
|
|
|
typedef void (*evm_update_state_fn)(struct evm_env* env,
|
|
|
|
enum evm_update_key key,
|
|
|
|
const struct evm_uint160be* address,
|
|
|
|
const union evm_variant* arg1,
|
|
|
|
const union evm_variant* arg2);
|
2016-06-24 09:35:33 +00:00
|
|
|
|
|
|
|
/// The kind of call-like instruction.
|
|
|
|
enum evm_call_kind {
|
2016-07-29 09:25:40 +00:00
|
|
|
EVM_CALL = 0, ///< Request CALL.
|
|
|
|
EVM_DELEGATECALL = 1, ///< Request DELEGATECALL. The value param ignored.
|
|
|
|
EVM_CALLCODE = 2, ///< Request CALLCODE.
|
|
|
|
EVM_CREATE = 3 ///< Request CREATE. Semantic of some params changes.
|
2016-06-24 09:35:33 +00:00
|
|
|
};
|
|
|
|
|
2017-01-09 22:50:14 +00:00
|
|
|
/// The flag indicating call failure in evm_call_fn() -- highest bit set.
|
|
|
|
static const int64_t EVM_CALL_FAILURE = 0x8000000000000000;
|
2016-08-23 22:08:35 +00:00
|
|
|
|
2016-06-24 09:35:33 +00:00
|
|
|
/// Pointer to the callback function supporting EVM calls.
|
|
|
|
///
|
2016-07-14 14:06:41 +00:00
|
|
|
/// @param env Pointer to execution environment managed by the host
|
|
|
|
/// application.
|
2016-06-24 09:35:33 +00:00
|
|
|
/// @param kind The kind of call-like opcode requested.
|
|
|
|
/// @param gas The amount of gas for the call.
|
|
|
|
/// @param address The address of a contract to be called. Ignored in case
|
|
|
|
/// of CREATE.
|
|
|
|
/// @param value The value sent to the callee. The endowment in case of
|
|
|
|
/// CREATE.
|
2016-08-22 17:25:13 +00:00
|
|
|
/// @param input The call input data or the CREATE init code.
|
2016-07-20 12:15:04 +00:00
|
|
|
/// @param input_size The size of the input data.
|
|
|
|
/// @param output The reference to the memory where the call output is to
|
2016-08-22 17:25:13 +00:00
|
|
|
/// be copied. In case of CREATE, the memory is guaranteed
|
2016-08-22 17:25:35 +00:00
|
|
|
/// to be at least 20 bytes to hold the address of the
|
2016-06-24 09:35:33 +00:00
|
|
|
/// created contract.
|
2016-08-22 17:25:13 +00:00
|
|
|
/// @param output_data The size of the output data. In case of CREATE, expected
|
2016-08-22 17:25:35 +00:00
|
|
|
/// value is 20.
|
2016-06-24 09:35:33 +00:00
|
|
|
/// @return If non-negative - the amount of gas left,
|
|
|
|
/// If negative - an exception occurred during the call/create.
|
|
|
|
/// There is no need to set 0 address in the output in this case.
|
|
|
|
typedef int64_t (*evm_call_fn)(
|
2016-07-14 14:06:41 +00:00
|
|
|
struct evm_env* env,
|
2016-06-24 09:35:33 +00:00
|
|
|
enum evm_call_kind kind,
|
|
|
|
int64_t gas,
|
2016-12-22 11:10:31 +00:00
|
|
|
const struct evm_uint160be* address,
|
|
|
|
const struct evm_uint256be* value,
|
2016-07-26 12:00:59 +00:00
|
|
|
uint8_t const* input,
|
2016-07-20 12:15:04 +00:00
|
|
|
size_t input_size,
|
2016-07-26 12:00:59 +00:00
|
|
|
uint8_t* output,
|
2016-07-20 12:15:04 +00:00
|
|
|
size_t output_size);
|
2016-06-24 09:35:33 +00:00
|
|
|
|
|
|
|
|
2016-12-20 15:50:23 +00:00
|
|
|
struct evm_instance; ///< Forward declaration.
|
2016-06-24 09:35:33 +00:00
|
|
|
|
2016-12-20 15:50:23 +00:00
|
|
|
/// Creates the EVM instance.
|
2016-06-24 09:35:33 +00:00
|
|
|
///
|
2016-12-20 15:50:23 +00:00
|
|
|
/// Creates and initializes an EVM instance by providing the information
|
|
|
|
/// about runtime callback functions.
|
2016-06-24 09:35:33 +00:00
|
|
|
///
|
2016-07-04 22:03:25 +00:00
|
|
|
/// @param query_fn Pointer to query callback function. Nonnull.
|
|
|
|
/// @param update_fn Pointer to update callback function. Nonnull.
|
|
|
|
/// @param call_fn Pointer to call callback function. Nonnull.
|
|
|
|
/// @return Pointer to the created EVM instance.
|
2017-01-20 12:38:11 +00:00
|
|
|
typedef struct evm_instance* (*evm_create_fn)(evm_query_state_fn query_fn,
|
2017-01-20 13:02:35 +00:00
|
|
|
evm_update_state_fn update_fn,
|
2017-01-18 21:58:30 +00:00
|
|
|
evm_call_fn call_fn,
|
2017-01-19 21:39:21 +00:00
|
|
|
evm_get_tx_context_fn,
|
|
|
|
evm_get_block_hash_fn);
|
2016-06-24 09:35:33 +00:00
|
|
|
|
|
|
|
/// Destroys the EVM instance.
|
|
|
|
///
|
|
|
|
/// @param evm The EVM instance to be destroyed.
|
2016-08-23 10:09:39 +00:00
|
|
|
typedef void (*evm_destroy_fn)(struct evm_instance* evm);
|
2016-06-24 09:35:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
/// Configures the EVM instance.
|
|
|
|
///
|
|
|
|
/// Allows modifying options of the EVM instance.
|
|
|
|
/// Options:
|
|
|
|
/// - code cache behavior: on, off, read-only, ...
|
|
|
|
/// - optimizations,
|
|
|
|
///
|
|
|
|
/// @param evm The EVM instance to be configured.
|
2016-08-31 09:58:19 +00:00
|
|
|
/// @param name The option name. NULL-terminated string. Cannot be NULL.
|
|
|
|
/// @param value The new option value. NULL-terminated string. Cannot be NULL.
|
2016-08-23 09:55:06 +00:00
|
|
|
/// @return 1 if the option set successfully, 0 otherwise.
|
2016-08-23 10:09:39 +00:00
|
|
|
typedef int (*evm_set_option_fn)(struct evm_instance* evm,
|
|
|
|
char const* name,
|
|
|
|
char const* value);
|
2016-06-24 09:35:33 +00:00
|
|
|
|
|
|
|
|
2016-07-28 10:45:01 +00:00
|
|
|
/// EVM compatibility mode aka chain mode.
|
2016-11-22 16:39:15 +00:00
|
|
|
/// The names for the last two hard forks come from Python implementation.
|
2016-07-28 10:45:01 +00:00
|
|
|
enum evm_mode {
|
2016-07-29 09:25:40 +00:00
|
|
|
EVM_FRONTIER = 0,
|
2016-11-22 16:39:15 +00:00
|
|
|
EVM_HOMESTEAD = 1,
|
|
|
|
EVM_ANTI_DOS = 2,
|
2017-04-03 14:13:18 +00:00
|
|
|
EVM_CLEARING = 3,
|
|
|
|
EVM_METROPOLIS = 4,
|
2016-07-28 10:45:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2016-06-24 09:35:33 +00:00
|
|
|
/// Generates and executes machine code for given EVM bytecode.
|
|
|
|
///
|
|
|
|
/// All the fun is here. This function actually does something useful.
|
|
|
|
///
|
|
|
|
/// @param instance A EVM instance.
|
|
|
|
/// @param env A pointer to the execution environment provided by the
|
|
|
|
/// user and passed to callback functions.
|
2016-07-28 10:45:01 +00:00
|
|
|
/// @param mode EVM compatibility mode.
|
2016-06-24 09:35:33 +00:00
|
|
|
/// @param code_hash A hash of the bytecode, usually Keccak. The EVM uses it
|
|
|
|
/// as the code identifier. A EVM implementation is able to
|
|
|
|
/// hash the code itself if it requires it, but the host
|
|
|
|
/// application usually has the hash already.
|
|
|
|
/// @param code Reference to the bytecode to be executed.
|
2016-07-20 12:15:04 +00:00
|
|
|
/// @param code_size The length of the bytecode.
|
2016-06-24 09:35:33 +00:00
|
|
|
/// @param gas Gas for execution. Min 0, max 2^63-1.
|
2016-07-20 12:15:04 +00:00
|
|
|
/// @param input Reference to the input data.
|
|
|
|
/// @param input_size The size of the input data.
|
2016-06-24 09:35:33 +00:00
|
|
|
/// @param value Call value.
|
|
|
|
/// @return All execution results.
|
2016-08-23 10:09:39 +00:00
|
|
|
typedef struct evm_result (*evm_execute_fn)(struct evm_instance* instance,
|
|
|
|
struct evm_env* env,
|
|
|
|
enum evm_mode mode,
|
2016-08-31 09:40:02 +00:00
|
|
|
struct evm_uint256be code_hash,
|
2016-08-23 10:09:39 +00:00
|
|
|
uint8_t const* code,
|
|
|
|
size_t code_size,
|
2017-01-12 15:45:14 +00:00
|
|
|
struct evm_message message);
|
2016-06-24 09:35:33 +00:00
|
|
|
|
|
|
|
|
2016-08-22 20:18:42 +00:00
|
|
|
/// Status of a code in VM. Useful for JIT-like implementations.
|
|
|
|
enum evm_code_status {
|
|
|
|
/// The code is uknown to the VM.
|
|
|
|
EVM_UNKNOWN,
|
2016-06-24 09:35:33 +00:00
|
|
|
|
2016-08-22 20:18:42 +00:00
|
|
|
/// The code has been compiled and is available in memory.
|
|
|
|
EVM_READY,
|
2016-07-26 09:17:02 +00:00
|
|
|
|
2016-08-22 20:18:42 +00:00
|
|
|
/// The compiled version of the code is available in on-disk cache.
|
|
|
|
EVM_CACHED,
|
|
|
|
};
|
2016-07-26 09:17:02 +00:00
|
|
|
|
2016-08-21 18:07:35 +00:00
|
|
|
|
2016-08-22 20:18:42 +00:00
|
|
|
/// Get information the status of the code in the VM.
|
2016-08-23 10:09:39 +00:00
|
|
|
typedef enum evm_code_status
|
|
|
|
(*evm_get_code_status_fn)(struct evm_instance* instance,
|
|
|
|
enum evm_mode mode,
|
2016-08-31 09:40:02 +00:00
|
|
|
struct evm_uint256be code_hash);
|
2016-07-26 09:17:02 +00:00
|
|
|
|
2016-08-22 20:18:42 +00:00
|
|
|
/// Request preparation of the code for faster execution. It is not required
|
|
|
|
/// to execute the code but allows compilation of the code ahead of time in
|
|
|
|
/// JIT-like VMs.
|
2016-08-23 10:09:39 +00:00
|
|
|
typedef void (*evm_prepare_code_fn)(struct evm_instance* instance,
|
|
|
|
enum evm_mode mode,
|
2016-08-31 09:40:02 +00:00
|
|
|
struct evm_uint256be code_hash,
|
2016-08-23 10:09:39 +00:00
|
|
|
uint8_t const* code,
|
2016-08-28 14:00:04 +00:00
|
|
|
size_t code_size);
|
2016-08-23 10:09:39 +00:00
|
|
|
|
2016-12-20 15:50:23 +00:00
|
|
|
/// The EVM instance.
|
2016-08-23 11:50:25 +00:00
|
|
|
///
|
2016-12-20 15:50:23 +00:00
|
|
|
/// Defines the base struct of the EVM implementation.
|
|
|
|
struct evm_instance {
|
|
|
|
/// Pointer to function destroying the EVM instance.
|
2016-08-23 10:09:39 +00:00
|
|
|
evm_destroy_fn destroy;
|
2016-08-23 11:50:25 +00:00
|
|
|
|
2016-12-20 15:50:23 +00:00
|
|
|
/// Pointer to function executing a code by the EVM instance.
|
2016-08-23 10:09:39 +00:00
|
|
|
evm_execute_fn execute;
|
2016-08-23 11:50:25 +00:00
|
|
|
|
|
|
|
/// Optional pointer to function returning a status of a code.
|
|
|
|
///
|
|
|
|
/// If the VM does not support this feature the pointer can be NULL.
|
2016-08-23 10:09:39 +00:00
|
|
|
evm_get_code_status_fn get_code_status;
|
|
|
|
|
2016-08-23 11:50:25 +00:00
|
|
|
/// Optional pointer to function compiling a code.
|
|
|
|
///
|
|
|
|
/// If the VM does not support this feature the pointer can be NULL.
|
2016-08-23 10:09:39 +00:00
|
|
|
evm_prepare_code_fn prepare_code;
|
|
|
|
|
2016-08-23 11:50:25 +00:00
|
|
|
/// Optional pointer to function modifying VM's options.
|
|
|
|
///
|
|
|
|
/// If the VM does not support this feature the pointer can be NULL.
|
2016-08-23 10:09:39 +00:00
|
|
|
evm_set_option_fn set_option;
|
|
|
|
};
|
|
|
|
|
2016-12-20 15:50:23 +00:00
|
|
|
/// The EVM instance factory.
|
|
|
|
///
|
|
|
|
/// Provides ABI protection and method to create an EVM instance.
|
|
|
|
struct evm_factory {
|
|
|
|
/// EVM-C ABI version implemented by the EVM factory and instance.
|
|
|
|
///
|
|
|
|
/// For future use to detect ABI incompatibilities. The EVM-C ABI version
|
|
|
|
/// represented by this file is in ::EVM_ABI_VERSION.
|
2016-12-22 15:52:21 +00:00
|
|
|
int abi_version;
|
2016-12-20 15:50:23 +00:00
|
|
|
|
|
|
|
/// Pointer to function creating and initializing the EVM instance.
|
|
|
|
evm_create_fn create;
|
|
|
|
};
|
|
|
|
|
2016-08-31 10:01:28 +00:00
|
|
|
// END Python CFFI declarations
|
|
|
|
|
2016-12-20 15:50:23 +00:00
|
|
|
/// Example of a function creating uninitialized instance of an example VM.
|
2016-08-23 11:50:25 +00:00
|
|
|
///
|
2016-12-20 15:50:23 +00:00
|
|
|
/// Each EVM implementation is obligated to provided a function returning
|
|
|
|
/// an EVM instance.
|
|
|
|
/// The function has to be named as `<vm-name>_get_factory(void)`.
|
2016-08-23 11:50:25 +00:00
|
|
|
///
|
2016-12-20 15:50:23 +00:00
|
|
|
/// @return EVM instance.
|
|
|
|
struct evm_factory examplevm_get_factory(void);
|
2016-08-23 10:58:09 +00:00
|
|
|
|
|
|
|
|
2016-06-24 09:35:33 +00:00
|
|
|
#if __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
2016-08-23 18:04:08 +00:00
|
|
|
|
|
|
|
#endif // EVM_H
|
2016-06-24 09:35:33 +00:00
|
|
|
/// @}
|