35 namespace fs = boost::filesystem;
37 void Account::setCode(
bytes&& _code)
39 m_codeCache = std::move(_code);
41 m_codeHash =
sha3(m_codeCache);
46 auto it = m_storageOriginal.find(_key);
47 if (it != m_storageOriginal.end())
52 std::string
const payload = memdb.
at(_key);
53 auto const value = payload.size() ?
RLP(payload).
toInt<
u256>() : 0;
54 m_storageOriginal[_key] = value;
58 namespace js = json_spirit;
63 uint64_t toUnsigned(js::mValue
const& _v)
67 case js::int_type:
return _v.get_uint64();
68 case js::str_type:
return fromBigEndian<uint64_t>(
fromHex(_v.get_str()));
75 auto n = _precompiled.at(
"name").get_str();
78 u256 startingBlock = 0;
79 if (_precompiled.count(
"startingBlock"))
80 startingBlock =
u256(_precompiled.at(
"startingBlock").get_str());
82 if (!_precompiled.count(
"linear"))
83 return PrecompiledContract(PrecompiledRegistrar::pricer(n), PrecompiledRegistrar::executor(n), startingBlock);
85 auto const& l = _precompiled.at(
"linear").get_obj();
86 unsigned base = toUnsigned(l.at(
"base"));
87 unsigned word = toUnsigned(l.at(
"word"));
90 catch (PricerNotFound
const&)
92 cwarn <<
"Couldn't create a precompiled contract account. Missing a pricer called:" << n;
95 catch (ExecutorNotFound
const&)
98 cwarn <<
"Couldn't create a precompiled contract account. Missing an executor called:" << n;
108 auto u256Safe = [](std::string
const& s) ->
u256 {
110 if (ret >=
bigint(1) << 256)
111 BOOST_THROW_EXCEPTION(
112 ValueTooLarge() <<
errinfo_comment(
"State value is equal or greater than 2**256"));
116 std::unordered_map<Address, Account> ret;
119 json_spirit::read_string_or_throw(_json, val);
121 for (
auto const& account : val.get_obj())
124 auto const& accountMaskJson = account.second.get_obj();
126 bool haveBalance = (accountMaskJson.count(
c_wei) || accountMaskJson.count(
c_finney) ||
128 bool haveNonce = accountMaskJson.count(
c_nonce);
130 bool haveStorage = accountMaskJson.count(
c_storage);
133 if (haveStorage || haveCode || haveNonce || haveBalance)
136 if (accountMaskJson.count(
c_wei))
137 balance = u256Safe(accountMaskJson.at(
c_wei).get_str());
138 else if (accountMaskJson.count(
c_finney))
139 balance = u256Safe(accountMaskJson.at(
c_finney).get_str()) * finney;
140 else if (accountMaskJson.count(
c_balance))
141 balance = u256Safe(accountMaskJson.at(
c_balance).get_str());
144 haveNonce ? u256Safe(accountMaskJson.at(
c_nonce).get_str()) : _defaultNonce;
146 ret[a] =
Account(nonce, balance);
147 auto codeIt = accountMaskJson.find(
c_code);
148 if (codeIt != accountMaskJson.end())
150 auto& codeObj = codeIt->second;
151 if (codeObj.type() == json_spirit::str_type)
153 auto& codeStr = codeObj.get_str();
154 if (codeStr.find(
"0x") != 0 && !codeStr.empty())
155 cerr <<
"Error importing code of account " << a
156 <<
"! Code needs to be hex bytecode prefixed by \"0x\".";
158 ret[a].setCode(
fromHex(codeStr));
161 cerr <<
"Error importing code of account " << a
162 <<
"! Code field needs to be a string";
166 if (codePathIt != accountMaskJson.end())
168 auto& codePathObj = codePathIt->second;
169 if (codePathObj.type() == json_spirit::str_type)
171 fs::path codePath{codePathObj.get_str()};
172 if (codePath.is_relative())
173 codePath = _configPath.parent_path() / codePath;
176 cerr <<
"Error importing code of account " << a <<
"! Code file "
177 << codePath <<
" empty or does not exist.\n";
178 ret[a].setCode(std::move(code));
181 cerr <<
"Error importing code of account " << a
182 <<
"! Code file path must be a string\n";
186 for (pair<string, js::mValue>
const& j : accountMaskJson.at(
c_storage).get_obj())
187 ret[a].setStorage(
u256(j.first),
u256(j.second.get_str()));
193 AccountMask(haveBalance, haveNonce, haveCode, haveStorage, shouldNotExists);
194 if (!haveStorage && !haveCode && !haveNonce && !haveBalance &&
202 o_precompiled->insert(make_pair(a, createPrecompiledContract(p)));