/* This file is part of cpp-ethereum. cpp-ethereum is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. cpp-ethereum is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cpp-ethereum. If not, see . */ /** @file main.cpp * @author Gav Wood * @date 2014 * Ethereum client. */ #include #include #include #include #include "Defaults.h" #include "Client.h" #include "PeerNetwork.h" #include "BlockChain.h" #include "State.h" #include "FileSystem.h" #include "Instruction.h" #include "BuildInfo.h" using namespace std; using namespace eth; using eth::Instruction; using eth::c_instructionInfo; bool isTrue(std::string const& _m) { return _m == "on" || _m == "yes" || _m == "true" || _m == "1"; } bool isFalse(std::string const& _m) { return _m == "off" || _m == "no" || _m == "false" || _m == "0"; } void help() { cout << "Usage eth [OPTIONS] " << endl << "Options:" << endl << " -a,--address Set the coinbase (mining payout) address to addr (default: auto)." << endl << " -c,--client-name Add a name to your client's version string (default: blank)." << endl << " -d,--db-path Load database from path (default: ~/.ethereum " << endl << " /Etherum or Library/Application Support/Ethereum)." << endl << " -h,--help Show this help message and exit." << endl << " -i,--interactive Enter interactive mode (default: non-interactive)." << endl << " -l,--listen Listen on the given port for incoming connected (default: 30303)." << endl << " -m,--mining Enable mining, optionally for a specified number of blocks (Default: off)" << endl << " -n,--upnp Use upnp for NAT (default: on)." << endl << " -o,--mode Start a full node or a peer node (Default: full)." << endl << " -p,--port Connect to remote port (default: 30303)." << endl << " -r,--remote Connect to remote host (default: none)." << endl << " -s,--secret Set the secret key for use with send command (default: auto)." << endl << " -u,--public-ip Force public ip to given (default; auto)." << endl << " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (Default: 8)." << endl << " -x,--peers Attempt to connect to given number of peers (Default: 5)." << endl << " -V,--version Show the version and exit." << endl; exit(0); } string credits(bool _interactive = false) { std::ostringstream ccout; ccout << "Ethereum (++) " << ETH_QUOTED(ETH_VERSION) << endl << " Code by Gav Wood, (c) 2013, 2014." << endl << " Based on a design by Vitalik Buterin." << endl << endl; if (_interactive) { string vs = toString(ETH_QUOTED(ETH_VERSION)); vs = vs.substr(vs.find_first_of('.') + 1)[0]; int pocnumber = stoi(vs); string m_servers; if (pocnumber == 3) m_servers = "54.201.28.117"; if (pocnumber == 4) m_servers = "54.72.31.55"; ccout << "Type 'netstart 30303' to start networking" << endl; ccout << "Type 'connect " << m_servers << " 30303' to connect" << endl; ccout << "Type 'exit' to quit" << endl << endl; } return ccout.str(); } void version() { cout << "eth version " << ETH_QUOTED(ETH_VERSION) << endl; cout << "Build: " << ETH_QUOTED(ETH_BUILD_PLATFORM) << "/" << ETH_QUOTED(ETH_BUILD_TYPE) << endl; exit(0); } u256 c_minGasPrice = 10000000000000; u256 c_minGas = 100; Address c_config = Address("ccdeac59d35627b7de09332e819d5159e7bb7250"); string pretty(h160 _a, eth::State _st) { string ns; h256 n; if (h160 nameReg = (u160)_st.contractStorage(c_config, 0)) n = _st.contractStorage(nameReg, (u160)(_a)); if (n) { std::string s((char const*)n.data(), 32); if (s.find_first_of('\0') != string::npos) s.resize(s.find_first_of('\0')); ns = " " + s; } return ns; } int main(int argc, char** argv) { unsigned short listenPort = 30303; string remoteHost; unsigned short remotePort = 30303; string dbPath; eth::uint mining = ~(eth::uint)0; NodeMode mode = NodeMode::Full; unsigned peers = 5; string publicIP; bool upnp = true; string clientName; // Init defaults Defaults::get(); // Our address. KeyPair us = KeyPair::create(); Address coinbase = us.address(); string configFile = getDataDir() + "/config.rlp"; bytes b = contents(configFile); if (b.size()) { RLP config(b); us = KeyPair(config[0].toHash()); coinbase = config[1].toHash
(); } else { RLPStream config(2); config << us.secret() << coinbase; writeFile(configFile, config.out()); } for (int i = 1; i < argc; ++i) { string arg = argv[i]; if ((arg == "-l" || arg == "--listen" || arg == "--listen-port") && i + 1 < argc) listenPort = (short)atoi(argv[++i]); else if ((arg == "-u" || arg == "--public-ip" || arg == "--public") && i + 1 < argc) publicIP = argv[++i]; else if ((arg == "-r" || arg == "--remote") && i + 1 < argc) remoteHost = argv[++i]; else if ((arg == "-p" || arg == "--port") && i + 1 < argc) remotePort = (short)atoi(argv[++i]); else if ((arg == "-n" || arg == "--upnp") && i + 1 < argc) { string m = argv[++i]; if (isTrue(m)) upnp = true; else if (isFalse(m)) upnp = false; else { cerr << "Invalid UPnP option: " << m << endl; return -1; } } else if ((arg == "-c" || arg == "--client-name") && i + 1 < argc) clientName = argv[++i]; else if ((arg == "-a" || arg == "--address" || arg == "--coinbase-address") && i + 1 < argc) coinbase = h160(fromHex(argv[++i])); else if ((arg == "-s" || arg == "--secret") && i + 1 < argc) us = KeyPair(h256(fromHex(argv[++i]))); else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc) dbPath = argv[++i]; else if ((arg == "-m" || arg == "--mining") && i + 1 < argc) { string m = argv[++i]; if (isTrue(m)) mining = ~(eth::uint)0; else if (isFalse(m)) mining = 0; else if (int i = stoi(m)) mining = i; else { cerr << "Unknown mining option: " << m << endl; return -1; } } else if ((arg == "-v" || arg == "--verbosity") && i + 1 < argc) g_logVerbosity = atoi(argv[++i]); else if ((arg == "-x" || arg == "--peers") && i + 1 < argc) peers = atoi(argv[++i]); else if ((arg == "-o" || arg == "--mode") && i + 1 < argc) { string m = argv[++i]; if (m == "full") mode = NodeMode::Full; else if (m == "peer") mode = NodeMode::PeerServer; else { cerr << "Unknown mode: " << m << endl; return -1; } } else if (arg == "-h" || arg == "--help") help(); else if (arg == "-V" || arg == "--version") version(); else remoteHost = argv[i]; } if (!clientName.empty()) clientName += "/"; Client c("Ethereum(++)/" + clientName + "v" ETH_QUOTED(ETH_VERSION) "/" ETH_QUOTED(ETH_BUILD_TYPE) "/" ETH_QUOTED(ETH_BUILD_PLATFORM), coinbase, dbPath); cout << credits(); cout << "Address: " << endl << toHex(us.address().asArray()) << endl; c.startNetwork(listenPort, remoteHost, remotePort, mode, peers, publicIP, upnp); eth::uint n = c.blockChain().details().number; if (mining) c.startMining(); while (true) { if (c.blockChain().details().number - n == mining) c.stopMining(); this_thread::sleep_for(chrono::milliseconds(100)); } return 0; }