Decentralised Art Server
High-performance C++ backend that exposes HTML interface and a secure REST API for managing Performative Transactions entities
 
Loading...
Searching...
No Matches
evm_storage.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <cstring>
5#include <vector>
6#include <format>
7#include <stack>
8
9// Undefine the conflicting macro
10#ifdef interface
11 #undef interface
12#endif
13
14#include <evmc/evmc.h>
15#include <evmc/evmc.hpp>
16#include <evmc/hex.hpp>
17
18#ifndef interface
19 #define interface __STRUCT__
20#endif
21
22#include <spdlog/spdlog.h>
23#include <absl/container/flat_hash_map.h>
24
25#include "keccak256.hpp"
26
27#include "evm_formatter.hpp"
28
29namespace dcn::evm
30{
31 const std::uint64_t DEFAULT_GAS_LIMIT = 100'000'000;
32
33 class EVMStorage : public evmc::Host
34 {
35 public:
36 struct Account
37 {
38 evmc_uint256be balance;
39 std::vector<std::uint8_t> code;
40 absl::flat_hash_map<evmc::bytes32, evmc::bytes32> storage;
41
42 // Deployment metadata
43 evmc::address creator{};
44 uint64_t nonce = 0;
45 uint64_t timestamp = 0;
46 };
47
48 EVMStorage(evmc::VM & vm, evmc_revision rev);
49
50 bool add_account(const evmc::address& addr)
51 {
52 if(account_exists(addr) == true)
53 {
54 spdlog::error(std::format("add_account: Account {} already exists", addr));
55 return false;
56 }
57 _accounts.emplace(to_key(addr), Account{});
58 return true;
59 }
60
61 void set_balance(const evmc::address& addr, std::uint64_t x) noexcept
62 {
63 if(account_exists(addr) == false)
64 {
65 spdlog::error(std::format("set_balance : Account {} does not exist", addr));
66 return;
67 }
68 Account & acc = _accounts.at(to_key(addr));
69
70 acc.balance = evmc::uint256be{};
71 for (std::size_t i = 0; i < sizeof(x); ++i)
72 acc.balance.bytes[sizeof(acc.balance) - 1 - i] = static_cast<uint8_t>(x >> (8 * i));
73 }
74
75 bool account_exists(const evmc::address& addr) const noexcept override;
76
77 evmc::bytes32 get_storage(const evmc::address& addr, const evmc::bytes32& key) const noexcept override;
78
79 evmc_storage_status set_storage(const evmc::address& address, const evmc::bytes32& key, const evmc::bytes32& value) noexcept override;
80
81 evmc::uint256be get_balance(const evmc::address& addr) const noexcept override;
82
83 std::size_t get_code_size(const evmc::address& addr) const noexcept override;
84
85 evmc::bytes32 get_code_hash(const evmc::address& addr) const noexcept override;
86
87 std::size_t copy_code(const evmc::address& addr,
88 std::size_t code_offset,
89 std::uint8_t* buffer_data,
90 std::size_t buffer_size) const noexcept override;
91
92 bool selfdestruct(const evmc::address& addr, const evmc::address& beneficiary) noexcept override;
93
94 evmc::Result call(const evmc_message& msg) noexcept override;
95
96 evmc_tx_context get_tx_context() const noexcept override;
97
98 evmc::bytes32 get_block_hash(int64_t block_number) const noexcept override;
99 void emit_log(const evmc::address& addr,
100 const std::uint8_t* data,
101 size_t data_size,
102 const evmc::bytes32 topics[],
103 size_t num_topics) noexcept override;
104
105 evmc_access_status access_account(const evmc::address& addr) noexcept override;
106
107 evmc_access_status access_storage(const evmc::address& addr, const evmc::bytes32& key) noexcept override;
108
109 evmc::bytes32 get_transient_storage(const evmc::address& addr,
110 const evmc::bytes32& key) const noexcept override;
111
112 void set_transient_storage(const evmc::address& addr,
113 const evmc::bytes32& key,
114 const evmc::bytes32& value) noexcept override;
115
116 protected:
117 std::string to_key(const evmc::address& addr) const;
118
119 evmc_address derive_create_address(const evmc::address& sender, std::uint64_t nonce);
120
121 evmc_address derive_create2_address(const evmc::address& sender, const evmc::bytes32& salt, const std::vector<std::uint8_t>& code);
122
123 void deploy_contract(evmc::address addr, std::vector<std::uint8_t>&& code, evmc_uint256be value, evmc::address creator, std::uint64_t nonce);
124
125 private:
126 evmc::VM & _vm;
127 evmc_revision _revision;
128
129 absl::flat_hash_map<std::string, Account> _accounts;
130 absl::flat_hash_map<evmc::address, std::uint64_t> _create_nonce;
131
132 std::stack<evmc::address> _sender_stack;
133 };
134
135 template <typename H>
136 inline H AbslHashValue(H h, const evmc::address & addr)
137 {
138 return H::combine(std::move(h), addr.bytes);
139 }
140}
141
Definition evm_storage.hpp:34
void set_balance(const evmc::address &addr, std::uint64_t x) noexcept
Definition evm_storage.hpp:61
void emit_log(const evmc::address &addr, const std::uint8_t *data, size_t data_size, const evmc::bytes32 topics[], size_t num_topics) noexcept override
Definition evm_storage.cpp:317
evmc::bytes32 get_block_hash(int64_t block_number) const noexcept override
Definition evm_storage.cpp:262
void set_transient_storage(const evmc::address &addr, const evmc::bytes32 &key, const evmc::bytes32 &value) noexcept override
Definition evm_storage.cpp:474
void deploy_contract(evmc::address addr, std::vector< std::uint8_t > &&code, evmc_uint256be value, evmc::address creator, std::uint64_t nonce)
Definition evm_storage.cpp:523
evmc_storage_status set_storage(const evmc::address &address, const evmc::bytes32 &key, const evmc::bytes32 &value) noexcept override
Definition evm_storage.cpp:28
evmc::uint256be get_balance(const evmc::address &addr) const noexcept override
Definition evm_storage.cpp:34
evmc::bytes32 get_transient_storage(const evmc::address &addr, const evmc::bytes32 &key) const noexcept override
Definition evm_storage.cpp:465
evmc_tx_context get_tx_context() const noexcept override
Definition evm_storage.cpp:224
evmc_address derive_create2_address(const evmc::address &sender, const evmc::bytes32 &salt, const std::vector< std::uint8_t > &code)
Definition evm_storage.cpp:502
std::size_t copy_code(const evmc::address &addr, std::size_t code_offset, std::uint8_t *buffer_data, std::size_t buffer_size) const noexcept override
Definition evm_storage.cpp:63
evmc::Result call(const evmc_message &msg) noexcept override
Definition evm_storage.cpp:93
bool selfdestruct(const evmc::address &addr, const evmc::address &beneficiary) noexcept override
Definition evm_storage.cpp:80
evmc_access_status access_account(const evmc::address &addr) noexcept override
Definition evm_storage.cpp:451
evmc_access_status access_storage(const evmc::address &addr, const evmc::bytes32 &key) noexcept override
Definition evm_storage.cpp:458
evmc_address derive_create_address(const evmc::address &sender, std::uint64_t nonce)
Definition evm_storage.cpp:488
bool account_exists(const evmc::address &addr) const noexcept override
Definition evm_storage.cpp:12
bool add_account(const evmc::address &addr)
Definition evm_storage.hpp:50
std::string to_key(const evmc::address &addr) const
Definition evm_storage.cpp:483
evmc::bytes32 get_code_hash(const evmc::address &addr) const noexcept override
Definition evm_storage.cpp:49
evmc::bytes32 get_storage(const evmc::address &addr, const evmc::bytes32 &key) const noexcept override
Definition evm_storage.cpp:17
std::size_t get_code_size(const evmc::address &addr) const noexcept override
Definition evm_storage.cpp:44
Definition evm.hpp:41
const std::uint64_t DEFAULT_GAS_LIMIT
Definition evm_storage.hpp:31
H AbslHashValue(H h, const evmc::address &addr)
Definition evm_storage.hpp:136
Definition evm_storage.hpp:37
uint64_t timestamp
Definition evm_storage.hpp:45
evmc::address creator
Definition evm_storage.hpp:43
std::vector< std::uint8_t > code
Definition evm_storage.hpp:39
uint64_t nonce
Definition evm_storage.hpp:44
evmc_uint256be balance
Definition evm_storage.hpp:38
absl::flat_hash_map< evmc::bytes32, evmc::bytes32 > storage
Definition evm_storage.hpp:40