EVMC
evmc.hpp
Go to the documentation of this file.
1 /* EVMC: Ethereum Client-VM Connector API.
2  * Copyright 2018-2020 The EVMC Authors.
3  * Licensed under the Apache License, Version 2.0.
4  */
5 #pragma once
6 
7 #include <evmc/evmc.h>
8 #include <evmc/helpers.h>
9 
10 #include <functional>
11 #include <initializer_list>
12 #include <ostream>
13 #include <utility>
14 
16  "latest stable revision ill-defined");
17 
20 namespace evmc
21 {
26 {
30  constexpr address(evmc_address init = {}) noexcept : evmc_address{init} {}
31 
36  constexpr explicit address(uint64_t v) noexcept
37  : evmc_address{{0,
38  0,
39  0,
40  0,
41  0,
42  0,
43  0,
44  0,
45  0,
46  0,
47  0,
48  0,
49  static_cast<uint8_t>(v >> 56),
50  static_cast<uint8_t>(v >> 48),
51  static_cast<uint8_t>(v >> 40),
52  static_cast<uint8_t>(v >> 32),
53  static_cast<uint8_t>(v >> 24),
54  static_cast<uint8_t>(v >> 16),
55  static_cast<uint8_t>(v >> 8),
56  static_cast<uint8_t>(v >> 0)}}
57  {}
58 
60  inline constexpr explicit operator bool() const noexcept;
61 };
62 
67 {
71  constexpr bytes32(evmc_bytes32 init = {}) noexcept : evmc_bytes32{init} {}
72 
77  constexpr explicit bytes32(uint64_t v) noexcept
78  : evmc_bytes32{{0,
79  0,
80  0,
81  0,
82  0,
83  0,
84  0,
85  0,
86  0,
87  0,
88  0,
89  0,
90  0,
91  0,
92  0,
93  0,
94  0,
95  0,
96  0,
97  0,
98  0,
99  0,
100  0,
101  0,
102  static_cast<uint8_t>(v >> 56),
103  static_cast<uint8_t>(v >> 48),
104  static_cast<uint8_t>(v >> 40),
105  static_cast<uint8_t>(v >> 32),
106  static_cast<uint8_t>(v >> 24),
107  static_cast<uint8_t>(v >> 16),
108  static_cast<uint8_t>(v >> 8),
109  static_cast<uint8_t>(v >> 0)}}
110  {}
111 
113  constexpr inline explicit operator bool() const noexcept;
114 };
115 
118 
119 
121 inline constexpr uint64_t load64be(const uint8_t* data) noexcept
122 {
123  return (uint64_t{data[0]} << 56) | (uint64_t{data[1]} << 48) | (uint64_t{data[2]} << 40) |
124  (uint64_t{data[3]} << 32) | (uint64_t{data[4]} << 24) | (uint64_t{data[5]} << 16) |
125  (uint64_t{data[6]} << 8) | uint64_t{data[7]};
126 }
127 
129 inline constexpr uint64_t load64le(const uint8_t* data) noexcept
130 {
131  return uint64_t{data[0]} | (uint64_t{data[1]} << 8) | (uint64_t{data[2]} << 16) |
132  (uint64_t{data[3]} << 24) | (uint64_t{data[4]} << 32) | (uint64_t{data[5]} << 40) |
133  (uint64_t{data[6]} << 48) | (uint64_t{data[7]} << 56);
134 }
135 
137 inline constexpr uint32_t load32be(const uint8_t* data) noexcept
138 {
139  return (uint32_t{data[0]} << 24) | (uint32_t{data[1]} << 16) | (uint32_t{data[2]} << 8) |
140  uint32_t{data[3]};
141 }
142 
144 inline constexpr uint32_t load32le(const uint8_t* data) noexcept
145 {
146  return uint32_t{data[0]} | (uint32_t{data[1]} << 8) | (uint32_t{data[2]} << 16) |
147  (uint32_t{data[3]} << 24);
148 }
149 
150 namespace fnv
151 {
152 constexpr auto prime = 0x100000001b3;
153 constexpr auto offset_basis = 0xcbf29ce484222325;
154 
156 inline constexpr uint64_t fnv1a_by64(uint64_t h, uint64_t x) noexcept
157 {
158  return (h ^ x) * prime;
159 }
160 } // namespace fnv
161 
162 
164 inline constexpr bool operator==(const address& a, const address& b) noexcept
165 {
166  return load64le(&a.bytes[0]) == load64le(&b.bytes[0]) &&
167  load64le(&a.bytes[8]) == load64le(&b.bytes[8]) &&
168  load32le(&a.bytes[16]) == load32le(&b.bytes[16]);
169 }
170 
172 inline constexpr bool operator!=(const address& a, const address& b) noexcept
173 {
174  return !(a == b);
175 }
176 
178 inline constexpr bool operator<(const address& a, const address& b) noexcept
179 {
180  return load64be(&a.bytes[0]) < load64be(&b.bytes[0]) ||
181  (load64be(&a.bytes[0]) == load64be(&b.bytes[0]) &&
182  (load64be(&a.bytes[8]) < load64be(&b.bytes[8]) ||
183  (load64be(&a.bytes[8]) == load64be(&b.bytes[8]) &&
184  load32be(&a.bytes[16]) < load32be(&b.bytes[16]))));
185 }
186 
188 inline constexpr bool operator>(const address& a, const address& b) noexcept
189 {
190  return b < a;
191 }
192 
194 inline constexpr bool operator<=(const address& a, const address& b) noexcept
195 {
196  return !(b < a);
197 }
198 
200 inline constexpr bool operator>=(const address& a, const address& b) noexcept
201 {
202  return !(a < b);
203 }
204 
206 inline constexpr bool operator==(const bytes32& a, const bytes32& b) noexcept
207 {
208  return load64le(&a.bytes[0]) == load64le(&b.bytes[0]) &&
209  load64le(&a.bytes[8]) == load64le(&b.bytes[8]) &&
210  load64le(&a.bytes[16]) == load64le(&b.bytes[16]) &&
211  load64le(&a.bytes[24]) == load64le(&b.bytes[24]);
212 }
213 
215 inline constexpr bool operator!=(const bytes32& a, const bytes32& b) noexcept
216 {
217  return !(a == b);
218 }
219 
221 inline constexpr bool operator<(const bytes32& a, const bytes32& b) noexcept
222 {
223  return load64be(&a.bytes[0]) < load64be(&b.bytes[0]) ||
224  (load64be(&a.bytes[0]) == load64be(&b.bytes[0]) &&
225  (load64be(&a.bytes[8]) < load64be(&b.bytes[8]) ||
226  (load64be(&a.bytes[8]) == load64be(&b.bytes[8]) &&
227  (load64be(&a.bytes[16]) < load64be(&b.bytes[16]) ||
228  (load64be(&a.bytes[16]) == load64be(&b.bytes[16]) &&
229  load64be(&a.bytes[24]) < load64be(&b.bytes[24]))))));
230 }
231 
233 inline constexpr bool operator>(const bytes32& a, const bytes32& b) noexcept
234 {
235  return b < a;
236 }
237 
239 inline constexpr bool operator<=(const bytes32& a, const bytes32& b) noexcept
240 {
241  return !(b < a);
242 }
243 
245 inline constexpr bool operator>=(const bytes32& a, const bytes32& b) noexcept
246 {
247  return !(a < b);
248 }
249 
251 inline constexpr bool is_zero(const address& a) noexcept
252 {
253  return a == address{};
254 }
255 
256 inline constexpr address::operator bool() const noexcept
257 {
258  return !is_zero(*this);
259 }
260 
262 inline constexpr bool is_zero(const bytes32& a) noexcept
263 {
264  return a == bytes32{};
265 }
266 
267 inline constexpr bytes32::operator bool() const noexcept
268 {
269  return !is_zero(*this);
270 }
271 
272 namespace literals
273 {
274 namespace internal
275 {
276 constexpr int from_hex(char c) noexcept
277 {
278  return (c >= 'a' && c <= 'f') ? c - ('a' - 10) :
279  (c >= 'A' && c <= 'F') ? c - ('A' - 10) :
280  c - '0';
281 }
282 
283 constexpr uint8_t byte(const char* s, size_t i) noexcept
284 {
285  return static_cast<uint8_t>((from_hex(s[2 * i]) << 4) | from_hex(s[2 * i + 1]));
286 }
287 
288 template <typename T>
289 T from_hex(const char*) noexcept;
290 
291 template <>
292 constexpr bytes32 from_hex<bytes32>(const char* s) noexcept
293 {
294  return {
295  {{byte(s, 0), byte(s, 1), byte(s, 2), byte(s, 3), byte(s, 4), byte(s, 5), byte(s, 6),
296  byte(s, 7), byte(s, 8), byte(s, 9), byte(s, 10), byte(s, 11), byte(s, 12), byte(s, 13),
297  byte(s, 14), byte(s, 15), byte(s, 16), byte(s, 17), byte(s, 18), byte(s, 19), byte(s, 20),
298  byte(s, 21), byte(s, 22), byte(s, 23), byte(s, 24), byte(s, 25), byte(s, 26), byte(s, 27),
299  byte(s, 28), byte(s, 29), byte(s, 30), byte(s, 31)}}};
300 }
301 
302 template <>
303 constexpr address from_hex<address>(const char* s) noexcept
304 {
305  return {
306  {{byte(s, 0), byte(s, 1), byte(s, 2), byte(s, 3), byte(s, 4), byte(s, 5), byte(s, 6),
307  byte(s, 7), byte(s, 8), byte(s, 9), byte(s, 10), byte(s, 11), byte(s, 12), byte(s, 13),
308  byte(s, 14), byte(s, 15), byte(s, 16), byte(s, 17), byte(s, 18), byte(s, 19)}}};
309 }
310 
311 template <typename T, char... c>
312 constexpr T from_literal() noexcept
313 {
314  constexpr auto size = sizeof...(c);
315  constexpr char literal[] = {c...};
316  constexpr bool is_simple_zero = size == 1 && literal[0] == '0';
317 
318  static_assert(is_simple_zero || (literal[0] == '0' && literal[1] == 'x'),
319  "literal must be in hexadecimal notation");
320  static_assert(is_simple_zero || size == 2 * sizeof(T) + 2,
321  "literal must match the result type size");
322 
323  return is_simple_zero ? T{} : from_hex<T>(&literal[2]);
324 }
325 } // namespace internal
326 
328 template <char... c>
329 constexpr address operator""_address() noexcept
330 {
331  return internal::from_literal<address, c...>();
332 }
333 
335 template <char... c>
336 constexpr bytes32 operator""_bytes32() noexcept
337 {
338  return internal::from_literal<bytes32, c...>();
339 }
340 } // namespace literals
341 
342 using namespace literals;
343 
344 
346 inline const char* to_string(evmc_status_code status_code) noexcept
347 {
348  return evmc_status_code_to_string(status_code);
349 }
350 
352 inline const char* to_string(evmc_revision rev) noexcept
353 {
354  return evmc_revision_to_string(rev);
355 }
356 
357 
359 constexpr auto make_result = evmc_make_result;
360 
365 class result : private evmc_result
366 {
367 public:
369  using evmc_result::gas_left;
373 
383  result(evmc_status_code _status_code,
384  int64_t _gas_left,
385  const uint8_t* _output_data,
386  size_t _output_size) noexcept
387  : evmc_result{make_result(_status_code, _gas_left, _output_data, _output_size)}
388  {}
389 
391  explicit result(evmc_result const& res) noexcept : evmc_result{res} {}
392 
394  ~result() noexcept
395  {
396  if (release != nullptr)
397  release(this);
398  }
399 
401  result(result&& other) noexcept : evmc_result{other}
402  {
403  other.release = nullptr; // Disable releasing of the rvalue object.
404  }
405 
412  result& operator=(result&& other) noexcept
413  {
414  this->~result(); // Release this object.
415  static_cast<evmc_result&>(*this) = other; // Copy data.
416  other.release = nullptr; // Disable releasing of the rvalue object.
417  return *this;
418  }
419 
429  {
430  const auto out = evmc_result{*this}; // Copy data.
431  this->release = nullptr; // Disable releasing of this object.
432  return out;
433  }
434 };
435 
436 
439 {
440 public:
441  virtual ~HostInterface() noexcept = default;
442 
444  virtual bool account_exists(const address& addr) const noexcept = 0;
445 
447  virtual bytes32 get_storage(const address& addr, const bytes32& key) const noexcept = 0;
448 
451  const bytes32& key,
452  const bytes32& value) noexcept = 0;
453 
455  virtual uint256be get_balance(const address& addr) const noexcept = 0;
456 
458  virtual size_t get_code_size(const address& addr) const noexcept = 0;
459 
461  virtual bytes32 get_code_hash(const address& addr) const noexcept = 0;
462 
464  virtual size_t copy_code(const address& addr,
465  size_t code_offset,
466  uint8_t* buffer_data,
467  size_t buffer_size) const noexcept = 0;
468 
470  virtual void selfdestruct(const address& addr, const address& beneficiary) noexcept = 0;
471 
473  virtual result call(const evmc_message& msg) noexcept = 0;
474 
476  virtual evmc_tx_context get_tx_context() const noexcept = 0;
477 
479  virtual bytes32 get_block_hash(int64_t block_number) const noexcept = 0;
480 
482  virtual void emit_log(const address& addr,
483  const uint8_t* data,
484  size_t data_size,
485  const bytes32 topics[],
486  size_t num_topics) noexcept = 0;
487 
489  virtual evmc_access_status access_account(const address& addr) noexcept = 0;
490 
492  virtual evmc_access_status access_storage(const address& addr, const bytes32& key) noexcept = 0;
493 };
494 
495 
500 {
501  const evmc_host_interface* host = nullptr;
502  evmc_host_context* context = nullptr;
503  mutable evmc_tx_context tx_context = {};
504 
505 public:
507  HostContext() = default;
508 
512  HostContext(const evmc_host_interface& interface, evmc_host_context* ctx) noexcept
513  : host{&interface}, context{ctx}
514  {}
515 
516  bool account_exists(const address& address) const noexcept final
517  {
518  return host->account_exists(context, &address);
519  }
520 
521  bytes32 get_storage(const address& address, const bytes32& key) const noexcept final
522  {
523  return host->get_storage(context, &address, &key);
524  }
525 
527  const bytes32& key,
528  const bytes32& value) noexcept final
529  {
530  return host->set_storage(context, &address, &key, &value);
531  }
532 
533  uint256be get_balance(const address& address) const noexcept final
534  {
535  return host->get_balance(context, &address);
536  }
537 
538  size_t get_code_size(const address& address) const noexcept final
539  {
540  return host->get_code_size(context, &address);
541  }
542 
543  bytes32 get_code_hash(const address& address) const noexcept final
544  {
545  return host->get_code_hash(context, &address);
546  }
547 
548  size_t copy_code(const address& address,
549  size_t code_offset,
550  uint8_t* buffer_data,
551  size_t buffer_size) const noexcept final
552  {
553  return host->copy_code(context, &address, code_offset, buffer_data, buffer_size);
554  }
555 
556  void selfdestruct(const address& addr, const address& beneficiary) noexcept final
557  {
558  host->selfdestruct(context, &addr, &beneficiary);
559  }
560 
561  result call(const evmc_message& message) noexcept final
562  {
563  return result{host->call(context, &message)};
564  }
565 
572  evmc_tx_context get_tx_context() const noexcept final
573  {
574  if (tx_context.block_timestamp == 0)
575  tx_context = host->get_tx_context(context);
576  return tx_context;
577  }
578 
579  bytes32 get_block_hash(int64_t number) const noexcept final
580  {
581  return host->get_block_hash(context, number);
582  }
583 
584  void emit_log(const address& addr,
585  const uint8_t* data,
586  size_t data_size,
587  const bytes32 topics[],
588  size_t topics_count) noexcept final
589  {
590  host->emit_log(context, &addr, data, data_size, topics, topics_count);
591  }
592 
594  {
595  return host->access_account(context, &address);
596  }
597 
598  evmc_access_status access_storage(const address& address, const bytes32& key) noexcept final
599  {
600  return host->access_storage(context, &address, &key);
601  }
602 };
603 
604 
610 class Host : public HostInterface
611 {
612 public:
615  static const evmc_host_interface& get_interface() noexcept;
616 
619  evmc_host_context* to_context() noexcept { return reinterpret_cast<evmc_host_context*>(this); }
620 
625  template <typename DerivedClass = Host>
626  static DerivedClass* from_context(evmc_host_context* context) noexcept
627  {
628  // Get pointer of the Host base class.
629  auto* h = reinterpret_cast<Host*>(context);
630 
631  // Additional downcast, only possible if DerivedClass inherits from Host.
632  return static_cast<DerivedClass*>(h);
633  }
634 };
635 
636 
641 class VM
642 {
643 public:
644  VM() noexcept = default;
645 
647  explicit VM(evmc_vm* vm) noexcept : m_instance{vm} {}
648 
650  ~VM() noexcept
651  {
652  if (m_instance != nullptr)
653  m_instance->destroy(m_instance);
654  }
655 
656  VM(const VM&) = delete;
657  VM& operator=(const VM&) = delete;
658 
660  VM(VM&& other) noexcept : m_instance{other.m_instance} { other.m_instance = nullptr; }
661 
663  VM& operator=(VM&& other) noexcept
664  {
665  this->~VM();
666  m_instance = other.m_instance;
667  other.m_instance = nullptr;
668  return *this;
669  }
670 
673  inline VM(evmc_vm* vm,
674  std::initializer_list<std::pair<const char*, const char*>> options) noexcept;
675 
677  explicit operator bool() const noexcept { return m_instance != nullptr; }
678 
680  bool is_abi_compatible() const noexcept { return m_instance->abi_version == EVMC_ABI_VERSION; }
681 
683  char const* name() const noexcept { return m_instance->name; }
684 
686  char const* version() const noexcept { return m_instance->version; }
687 
689  bool has_capability(evmc_capabilities capability) const noexcept
690  {
691  return (get_capabilities() & static_cast<evmc_capabilities_flagset>(capability)) != 0;
692  }
693 
696  {
697  return m_instance->get_capabilities(m_instance);
698  }
699 
701  evmc_set_option_result set_option(const char name[], const char value[]) noexcept
702  {
703  return evmc_set_option(m_instance, name, value);
704  }
705 
708  evmc_host_context* ctx,
709  evmc_revision rev,
710  const evmc_message& msg,
711  const uint8_t* code,
712  size_t code_size) noexcept
713  {
714  return result{m_instance->execute(m_instance, &host, ctx, rev, &msg, code, code_size)};
715  }
716 
719  evmc_revision rev,
720  const evmc_message& msg,
721  const uint8_t* code,
722  size_t code_size) noexcept
723  {
724  return execute(Host::get_interface(), host.to_context(), rev, msg, code, code_size);
725  }
726 
736  const evmc_message& msg,
737  const uint8_t* code,
738  size_t code_size) noexcept
739  {
740  return result{
741  m_instance->execute(m_instance, nullptr, nullptr, rev, &msg, code, code_size)};
742  }
743 
749  evmc_vm* get_raw_pointer() const noexcept { return m_instance; }
750 
751 private:
752  evmc_vm* m_instance = nullptr;
753 };
754 
755 inline VM::VM(evmc_vm* vm,
756  std::initializer_list<std::pair<const char*, const char*>> options) noexcept
757  : m_instance{vm}
758 {
759  // This constructor is implemented outside of the class definition to workaround a doxygen bug.
760  for (const auto& option : options)
761  set_option(option.first, option.second);
762 }
763 
764 
765 namespace internal
766 {
767 inline bool account_exists(evmc_host_context* h, const evmc_address* addr) noexcept
768 {
769  return Host::from_context(h)->account_exists(*addr);
770 }
771 
772 inline evmc_bytes32 get_storage(evmc_host_context* h,
773  const evmc_address* addr,
774  const evmc_bytes32* key) noexcept
775 {
776  return Host::from_context(h)->get_storage(*addr, *key);
777 }
778 
779 inline evmc_storage_status set_storage(evmc_host_context* h,
780  const evmc_address* addr,
781  const evmc_bytes32* key,
782  const evmc_bytes32* value) noexcept
783 {
784  return Host::from_context(h)->set_storage(*addr, *key, *value);
785 }
786 
787 inline evmc_uint256be get_balance(evmc_host_context* h, const evmc_address* addr) noexcept
788 {
789  return Host::from_context(h)->get_balance(*addr);
790 }
791 
792 inline size_t get_code_size(evmc_host_context* h, const evmc_address* addr) noexcept
793 {
794  return Host::from_context(h)->get_code_size(*addr);
795 }
796 
797 inline evmc_bytes32 get_code_hash(evmc_host_context* h, const evmc_address* addr) noexcept
798 {
799  return Host::from_context(h)->get_code_hash(*addr);
800 }
801 
802 inline size_t copy_code(evmc_host_context* h,
803  const evmc_address* addr,
804  size_t code_offset,
805  uint8_t* buffer_data,
806  size_t buffer_size) noexcept
807 {
808  return Host::from_context(h)->copy_code(*addr, code_offset, buffer_data, buffer_size);
809 }
810 
811 inline void selfdestruct(evmc_host_context* h,
812  const evmc_address* addr,
813  const evmc_address* beneficiary) noexcept
814 {
815  Host::from_context(h)->selfdestruct(*addr, *beneficiary);
816 }
817 
818 inline evmc_result call(evmc_host_context* h, const evmc_message* msg) noexcept
819 {
820  return Host::from_context(h)->call(*msg).release_raw();
821 }
822 
823 inline evmc_tx_context get_tx_context(evmc_host_context* h) noexcept
824 {
825  return Host::from_context(h)->get_tx_context();
826 }
827 
828 inline evmc_bytes32 get_block_hash(evmc_host_context* h, int64_t block_number) noexcept
829 {
830  return Host::from_context(h)->get_block_hash(block_number);
831 }
832 
833 inline void emit_log(evmc_host_context* h,
834  const evmc_address* addr,
835  const uint8_t* data,
836  size_t data_size,
837  const evmc_bytes32 topics[],
838  size_t num_topics) noexcept
839 {
840  Host::from_context(h)->emit_log(*addr, data, data_size, static_cast<const bytes32*>(topics),
841  num_topics);
842 }
843 
844 inline evmc_access_status access_account(evmc_host_context* h, const evmc_address* addr) noexcept
845 {
846  return Host::from_context(h)->access_account(*addr);
847 }
848 
849 inline evmc_access_status access_storage(evmc_host_context* h,
850  const evmc_address* addr,
851  const evmc_bytes32* key) noexcept
852 {
853  return Host::from_context(h)->access_storage(*addr, *key);
854 }
855 } // namespace internal
856 
857 inline const evmc_host_interface& Host::get_interface() noexcept
858 {
859  static constexpr evmc_host_interface interface{
860  ::evmc::internal::account_exists, ::evmc::internal::get_storage,
861  ::evmc::internal::set_storage, ::evmc::internal::get_balance,
862  ::evmc::internal::get_code_size, ::evmc::internal::get_code_hash,
863  ::evmc::internal::copy_code, ::evmc::internal::selfdestruct,
864  ::evmc::internal::call, ::evmc::internal::get_tx_context,
865  ::evmc::internal::get_block_hash, ::evmc::internal::emit_log,
866  ::evmc::internal::access_account, ::evmc::internal::access_storage,
867  };
868  return interface;
869 }
870 } // namespace evmc
871 
872 
877 inline std::ostream& operator<<(std::ostream& os, evmc_status_code status_code)
878 {
879  return os << evmc::to_string(status_code);
880 }
881 
886 inline std::ostream& operator<<(std::ostream& os, evmc_revision rev)
887 {
888  return os << evmc::to_string(rev);
889 }
890 
891 namespace std
892 {
894 template <>
895 struct hash<evmc::address>
896 {
898  constexpr size_t operator()(const evmc::address& s) const noexcept
899  {
900  using namespace evmc;
901  using namespace fnv;
902  return static_cast<size_t>(fnv1a_by64(
903  fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64le(&s.bytes[0])), load64le(&s.bytes[8])),
904  load32le(&s.bytes[16])));
905  }
906 };
907 
909 template <>
910 struct hash<evmc::bytes32>
911 {
913  constexpr size_t operator()(const evmc::bytes32& s) const noexcept
914  {
915  using namespace evmc;
916  using namespace fnv;
917  return static_cast<size_t>(
918  fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64le(&s.bytes[0])),
919  load64le(&s.bytes[8])),
920  load64le(&s.bytes[16])),
921  load64le(&s.bytes[24])));
922  }
923 };
924 } // namespace std
Wrapper around EVMC host context / host interface.
Definition: evmc.hpp:500
bytes32 get_code_hash(const address &address) const noexcept final
Get code hash callback function.
Definition: evmc.hpp:543
bool account_exists(const address &address) const noexcept final
Check account existence callback function.
Definition: evmc.hpp:516
void selfdestruct(const address &addr, const address &beneficiary) noexcept final
Selfdestruct callback function.
Definition: evmc.hpp:556
size_t get_code_size(const address &address) const noexcept final
Get code size callback function.
Definition: evmc.hpp:538
HostContext()=default
Default constructor for null Host context.
uint256be get_balance(const address &address) const noexcept final
Get balance callback function.
Definition: evmc.hpp:533
HostContext(const evmc_host_interface &interface, evmc_host_context *ctx) noexcept
Constructor from the EVMC Host primitives.
Definition: evmc.hpp:512
evmc_access_status access_storage(const address &address, const bytes32 &key) noexcept final
Access storage callback function.
Definition: evmc.hpp:598
result call(const evmc_message &message) noexcept final
Call callback function.
Definition: evmc.hpp:561
size_t copy_code(const address &address, size_t code_offset, uint8_t *buffer_data, size_t buffer_size) const noexcept final
Copy code callback function.
Definition: evmc.hpp:548
evmc_access_status access_account(const address &address) noexcept final
Access account callback function.
Definition: evmc.hpp:593
bytes32 get_block_hash(int64_t number) const noexcept final
Get block hash callback function.
Definition: evmc.hpp:579
void emit_log(const address &addr, const uint8_t *data, size_t data_size, const bytes32 topics[], size_t topics_count) noexcept final
Emit log callback function.
Definition: evmc.hpp:584
evmc_storage_status set_storage(const address &address, const bytes32 &key, const bytes32 &value) noexcept final
Set storage callback function.
Definition: evmc.hpp:526
evmc_tx_context get_tx_context() const noexcept final
Get transaction context callback function.
Definition: evmc.hpp:572
bytes32 get_storage(const address &address, const bytes32 &key) const noexcept final
Get storage callback function.
Definition: evmc.hpp:521
The EVMC Host interface.
Definition: evmc.hpp:439
virtual bytes32 get_storage(const address &addr, const bytes32 &key) const noexcept=0
Get storage callback function.
virtual evmc_tx_context get_tx_context() const noexcept=0
Get transaction context callback function.
virtual result call(const evmc_message &msg) noexcept=0
Call callback function.
virtual bytes32 get_code_hash(const address &addr) const noexcept=0
Get code hash callback function.
virtual size_t get_code_size(const address &addr) const noexcept=0
Get code size callback function.
virtual evmc_storage_status set_storage(const address &addr, const bytes32 &key, const bytes32 &value) noexcept=0
Set storage callback function.
virtual uint256be get_balance(const address &addr) const noexcept=0
Get balance callback function.
virtual size_t copy_code(const address &addr, size_t code_offset, uint8_t *buffer_data, size_t buffer_size) const noexcept=0
Copy code callback function.
virtual bool account_exists(const address &addr) const noexcept=0
Check account existence callback function.
virtual void selfdestruct(const address &addr, const address &beneficiary) noexcept=0
Selfdestruct callback function.
Abstract class to be used by Host implementations.
Definition: evmc.hpp:611
evmc_host_context * to_context() noexcept
Converts the Host object to the opaque host context pointer.
Definition: evmc.hpp:619
static const evmc_host_interface & get_interface() noexcept
Provides access to the global host interface.
Definition: evmc.hpp:857
static DerivedClass * from_context(evmc_host_context *context) noexcept
Converts the opaque host context pointer back to the original Host object.
Definition: evmc.hpp:626
The VM instance.
Definition: evmc.hpp:642
char const * version() const noexcept
The version of the EVMC VM implementation, e.g.
Definition: evmc.hpp:686
result execute(evmc_revision rev, const evmc_message &msg, const uint8_t *code, size_t code_size) noexcept
Executes code without the Host context.
Definition: evmc.hpp:735
result execute(Host &host, evmc_revision rev, const evmc_message &msg, const uint8_t *code, size_t code_size) noexcept
Convenient variant of the VM::execute() that takes reference to evmc::Host class.
Definition: evmc.hpp:718
evmc_set_option_result set_option(const char name[], const char value[]) noexcept
Sets the option for the VM, if the feature is supported by the VM.
Definition: evmc.hpp:701
evmc_vm * get_raw_pointer() const noexcept
Returns the pointer to C EVMC struct representing the VM.
Definition: evmc.hpp:749
VM & operator=(VM &&other) noexcept
Move assignment operator.
Definition: evmc.hpp:663
~VM() noexcept
Destructor responsible for automatically destroying the VM instance.
Definition: evmc.hpp:650
bool is_abi_compatible() const noexcept
Checks whenever the VM instance is ABI compatible with the current EVMC API.
Definition: evmc.hpp:680
bool has_capability(evmc_capabilities capability) const noexcept
Checks if the VM has the given capability.
Definition: evmc.hpp:689
VM(VM &&other) noexcept
Move constructor.
Definition: evmc.hpp:660
result execute(const evmc_host_interface &host, evmc_host_context *ctx, evmc_revision rev, const evmc_message &msg, const uint8_t *code, size_t code_size) noexcept
Executes code in the VM instance.
Definition: evmc.hpp:707
evmc_capabilities_flagset get_capabilities() const noexcept
A method returning capabilities supported by the VM instance.
Definition: evmc.hpp:695
VM(evmc_vm *vm) noexcept
Converting constructor from evmc_vm.
Definition: evmc.hpp:647
char const * name() const noexcept
The name of the EVMC VM implementation.
Definition: evmc.hpp:683
The EVM code execution result.
Definition: evmc.hpp:366
result & operator=(result &&other) noexcept
Move assignment operator.
Definition: evmc.hpp:412
evmc_result release_raw() noexcept
Releases the ownership and returns the raw copy of evmc_result.
Definition: evmc.hpp:428
result(evmc_result const &res) noexcept
Converting constructor from raw evmc_result.
Definition: evmc.hpp:391
result(evmc_status_code _status_code, int64_t _gas_left, const uint8_t *_output_data, size_t _output_size) noexcept
Creates the result from the provided arguments.
Definition: evmc.hpp:383
result(result &&other) noexcept
Move constructor.
Definition: evmc.hpp:401
~result() noexcept
Destructor responsible for automatically releasing attached resources.
Definition: evmc.hpp:394
EVMC: Ethereum Client-VM Connector API.
std::ostream & operator<<(std::ostream &os, evmc_status_code status_code)
"Stream out" operator implementation for evmc_status_code.
Definition: evmc.hpp:877
constexpr auto offset_basis
The 64-bit FNV offset basis.
Definition: evmc.hpp:153
constexpr uint64_t fnv1a_by64(uint64_t h, uint64_t x) noexcept
The hashing transformation for 64-bit inputs based on the FNV-1a formula.
Definition: evmc.hpp:156
constexpr auto prime
The 64-bit FNV prime number.
Definition: evmc.hpp:152
evmc_set_option_result
Possible outcomes of evmc_set_option.
Definition: evmc.h:778
evmc_capabilities
Possible capabilities of a VM.
Definition: evmc.h:931
evmc_status_code
The execution status code.
Definition: evmc.h:260
uint32_t evmc_capabilities_flagset
Alias for unsigned integer representing a set of bit flags of EVMC capabilities.
Definition: evmc.h:960
evmc_access_status
Access status per EIP-2929: Gas cost increases for state access opcodes.
Definition: evmc.h:658
evmc_storage_status
The effect of an attempt to modify a contract storage item.
Definition: evmc.h:511
evmc_revision
EVM revision.
Definition: evmc.h:809
@ EVMC_ABI_VERSION
The EVMC ABI version number of the interface declared in this file.
Definition: evmc.h:47
@ EVMC_LATEST_STABLE_REVISION
The latest known EVM revision with finalized specification.
Definition: evmc.h:897
@ EVMC_MAX_REVISION
The maximum EVM revision supported.
Definition: evmc.h:890
static struct evmc_result evmc_make_result(enum evmc_status_code status_code, int64_t gas_left, const uint8_t *output_data, size_t output_size)
Creates the result from the provided arguments.
Definition: helpers.h:121
static const char * evmc_status_code_to_string(enum evmc_status_code status_code)
Returns text representation of the evmc_status_code.
Definition: helpers.h:213
static enum evmc_set_option_result evmc_set_option(struct evmc_vm *vm, char const *name, char const *value)
Sets the option for the VM, if the feature is supported by the VM.
Definition: helpers.h:73
static const char * evmc_revision_to_string(enum evmc_revision rev)
Returns the name of the evmc_revision.
Definition: helpers.h:264
EVMC Helpers.
EVMC C++ API - wrappers and bindings for C++.
Definition: evmc.hpp:21
constexpr bool operator<(const address &a, const address &b) noexcept
The "less than" comparison operator for the evmc::address type.
Definition: evmc.hpp:178
constexpr uint64_t load64be(const uint8_t *data) noexcept
Loads 64 bits / 8 bytes of data from the given data array in big-endian order.
Definition: evmc.hpp:121
constexpr uint32_t load32be(const uint8_t *data) noexcept
Loads 32 bits / 4 bytes of data from the given data array in big-endian order.
Definition: evmc.hpp:137
constexpr bool operator==(const address &a, const address &b) noexcept
The "equal to" comparison operator for the evmc::address type.
Definition: evmc.hpp:164
constexpr bool operator>(const address &a, const address &b) noexcept
The "greater than" comparison operator for the evmc::address type.
Definition: evmc.hpp:188
bytes from_hex(std::string_view hex)
Decodes hex encoded string to bytes.
constexpr auto make_result
Alias for evmc_make_result().
Definition: evmc.hpp:359
constexpr bool operator>=(const address &a, const address &b) noexcept
The "greater than or equal to" comparison operator for the evmc::address type.
Definition: evmc.hpp:200
const char * to_string(evmc_status_code status_code) noexcept
Returns text representation of the evmc_status_code.
Definition: evmc.hpp:346
constexpr bool operator<=(const address &a, const address &b) noexcept
The "less than or equal to" comparison operator for the evmc::address type.
Definition: evmc.hpp:194
constexpr uint64_t load64le(const uint8_t *data) noexcept
Loads 64 bits / 8 bytes of data from the given data array in little-endian order.
Definition: evmc.hpp:129
constexpr bool operator!=(const address &a, const address &b) noexcept
The "not equal to" comparison operator for the evmc::address type.
Definition: evmc.hpp:172
constexpr uint32_t load32le(const uint8_t *data) noexcept
Loads 32 bits / 4 bytes of data from the given data array in little-endian order.
Definition: evmc.hpp:144
constexpr bool is_zero(const address &a) noexcept
Checks if the given address is the zero address.
Definition: evmc.hpp:251
The big-endian 160-bit hash suitable for keeping an Ethereum address.
Definition: evmc.hpp:26
constexpr address(evmc_address init={}) noexcept
Default and converting constructor.
Definition: evmc.hpp:30
constexpr address(uint64_t v) noexcept
Converting constructor from unsigned integer value.
Definition: evmc.hpp:36
The fixed size array of 32 bytes for storing 256-bit EVM values.
Definition: evmc.hpp:67
constexpr bytes32(evmc_bytes32 init={}) noexcept
Default and converting constructor.
Definition: evmc.hpp:71
constexpr bytes32(uint64_t v) noexcept
Converting constructor from unsigned integer value.
Definition: evmc.hpp:77
Big-endian 160-bit hash suitable for keeping an Ethereum address.
Definition: evmc.h:69
The fixed size array of 32 bytes.
Definition: evmc.h:57
The opaque data type representing the Host execution context.
The Host interface.
Definition: evmc.h:719
evmc_get_code_hash_fn get_code_hash
Get code hash callback function.
Definition: evmc.h:736
evmc_call_fn call
Call callback function.
Definition: evmc.h:745
evmc_selfdestruct_fn selfdestruct
Selfdestruct callback function.
Definition: evmc.h:742
evmc_get_storage_fn get_storage
Get storage callback function.
Definition: evmc.h:724
evmc_copy_code_fn copy_code
Copy code callback function.
Definition: evmc.h:739
evmc_get_code_size_fn get_code_size
Get code size callback function.
Definition: evmc.h:733
evmc_get_block_hash_fn get_block_hash
Get block hash callback function.
Definition: evmc.h:751
evmc_emit_log_fn emit_log
Emit log callback function.
Definition: evmc.h:754
evmc_account_exists_fn account_exists
Check account existence callback function.
Definition: evmc.h:721
evmc_access_account_fn access_account
Access account callback function.
Definition: evmc.h:757
evmc_get_balance_fn get_balance
Get balance callback function.
Definition: evmc.h:730
evmc_set_storage_fn set_storage
Set storage callback function.
Definition: evmc.h:727
evmc_get_tx_context_fn get_tx_context
Get transaction context callback function.
Definition: evmc.h:748
evmc_access_storage_fn access_storage
Access storage callback function.
Definition: evmc.h:760
The message describing an EVM call, including a zero-depth calls from a transaction origin.
Definition: evmc.h:97
The EVM code execution result.
Definition: evmc.h:392
const uint8_t * output_data
The reference to output data.
Definition: evmc.h:415
enum evmc_status_code status_code
The execution status code.
Definition: evmc.h:394
evmc_release_result_fn release
The method releasing all resources associated with the result object.
Definition: evmc.h:443
size_t output_size
The size of the output data.
Definition: evmc.h:422
evmc_address create_address
The address of the contract created by create instructions.
Definition: evmc.h:454
int64_t gas_left
The amount of gas left after the execution.
Definition: evmc.h:402
The transaction and block data for execution.
Definition: evmc.h:195
int64_t block_timestamp
The block timestamp.
Definition: evmc.h:200
The VM instance.
Definition: evmc.h:980