EVM-C: Replace evm_{uint|hash}256 with single evm_uint256be

All values transfered to/from a VM must be passed as big-endian integers.
This commit is contained in:
Paweł Bylica 2016-08-31 11:40:02 +02:00
parent 50c49b0b9d
commit 2a99b13573
3 changed files with 42 additions and 55 deletions

View File

@ -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 =

View File

@ -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;

View File

@ -25,36 +25,26 @@ extern "C" {
/// 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];
};
/// Big-endian 160-bit hash suitable for keeping an Ethereum address.
struct evm_hash160 {
/// 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.
/// 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.
///
/// The memory is expected be aligned to 8 bytes, but there is no portable
/// way to express that.
uint8_t bytes[32];
};
/// Big-endian 160-bit hash suitable for keeping an Ethereum address.
struct evm_uint160be {
/// The 20 bytes of the hash.
uint8_t bytes[20];
};
/// The execution result code.
enum evm_result_code {
EVM_SUCCESS = 0, ///< Execution finished with success.
@ -128,11 +118,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 +127,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 +153,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 +190,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 +244,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,
@ -335,13 +322,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 +357,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);