diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index f938d71..ee599ab 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,5 +1,6 @@ -add_library(example-capi STATIC EXCLUDE_FROM_ALL capi.c) -target_include_directories(example-capi PRIVATE ../include) - add_library(example-vm STATIC EXCLUDE_FROM_ALL examplevm.c) target_include_directories(example-vm PRIVATE ../include) + +add_executable(example-capi EXCLUDE_FROM_ALL capi.c) +target_include_directories(example-capi PRIVATE ../include) +target_link_libraries(example-capi PRIVATE example-vm) diff --git a/examples/capi.c b/examples/capi.c index cd16381..01b8d3e 100644 --- a/examples/capi.c +++ b/examples/capi.c @@ -1,11 +1,25 @@ +#include +#include +#include #include "evm.h" -struct evm_uint256 balance(struct evm_env*, struct evm_hash160 address); +struct evm_uint256 balance(struct evm_env* env, struct evm_hash160 address) +{ + struct evm_uint256 ret = { .words = { 1 } }; + return ret; +} + +struct evm_hash160 address(struct evm_env* env) +{ + struct evm_hash160 ret = { .bytes = { 1, 2, 3, 4 } }; + return ret; +} union evm_variant query(struct evm_env* env, enum evm_query_key key, union evm_variant arg) { union evm_variant result; + printf("EVM-C: QUERY %d\n", key); switch (key) { case EVM_GAS_LIMIT: result.int64 = 314; break; @@ -13,25 +27,70 @@ union evm_variant query(struct evm_env* env, result.uint256 = balance(env, arg.address); break; + case EVM_ADDRESS: + result.address = address(env); + break; + default: result.int64 = 0; break; } return result; } +void update(struct evm_env* env, + enum evm_update_key key, + union evm_variant arg1, + union evm_variant arg2) +{ + printf("EVM-C: UPDATE %d\n", key); +} + +int64_t call( + struct evm_env* _opaqueEnv, + enum evm_call_kind _kind, + int64_t _gas, + struct evm_hash160 _address, + struct evm_uint256 _value, + uint8_t const* _inputData, + size_t _inputSize, + uint8_t* _outputData, + size_t _outputSize +) +{ + printf("EVM-C: CALL %d\n", _kind); + return EVM_EXCEPTION; +} + /// Example how the API is supposed to be used. -void example() { - struct evm_instance* jit = evm_create(query, 0, 0); +int main(int argc, char *argv[]) { + printf("Using VM: %s (%s)\n", evm_get_info(EVM_NAME), evm_get_info(EVM_VERSION)); + + struct evm_instance* jit = evm_create(query, update, call); char const code[] = "exec()"; + const size_t code_size = sizeof(code); struct evm_hash256 code_hash = {.words = {1, 2, 3}}; char const input[] = "Hello World!"; struct evm_uint256 value = {{1, 0, 0, 0}}; int64_t gas = 200000; struct evm_result result = - evm_execute(jit, NULL, code_hash, code, sizeof(code), gas, input, + evm_execute(jit, NULL, EVM_HOMESTEAD, code_hash, (const uint8_t *)code, code_size, gas, (const uint8_t *)input, sizeof(input), value); + printf("Execution result:\n"); + if (result.gas_left & EVM_EXCEPTION) { + printf(" EVM eception\n"); + } + printf(" Gas used: %lld\n", gas - result.gas_left); + printf(" Gas left: %lld\n", result.gas_left); + printf(" Output size: %zd\n", result.output_size); + + printf(" Output: "); + for (int i = 0; i < result.output_size; i++) { + printf("%02x ", result.output_data[i]); + } + printf("\n"); + evm_destroy_result(result); evm_destroy(jit); }