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 "native.h"
23#include <asio.hpp>
24#include <spdlog/spdlog.h>
25#include <absl/container/flat_hash_map.h>
26
27#include "utils.hpp"
28#include "keccak256.hpp"
29
30#include "evm_formatter.hpp"
31
32namespace dcn::evm
33{
34 const std::uint64_t DEFAULT_GAS_LIMIT = 100'000'000;
35
36 class EVMStorage : public evmc::Host
37 {
38 public:
39 struct Account
40 {
41 evmc_uint256be balance;
42 std::vector<std::uint8_t> code;
43 absl::flat_hash_map<evmc::bytes32, evmc::bytes32> storage;
44
45 // Deployment metadata
46 evmc::address creator{};
47 uint64_t nonce = 0;
48 uint64_t timestamp = 0;
49 };
50
51 EVMStorage(evmc::VM & vm, evmc_revision rev);
52
53 bool add_account(const evmc::address& addr)
54 {
55 if(account_exists(addr) == true)
56 {
57 spdlog::error(std::format("add_account: Account {} already exists", addr));
58 return false;
59 }
60 _accounts.emplace(to_key(addr), Account{});
61 return true;
62 }
63
64 void set_balance(const evmc::address& addr, std::uint64_t x) noexcept
65 {
66 if(account_exists(addr) == false)
67 {
68 spdlog::error(std::format("set_balance : Account {} does not exist", addr));
69 return;
70 }
71 Account & acc = _accounts.at(to_key(addr));
72
73 acc.balance = evmc::uint256be{};
74 for (std::size_t i = 0; i < sizeof(x); ++i)
75 acc.balance.bytes[sizeof(acc.balance) - 1 - i] = static_cast<uint8_t>(x >> (8 * i));
76 }
77
78 bool account_exists(const evmc::address& addr) const noexcept override;
79
80 evmc::bytes32 get_storage(const evmc::address& addr, const evmc::bytes32& key) const noexcept override;
81
82 evmc_storage_status set_storage(const evmc::address& address, const evmc::bytes32& key, const evmc::bytes32& value) noexcept override;
83
84 evmc::uint256be get_balance(const evmc::address& addr) const noexcept override;
85
86 std::size_t get_code_size(const evmc::address& addr) const noexcept override;
87
88 evmc::bytes32 get_code_hash(const evmc::address& addr) const noexcept override;
89
90 std::size_t copy_code(const evmc::address& addr,
91 std::size_t code_offset,
92 std::uint8_t* buffer_data,
93 std::size_t buffer_size) const noexcept override;
94
95 bool selfdestruct(const evmc::address& addr, const evmc::address& beneficiary) noexcept override;
96
97 evmc::Result call(const evmc_message& msg) noexcept override;
98
99 evmc_tx_context get_tx_context() const noexcept override;
100
101 evmc::bytes32 get_block_hash(int64_t block_number) const noexcept override;
102 void emit_log(const evmc::address& addr,
103 const std::uint8_t* data,
104 size_t data_size,
105 const evmc::bytes32 topics[],
106 size_t num_topics) noexcept override;
107
108 evmc_access_status access_account(const evmc::address& addr) noexcept override;
109
110 evmc_access_status access_storage(const evmc::address& addr, const evmc::bytes32& key) noexcept override;
111
112 evmc::bytes32 get_transient_storage(const evmc::address& addr,
113 const evmc::bytes32& key) const noexcept override;
114
115 void set_transient_storage(const evmc::address& addr,
116 const evmc::bytes32& key,
117 const evmc::bytes32& value) noexcept override;
118
119 protected:
120 std::string to_key(const evmc::address& addr) const;
121
122 evmc_address derive_create_address(const evmc::address& sender, std::uint64_t nonce);
123
124 evmc_address derive_create2_address(const evmc::address& sender, const evmc::bytes32& salt, const std::vector<std::uint8_t>& code);
125
126 void deploy_contract(evmc::address addr, std::vector<std::uint8_t>&& code, evmc_uint256be value, evmc::address creator, std::uint64_t nonce);
127
128 private:
129 evmc::VM & _vm;
130 evmc_revision _revision;
131
132 absl::flat_hash_map<std::string, Account> _accounts;
133 absl::flat_hash_map<evmc::address, std::uint64_t> _create_nonce;
134
135 std::stack<evmc::address> _sender_stack;
136 };
137
138 template <typename H>
139 inline H AbslHashValue(H h, const evmc::address & addr)
140 {
141 return H::combine(std::move(h), addr.bytes);
142 }
143}
144
Definition evm_storage.hpp:37
void set_balance(const evmc::address &addr, std::uint64_t x) noexcept
Definition evm_storage.hpp:64
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:248
evmc::bytes32 get_block_hash(int64_t block_number) const noexcept override
Definition evm_storage.cpp:227
void set_transient_storage(const evmc::address &addr, const evmc::bytes32 &key, const evmc::bytes32 &value) noexcept override
Definition evm_storage.cpp:300
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:349
evmc_storage_status set_storage(const evmc::address &address, const evmc::bytes32 &key, const evmc::bytes32 &value) noexcept override
Definition evm_storage.cpp:27
evmc::uint256be get_balance(const evmc::address &addr) const noexcept override
Definition evm_storage.cpp:33
evmc::bytes32 get_transient_storage(const evmc::address &addr, const evmc::bytes32 &key) const noexcept override
Definition evm_storage.cpp:291
evmc_tx_context get_tx_context() const noexcept override
Definition evm_storage.cpp:189
evmc_address derive_create2_address(const evmc::address &sender, const evmc::bytes32 &salt, const std::vector< std::uint8_t > &code)
Definition evm_storage.cpp:328
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:62
evmc::Result call(const evmc_message &msg) noexcept override
Definition evm_storage.cpp:92
bool selfdestruct(const evmc::address &addr, const evmc::address &beneficiary) noexcept override
Definition evm_storage.cpp:79
evmc_access_status access_account(const evmc::address &addr) noexcept override
Definition evm_storage.cpp:277
evmc_access_status access_storage(const evmc::address &addr, const evmc::bytes32 &key) noexcept override
Definition evm_storage.cpp:284
evmc_address derive_create_address(const evmc::address &sender, std::uint64_t nonce)
Definition evm_storage.cpp:314
bool account_exists(const evmc::address &addr) const noexcept override
Definition evm_storage.cpp:11
bool add_account(const evmc::address &addr)
Definition evm_storage.hpp:53
std::string to_key(const evmc::address &addr) const
Definition evm_storage.cpp:309
evmc::bytes32 get_code_hash(const evmc::address &addr) const noexcept override
Definition evm_storage.cpp:48
evmc::bytes32 get_storage(const evmc::address &addr, const evmc::bytes32 &key) const noexcept override
Definition evm_storage.cpp:16
std::size_t get_code_size(const evmc::address &addr) const noexcept override
Definition evm_storage.cpp:43
Definition evm.hpp:43
const std::uint64_t DEFAULT_GAS_LIMIT
Definition evm_storage.hpp:34
H AbslHashValue(H h, const evmc::address &addr)
Definition evm_storage.hpp:139
Definition evm_storage.hpp:40
uint64_t timestamp
Definition evm_storage.hpp:48
evmc::address creator
Definition evm_storage.hpp:46
std::vector< std::uint8_t > code
Definition evm_storage.hpp:42
uint64_t nonce
Definition evm_storage.hpp:47
evmc_uint256be balance
Definition evm_storage.hpp:41
absl::flat_hash_map< evmc::bytes32, evmc::bytes32 > storage
Definition evm_storage.hpp:43