25 #include <boost/algorithm/string.hpp> 46 <<
"Usage ethvm <options> [trace|stats|output|test] (<file>|-)" << endl
47 <<
"Transaction options:" << endl
48 <<
" --value <n> Transaction should transfer the <n> wei (default: 0)." << endl
49 <<
" --gas <n> Transaction should be given <n> gas (default: block gas limit)." << endl
50 <<
" --gas-limit <n> Block gas limit (default: " << MaxBlockGasLimit <<
")." << endl
51 <<
" --gas-price <n> Transaction's gas price' should be <n> (default: 0)." << endl
52 <<
" --sender <a> Transaction sender should be <a> (default: 0000...0069)." << endl
53 <<
" --origin <a> Transaction origin should be <a> (default: 0000...0069)." << endl
54 <<
" --input <d> Transaction code should be <d>" << endl
55 <<
" --code <d> Contract code <d>. Makes transaction a call to this contract" << endl
58 <<
"VM options:" << endl
59 <<
" --vm <vm-kind> Select VM. Options are: interpreter, jit, smart. (default: interpreter)" << endl
61 <<
"Network options:" << endl
62 <<
" --network Main|Ropsten|Homestead|Frontier" << endl
64 <<
"Options for trace:" << endl
65 <<
" --flat Minimal whitespace in the JSON." << endl
66 <<
" --mnemonics Show instruction mnemonics in the trace (non-standard)." << endl
68 <<
"General options:" << endl
69 <<
" -V,--version Show the version and exit." << endl
70 <<
" -h,--help Show this help message and exit." << endl;
77 cout <<
"By Gav Wood, 2015." << endl;
78 cout <<
"Build: " <<
DEV_QUOTED(ETH_BUILD_PLATFORM) <<
"/" <<
DEV_QUOTED(ETH_BUILD_TYPE) << endl;
98 if (!std::setlocale(LC_ALL,
""))
100 setenv(
"LC_ALL",
"C", 1);
117 int main(
int argc,
char** argv)
122 VMKind vmKind = VMKind::Interpreter;
127 u256 gas = MaxBlockGasLimit;
129 bool styledJson =
true;
132 Network networkName = Network::MainNetwork;
140 for (
int i = 1; i < argc; ++i)
142 string arg = argv[i];
143 if (arg ==
"-h" || arg ==
"--help")
145 else if (arg ==
"-V" || arg ==
"--version")
147 else if (arg ==
"--vm" && i + 1 < argc)
149 string vmKindStr = argv[++i];
150 if (vmKindStr ==
"interpreter")
151 vmKind = VMKind::Interpreter;
153 else if (vmKindStr ==
"jit")
154 vmKind = VMKind::JIT;
155 else if (vmKindStr ==
"smart")
156 vmKind = VMKind::Smart;
160 cerr <<
"Unknown/unsupported VM kind: " << vmKindStr << endl;
164 else if (arg ==
"--mnemonics")
166 else if (arg ==
"--flat")
168 else if (arg ==
"--sender" && i + 1 < argc)
170 else if (arg ==
"--origin" && i + 1 < argc)
172 else if (arg ==
"--gas" && i + 1 < argc)
173 gas =
u256(argv[++i]);
174 else if (arg ==
"--gas-price" && i + 1 < argc)
175 gasPrice =
u256(argv[++i]);
176 else if (arg ==
"--author" && i + 1 < argc)
178 else if (arg ==
"--number" && i + 1 < argc)
180 else if (arg ==
"--difficulty" && i + 1 < argc)
182 else if (arg ==
"--timestamp" && i + 1 < argc)
184 else if (arg ==
"--gas-limit" && i + 1 < argc)
186 else if (arg ==
"--value" && i + 1 < argc)
187 value =
u256(argv[++i]);
188 else if (arg ==
"--network" && i + 1 < argc)
190 string network = argv[++i];
191 if (network ==
"Frontier")
192 networkName = Network::FrontierTest;
193 else if (network ==
"Ropsten")
194 networkName = Network::Ropsten;
195 else if (network ==
"Homestead")
196 networkName = Network::HomesteadTest;
197 else if (network ==
"Main")
198 networkName = Network::MainNetwork;
201 cerr <<
"Unknown network type: " << network << endl;
205 else if (arg ==
"stats")
207 else if (arg ==
"output")
209 else if (arg ==
"trace")
211 else if (arg ==
"test")
213 else if (arg ==
"--input" && i + 1 < argc)
215 else if (arg ==
"--code" && i + 1 < argc)
217 else if (inputFile.empty())
221 cerr <<
"Unknown argument: " << arg <<
'\n';
226 VMFactory::setKind(vmKind);
230 if (!inputFile.empty())
233 cerr <<
"--code argument overwritten by input file " 234 << inputFile <<
'\n';
236 if (inputFile ==
"-")
237 for (
int i = cin.get(); i != -1; i = cin.get())
238 code.push_back((
char)i);
244 std::string strCode{
reinterpret_cast<char const*
>(code.data()), code.size()};
245 strCode.erase(strCode.find_last_not_of(
" \t\n\r") + 1);
246 code =
fromHex(strCode, WhenError::Throw);
248 catch (BadHexCharacter
const&) {}
252 Address contractDestination(
"1122334455667788991011121314151617181920");
258 std::unordered_map<Address, Account> map;
259 map[contractDestination] = account;
261 t =
Transaction(value, gasPrice, gas, contractDestination, data, 0);
271 Executive executive(state, envInfo, *se);
276 unordered_map<byte, pair<unsigned, bigint>> counts;
282 counts[(
byte)inst].first++;
283 counts[(
byte)inst].second += gasCost;
289 st(step, PC, inst, m, gasCost, gas, vm, extVM);
294 executive.
call(contractDestination, sender, value, gasPrice, &data, gas);
296 executive.
create(sender, value, gasPrice, gas, &data, origin);
304 double execTime = timer.
elapsed();
311 cout <<
"Output: " <<
toHex(output) << endl;
313 cout << logs.size() <<
" logs" << (logs.empty() ?
"." :
":") << endl;
316 cout <<
" " << l.address.hex() <<
": " <<
toHex(t.
data()) << endl;
317 for (
h256 const& t: l.topics)
318 cout <<
" " << t.
hex() << endl;
321 cout << total <<
" operations in " << execTime <<
" seconds." << endl;
322 cout <<
"Maximum memory usage: " << memTotal * 32 <<
" bytes" << endl;
323 cout <<
"Expensive operations:" << endl;
324 for (
auto const&
c: {Instruction::SSTORE, Instruction::SLOAD, Instruction::CALL, Instruction::CREATE, Instruction::CALLCODE, Instruction::DELEGATECALL, Instruction::MSTORE8, Instruction::MSTORE, Instruction::MLOAD, Instruction::SHA3})
325 if (!!counts[(
byte)
c].first)
329 cout << st.
json(styledJson);
331 cout <<
toHex(output) <<
'\n';
336 auto exception = res.
excepted != TransactionException::None;
337 cout <<
"output: '" <<
toHex(output) <<
"'\n";
338 cout <<
"exception: " << boolalpha << exception <<
'\n';
339 cout <<
"gas used: " << res.
gasUsed <<
'\n';
340 cout <<
"gas/sec: " << scientific << setprecision(3) << uint64_t(res.
gasUsed)/execTime <<
'\n';
341 cout <<
"exec time: " << fixed << setprecision(6) << execTime <<
'\n';
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
bool call(Address _receiveAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas)
Set up the executive for evaluating a bare CALL (message call) operation.
bool create(Address _txSender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _code, Address _originAddress)
Set up the executive for evaluating a bare CREATE (contract-creation) operation.
std::string toHex(T const &_data, int _w=2, HexPrefix _prefix=HexPrefix::DontAdd)
boost::multiprecision::number< boost::multiprecision::cpp_int_backend<>> bigint
Models the state of a single Ethereum account.
h160 Address
An Ethereum address: 20 bytes.
std::hash for asio::adress
Test mode ā output information needed for test verification and benchmarking.
void setGasLimit(int64_t _v)
int64_t baseGasRequired(EVMSchedule const &_es) const
Description of the result of executing a transaction.
Model of an Ethereum state, essentially a facade for the trie.
bool go(OnOpFunc const &_onOp=OnOpFunc())
Executes (or continues execution of) the VM.
void populateFrom(AccountMap const &_map)
Populate the state from the given AccountMap. Just uses dev::eth::commit().
InstructionInfo instructionInfo(Instruction _inst)
Information on all the instructions.
bytes fromHex(std::string const &_s, WhenError _throw=WhenError::DontThrow)
void setDefaultOrCLocale()
std::string json(bool _styled=false) const
std::string name
The name of the instruction.
int main(int argc, char **argv)
void setNewCode(bytes &&_code)
Sets the code of the account. Used by "create" messages.
void finalize()
Finalise a transaction previously set up with initialize().
void setTimestamp(u256 const &_v)
std::vector< byte > bytes
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
bytes const & data() const
void setNumber(u256 const &_v)
Message-call/contract-creation executor; useful for executing transactions.
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
LogEntries const & logs() const
Encodes a transaction, ready to be exported to or freshly imported from RLP.
TransactionException excepted
Instruction
Virtual machine bytecode instruction.
void initialize(bytesConstRef _transaction)
Initializes the executive for evaluating a transaction. You must call finalize() at some point follow...
Interface and null implementation of the class for specifying VM externalities.
u256 u256Param(std::string const &_name) const
Convenience method to get an otherParam as a u256 int.
std::string const & genesisInfo(Network _n)
void forceSender(Address const &_a)
Force the sender to a particular value. This will result in an invalid transaction RLP...
virtual void addBalance(Address const &_id, u256 const &_amount)
Add some amount to balance.
void setAuthor(Address const &_v)
void setDifficulty(u256 const &_v)
bytes contents(std::string const &_file)
Retrieve and returns the contents of the given file.
std::vector< LogEntry > LogEntries
void setResultRecipient(ExecutionResult &_res)
Collect execution results in the result storage provided.