I am experimenting with evmone and evmc to execute some simple assembly code snippets on EVM. I wrote a test that is supposed to return 0x42
as output data. The code goes as follows:
PUSH 0x42
PUSH 0x70
MSTORE
PUSH 0x01
PUSH 0x70
RETURN
However, this code returns 0
, which I don't understand. I did some more scanning of the memory laying around and I found that if I fix the lookup position to 0x8f
then it returns 0x42
as expected:
PUSH 0x42
PUSH 0x70
MSTORE
PUSH 0x01
PUSH 0x8f
RETURN
What is going on here?
My testing code:
#include <evmc/evmc.hpp>
#include <evmc/loader.h>
#include <evmone/evmone.h>
#include <iostream>
#include <vector>
const evmc_revision REVISION = EVMC_SHANGHAI;
uint8_t parse_byte(char c) {
if(c >= 'a' && c <= 'f') {
return c - 'a' + 10;
}
if(c >= 'A' && c <= 'F') {
return c - 'A' + 10;
}
return c - '0';
}
std::vector<uint8_t> parse_bytes(std::string in) {
std::vector<uint8_t> out;
for(int i = 0; i + 1 < in.size(); i += 2) {
uint8_t x = parse_byte(in[i]) * 0x10 + parse_byte(in[i + 1]);
out.push_back(x);
}
return out;
}
int main(int argc, char** argv) {
std::vector<uint8_t> code = parse_bytes("60426070526001608ff3"); // EVM code in hex
auto vm = evmc::VM{evmc_create_evmone()};
auto msg = evmc_message{};
auto dst = evmc_address{};
dst.bytes[19] = 0xaa;
auto val = evmc_uint256be{};
msg.kind = EVMC_CALL;
msg.flags = int32_t{EVMC_STATIC};
msg.recipient = dst;
msg.code_address = dst;
msg.sender = dst;
msg.value = val;
msg.gas = 10000;
auto res = vm.execute(REVISION, msg, code.data(), code.size());
std::cout << "OUTPUT: ";
for(int i = 0; i < res.output_size; ++i) {
std::cout << std::hex << int(res.output_data[i]);
}
std::cout << std::endl;
}