diff --git a/examples/capi.c b/examples/capi.c index 5fdb11a..cb66ee0 100644 --- a/examples/capi.c +++ b/examples/capi.c @@ -4,15 +4,15 @@ #include "evm.h" -struct evm_uint256 balance(struct evm_env* env, struct evm_hash160 address) +struct evm_uint256be balance(struct evm_env* env, struct evm_uint160be address) { - struct evm_uint256 ret = { .words = { 1 } }; + struct evm_uint256be ret = {.bytes = {1, 2, 3, 4}}; return ret; } -struct evm_hash160 address(struct evm_env* env) +struct evm_uint160be address(struct evm_env* env) { - struct evm_hash160 ret = { .bytes = { 1, 2, 3, 4 } }; + struct evm_uint160be ret = {.bytes = {1, 2, 3, 4}}; return ret; } @@ -25,7 +25,7 @@ union evm_variant query(struct evm_env* env, case EVM_GAS_LIMIT: result.int64 = 314; break; case EVM_BALANCE: - result.uint256 = balance(env, arg.address); + result.uint256be = balance(env, arg.address); break; case EVM_ADDRESS: @@ -49,8 +49,8 @@ int64_t call( struct evm_env* _opaqueEnv, enum evm_call_kind _kind, int64_t _gas, - struct evm_hash160 _address, - struct evm_uint256 _value, + struct evm_uint160be _address, + struct evm_uint256be _value, uint8_t const* _inputData, size_t _inputSize, uint8_t* _outputData, @@ -68,9 +68,9 @@ int main(int argc, char *argv[]) { char const code[] = "exec()"; const size_t code_size = sizeof(code); - struct evm_hash256 code_hash = {.bytes = {1, 2, 3,}}; + struct evm_uint256be code_hash = {.bytes = {1, 2, 3,}}; char const input[] = "Hello World!"; - struct evm_uint256 value = {{1, 0, 0, 0}}; + struct evm_uint256be value = {{1, 0, 0, 0}}; int64_t gas = 200000; struct evm_result result = diff --git a/examples/examplevm.c b/examples/examplevm.c index f329149..4569fa4 100644 --- a/examples/examplevm.c +++ b/examples/examplevm.c @@ -43,13 +43,13 @@ int evm_set_option(struct evm_instance* evm, static struct evm_result evm_execute(struct evm_instance* instance, struct evm_env* env, enum evm_mode mode, - struct evm_hash256 code_hash, + struct evm_uint256be code_hash, uint8_t const* code, size_t code_size, int64_t gas, uint8_t const* input, size_t input_size, - struct evm_uint256 value) + struct evm_uint256be value) { struct evm_result ret; diff --git a/include/evm.h b/include/evm.h index 6bd0f13..3f99bd4 100644 --- a/include/evm.h +++ b/include/evm.h @@ -22,39 +22,28 @@ extern "C" { #endif +// BEGIN Python CFFI declarations + /// The EVM-C ABI version number matching the interface declared in this file. static const uint32_t EVM_ABI_VERSION = 0; -/// Host-endian 256-bit integer. +/// Big-endian 256-bit integer. /// -/// 32 bytes of data representing host-endian (that means little-endian almost -/// all the time) 256-bit integer. This applies to the words[] order as well. -/// words[0] contains the 64 lowest precision bits, words[3] constains the 64 -/// highest precision bits. -struct evm_uint256 { - /// The 4 64-bit words of the integer. Memory aligned to 8 bytes. - uint64_t words[4]; +/// 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]; }; /// Big-endian 160-bit hash suitable for keeping an Ethereum address. -struct evm_hash160 { +struct evm_uint160be { /// The 20 bytes of the hash. uint8_t bytes[20]; }; - -/// Big-endian 256-bit integer/hash. -/// -/// 32 bytes of data. For EVM that means big-endian 256-bit integer. Values of -/// this type are converted to host-endian values inside EVM. -struct evm_hash256 { - /// The 32 bytes of the integer/hash. - /// - /// The memory is expected be aligned to 8 bytes, but there is no portable - /// way to express that. - uint8_t bytes[32]; -}; - /// The execution result code. enum evm_result_code { EVM_SUCCESS = 0, ///< Execution finished with success. @@ -128,11 +117,8 @@ union evm_variant { /// A host-endian 64-bit integer. int64_t int64; - /// A host-endian 256-bit integer. - struct evm_uint256 uint256; - - /// A big-endian 256-bit integer/hash. - struct evm_hash256 hash256; + /// A big-endian 256-bit integer or hash. + struct evm_uint256be uint256be; struct { /// Additional padding to align the evm_variant::address with lower @@ -140,7 +126,7 @@ union evm_variant { uint8_t address_padding[12]; /// An Ethereum address. - struct evm_hash160 address; + struct evm_uint160be address; }; /// A memory reference. @@ -166,19 +152,19 @@ union evm_variant { /// ## Types of queries /// Key | Arg | Expected result /// ----------------------| -------------------- | ---------------------------- -/// ::EVM_GAS_PRICE | | evm_variant::uint256 +/// ::EVM_GAS_PRICE | | evm_variant::uint256be /// ::EVM_ADDRESS | | evm_variant::address /// ::EVM_CALLER | | evm_variant::address /// ::EVM_ORIGIN | | evm_variant::address /// ::EVM_COINBASE | | evm_variant::address -/// ::EVM_DIFFICULTY | | evm_variant::uint256 -/// ::EVM_GAS_LIMIT | | evm_variant::uint256 +/// ::EVM_DIFFICULTY | | evm_variant::uint256be +/// ::EVM_GAS_LIMIT | | evm_variant::uint256be /// ::EVM_NUMBER | | evm_variant::int64? /// ::EVM_TIMESTAMP | | evm_variant::int64? /// ::EVM_CODE_BY_ADDRESS | evm_variant::address | evm_variant::data -/// ::EVM_BALANCE | evm_variant::address | evm_variant::uint256 -/// ::EVM_BLOCKHASH | evm_variant::int64 | evm_variant::hash256 -/// ::EVM_SLOAD | evm_variant::uint256 | evm_variant::uint256? +/// ::EVM_BALANCE | evm_variant::address | evm_variant::uint256be +/// ::EVM_BLOCKHASH | evm_variant::int64 | evm_variant::uint256be +/// ::EVM_SLOAD | evm_variant::uint256be | evm_variant::uint256be typedef union evm_variant (*evm_query_fn)(struct evm_env* env, enum evm_query_key key, union evm_variant arg); @@ -203,13 +189,13 @@ enum evm_update_key { /// ## Kinds of updates /// /// - ::EVM_SSTORE -/// @param arg1 evm_variant::uint256 The index of the storage entry. -/// @param arg2 evm_variant::uint256 The value to be stored. +/// @param arg1 evm_variant::uint256be The index of the storage entry. +/// @param arg2 evm_variant::uint256be The value to be stored. /// /// - ::EVM_LOG /// @param arg1 evm_variant::data The log unindexed data. /// @param arg2 evm_variant::data The log topics. The referenced data is an -/// array of evm_hash256[] of possible length +/// array of evm_uint256be[] of possible length /// from 0 to 4. So the valid /// evm_variant::data_size values are 0, 32, 64 /// 92 and 128. @@ -257,8 +243,8 @@ typedef int64_t (*evm_call_fn)( struct evm_env* env, enum evm_call_kind kind, int64_t gas, - struct evm_hash160 address, - struct evm_uint256 value, + struct evm_uint160be address, + struct evm_uint256be value, uint8_t const* input, size_t input_size, uint8_t* output, @@ -297,8 +283,8 @@ typedef void (*evm_destroy_fn)(struct evm_instance* evm); /// - optimizations, /// /// @param evm The EVM instance to be configured. -/// @param name The option name. Cannot be null. -/// @param value The new option value. Cannot be null. +/// @param name The option name. NULL-terminated string. Cannot be NULL. +/// @param value The new option value. NULL-terminated string. Cannot be NULL. /// @return 1 if the option set successfully, 0 otherwise. typedef int (*evm_set_option_fn)(struct evm_instance* evm, char const* name, @@ -335,13 +321,13 @@ enum evm_mode { typedef struct evm_result (*evm_execute_fn)(struct evm_instance* instance, struct evm_env* env, enum evm_mode mode, - struct evm_hash256 code_hash, + struct evm_uint256be code_hash, uint8_t const* code, size_t code_size, int64_t gas, uint8_t const* input, size_t input_size, - struct evm_uint256 value); + struct evm_uint256be value); /// Releases resources assigned to an execution result. /// @@ -370,14 +356,14 @@ enum evm_code_status { typedef enum evm_code_status (*evm_get_code_status_fn)(struct evm_instance* instance, enum evm_mode mode, - struct evm_hash256 code_hash); + struct evm_uint256be code_hash); /// 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. typedef void (*evm_prepare_code_fn)(struct evm_instance* instance, enum evm_mode mode, - struct evm_hash256 code_hash, + struct evm_uint256be code_hash, uint8_t const* code, size_t code_size); @@ -419,10 +405,13 @@ struct evm_interface { evm_set_option_fn set_option; }; +// END Python CFFI declarations + /// Example of a function exporting an interface for an example VM. /// /// Each VM implementation is obligates to provided a function returning -/// VM's interface. The function has to be named as `_get_interface()`. +/// VM's interface. +/// The function has to be named as `_get_interface(void)`. /// /// @return VM interface struct evm_interface examplevm_get_interface(void);