20 #include <evmc/helpers.h>
29 static_assert(
sizeof(
Address) ==
sizeof(evmc_address),
"Address types size mismatch");
30 static_assert(
alignof(
Address) ==
alignof(evmc_address),
"Address types alignment mismatch");
31 static_assert(
sizeof(
h256) ==
sizeof(evmc_uint256be),
"Hash types size mismatch");
32 static_assert(
alignof(
h256) ==
alignof(evmc_uint256be),
"Hash types alignment mismatch");
34 bool accountExists(evmc_context* _context, evmc_address
const* _addr) noexcept
36 auto& env =
static_cast<ExtVMFace&
>(*_context);
38 return env.exists(addr);
41 evmc_bytes32 getStorage(
42 evmc_context* _context, evmc_address
const* _addr, evmc_uint256be
const* _key) noexcept
45 auto& env =
static_cast<ExtVMFace&
>(*_context);
46 assert(
fromEvmC(*_addr) == env.myAddress);
48 return toEvmC(env.store(key));
51 evmc_storage_status setStorage(evmc_context* _context, evmc_address
const* _addr,
52 evmc_uint256be
const* _key, evmc_uint256be
const* _value) noexcept
55 auto& env =
static_cast<ExtVMFace&
>(*_context);
56 assert(
fromEvmC(*_addr) == env.myAddress);
59 u256 const currentValue = env.store(index);
61 if (newValue == currentValue)
62 return EVMC_STORAGE_UNCHANGED;
64 EVMSchedule
const& schedule = env.evmSchedule();
65 auto status = EVMC_STORAGE_MODIFIED;
66 u256 const originalValue = env.originalStorageValue(index);
67 if (originalValue == currentValue || !schedule.eip1283Mode)
69 if (currentValue == 0)
70 status = EVMC_STORAGE_ADDED;
71 else if (newValue == 0)
73 status = EVMC_STORAGE_DELETED;
74 env.sub.refunds += schedule.sstoreRefundGas;
79 status = EVMC_STORAGE_MODIFIED_AGAIN;
80 if (originalValue != 0)
82 if (currentValue == 0)
83 env.sub.refunds -= schedule.sstoreRefundGas;
85 env.sub.refunds += schedule.sstoreRefundGas;
87 if (originalValue == newValue)
89 if (originalValue == 0)
90 env.sub.refunds += schedule.sstoreRefundGas + schedule.sstoreRefundNonzeroGas;
92 env.sub.refunds += schedule.sstoreRefundNonzeroGas;
96 env.setStore(index, newValue);
101 evmc_uint256be getBalance(evmc_context* _context, evmc_address
const* _addr) noexcept
103 auto& env =
static_cast<ExtVMFace&
>(*_context);
107 size_t getCodeSize(evmc_context* _context, evmc_address
const* _addr)
109 auto& env =
static_cast<ExtVMFace&
>(*_context);
110 return env.codeSizeAt(
fromEvmC(*_addr));
113 evmc_bytes32 getCodeHash(evmc_context* _context, evmc_address
const* _addr)
115 auto& env =
static_cast<ExtVMFace&
>(*_context);
119 size_t copyCode(evmc_context* _context, evmc_address
const* _addr,
size_t _codeOffset,
120 byte* _bufferData,
size_t _bufferSize)
122 auto& env =
static_cast<ExtVMFace&
>(*_context);
124 bytes const& code = env.codeAt(addr);
127 if (_codeOffset >= code.size())
130 size_t maxToCopy = code.size() - _codeOffset;
131 size_t numToCopy = std::min(maxToCopy, _bufferSize);
132 std::copy_n(&code[_codeOffset], numToCopy, _bufferData);
137 evmc_context* _context,
138 evmc_address
const* _addr,
139 evmc_address
const* _beneficiary
143 auto& env =
static_cast<ExtVMFace&
>(*_context);
144 assert(
fromEvmC(*_addr) == env.myAddress);
145 env.suicide(
fromEvmC(*_beneficiary));
150 evmc_context* _context,
151 evmc_address
const* _addr,
152 uint8_t
const* _data,
154 evmc_uint256be
const _topics[],
159 auto& env =
static_cast<ExtVMFace&
>(*_context);
160 assert(
fromEvmC(*_addr) == env.myAddress);
161 h256 const* pTopics =
reinterpret_cast<h256 const*
>(_topics);
162 env.log(
h256s{pTopics, pTopics + _numTopics},
166 evmc_tx_context getTxContext(evmc_context* _context) noexcept
168 auto& env =
static_cast<ExtVMFace&
>(*_context);
169 evmc_tx_context result = {};
170 result.tx_gas_price =
toEvmC(env.gasPrice);
171 result.tx_origin =
toEvmC(env.origin);
172 result.block_coinbase =
toEvmC(env.envInfo().author());
173 result.block_number =
static_cast<int64_t
>(env.envInfo().number());
174 result.block_timestamp =
static_cast<int64_t
>(env.envInfo().timestamp());
175 result.block_gas_limit =
static_cast<int64_t
>(env.envInfo().gasLimit());
176 result.block_difficulty =
toEvmC(env.envInfo().difficulty());
180 evmc_bytes32 getBlockHash(evmc_context* _envPtr, int64_t _number)
182 auto& env =
static_cast<ExtVMFace&
>(*_envPtr);
183 return toEvmC(env.blockHash(_number));
186 evmc_result create(ExtVMFace& _env, evmc_message
const* _msg) noexcept
188 u256 gas = _msg->gas;
195 assert(
fromEvmC(_msg->sender) == _env.myAddress);
197 CreateResult result = _env.create(value, gas, init, opcode, salt, {});
198 evmc_result evmcResult = {};
199 evmcResult.status_code = result.status;
200 evmcResult.gas_left =
static_cast<int64_t
>(gas);
202 if (result.status == EVMC_SUCCESS)
203 evmcResult.create_address =
toEvmC(result.address);
211 evmcResult.output_data = result.output.data();
212 evmcResult.output_size = result.output.size();
215 auto* data = evmc_get_optional_storage(&evmcResult);
216 static_assert(
sizeof(
bytes) <=
sizeof(*data),
"Vector is too big");
217 new(data)
bytes(result.output.takeBytes());
219 evmcResult.release = [](evmc_result
const* _result)
221 auto* data = evmc_get_const_optional_storage(_result);
222 auto& output =
reinterpret_cast<bytes const&
>(*data);
231 evmc_result call(evmc_context* _context, evmc_message
const* _msg) noexcept
233 assert(_msg->gas >= 0 &&
"Invalid gas value");
234 auto& env =
static_cast<ExtVMFace&
>(*_context);
237 if (_msg->kind == EVMC_CREATE || _msg->kind == EVMC_CREATE2)
238 return create(env, _msg);
240 CallParameters params;
241 params.gas = _msg->gas;
242 params.apparentValue =
fromEvmC(_msg->value);
243 params.valueTransfer =
244 _msg->kind == EVMC_DELEGATECALL ? 0 : params.apparentValue;
245 params.senderAddress =
fromEvmC(_msg->sender);
246 params.codeAddress =
fromEvmC(_msg->destination);
247 params.receiveAddress =
248 _msg->kind == EVMC_CALL ? params.codeAddress : env.myAddress;
249 params.data = {_msg->input_data, _msg->input_size};
250 params.staticCall = (_msg->flags & EVMC_STATIC) != 0;
253 CallResult result = env.call(params);
254 evmc_result evmcResult = {};
255 evmcResult.status_code = result.status;
256 evmcResult.gas_left =
static_cast<int64_t
>(params.gas);
263 evmcResult.output_data = result.output.data();
264 evmcResult.output_size = result.output.size();
267 auto* data = evmc_get_optional_storage(&evmcResult);
268 static_assert(
sizeof(
bytes) <=
sizeof(*data),
"Vector is too big");
269 new(data)
bytes(result.output.takeBytes());
271 evmcResult.release = [](evmc_result
const* _result)
273 auto* data = evmc_get_const_optional_storage(_result);
274 auto& output =
reinterpret_cast<bytes const&
>(*data);
282 evmc_host_interface
const hostInterface = {
300 unsigned _depth,
bool _isCreate,
bool _staticCall)
301 : evmc_context{&hostInterface},
303 myAddress(_myAddress),
309 code(std::move(_code)),
313 staticCall(_staticCall)