diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index de8e862ab..7ed961a77 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -279,7 +279,7 @@ Address Main::getNameReg() const Address Main::getCurrencies() const { - return abiOut
(ethereum()->call(c_newConfig, abiIn("lookup(uint256)", (u256)2))); + return abiOut
(ethereum()->call(c_newConfig, abiIn("lookup(uint256)", (u256)3))); } void Main::installNameRegWatch() @@ -343,6 +343,9 @@ void Main::onNewBlock() refreshBlockCount(); refreshBlockChain(); refreshAccounts(); + + // We must update balances since we can't filter updates to basic accounts. + refreshBalances(); } void Main::onNewPending() @@ -2140,7 +2143,9 @@ QString Main::prettyU256(dev::u256 _n) const unsigned inc = 0; QString raw; ostringstream s; - if (!(_n >> 64)) + if (_n > szabo && _n < 1000000 * ether) + s << "" << formatBalance(_n) << " (0x" << hex << (uint64_t)_n << ")"; + else if (!(_n >> 64)) s << "" << (uint64_t)_n << " (0x" << hex << (uint64_t)_n << ")"; else if (!~(_n >> 64)) s << "" << (int64_t)_n << " (0x" << hex << (int64_t)_n << ")"; diff --git a/exp/main.cpp b/exp/main.cpp index e714f29da..80f4fa37d 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -75,7 +75,7 @@ int main() cnote << i;*/ return 0; } -#else +#elif 0 int main() { KeyPair u = KeyPair::create(); @@ -95,5 +95,11 @@ int main() cnote << "State after transaction: " << s; cnote << before.diff(s); } +#else +int main() +{ + cnote << KeyPair(Secret("0000000000000000000000000000000000000000000000000000000000000000")).address(); + cnote << KeyPair(Secret("1111111111111111111111111111111111111111111111111111111111111111")).address(); +} #endif diff --git a/libdevcrypto/CryptoPP.cpp b/libdevcrypto/CryptoPP.cpp index acd59184f..2d0170fb9 100644 --- a/libdevcrypto/CryptoPP.cpp +++ b/libdevcrypto/CryptoPP.cpp @@ -199,6 +199,8 @@ bool Secp256k1::verifySecret(Secret const& _s, Public& _p) void Secp256k1::agree(Secret const& _s, Public const& _r, h256& o_s) { + (void)o_s; + (void)_s; ECDH::Domain d(m_oid); assert(d.AgreedValueLength() == sizeof(o_s)); byte remote[65] = {0x04}; diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index c4ce543d6..4eed2b284 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -35,7 +35,7 @@ using namespace dev::eth; Executive::Executive(State& _s, BlockChain const& _bc, unsigned _level): m_s(_s), - m_lastHashes(_s.getLastHashes(_bc)), + m_lastHashes(_s.getLastHashes(_bc, (unsigned)_s.info().number - 1)), m_depth(_level) {} diff --git a/libethereum/State.cpp b/libethereum/State.cpp index 3c59bf415..9ed9a3a3a 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -418,7 +418,7 @@ TransactionReceipts State::sync(BlockChain const& _bc, TransactionQueue& _tq, bo TransactionReceipts ret; auto ts = _tq.transactions(); - auto lh = getLastHashes(_bc); + auto lh = getLastHashes(_bc, _bc.number()); for (int goodTxs = 1; goodTxs;) { @@ -498,7 +498,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce) GenericTrieDB receiptsTrie(&rm); receiptsTrie.init(); - LastHashes lh = getLastHashes(_bc); + LastHashes lh = getLastHashes(_bc, (unsigned)m_previousBlock.number); // All ok with the block generally. Play back the transactions now... unsigned i = 0; @@ -527,7 +527,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce) cwarn << "Bad receipts state root."; cwarn << "Block:" << toHex(_block); cwarn << "Block RLP:" << RLP(_block); - cwarn << "Want: " << receiptsTrie.root() << ", got: " << m_currentBlock.receiptsRoot; + cwarn << "Calculated: " << receiptsTrie.root(); for (unsigned j = 0; j < i; ++j) { RLPStream k; @@ -538,6 +538,16 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce) cwarn << "Hex: " << toHex(b); cwarn << TransactionReceipt(&b); } + cwarn << "Recorded: " << m_currentBlock.receiptsRoot; + auto rs = _bc.receipts(m_currentBlock.hash); + for (unsigned j = 0; j < rs.receipts.size(); ++j) + { + auto b = rs.receipts[j].rlp(); + cwarn << j << ": "; + cwarn << "RLP: " << RLP(b); + cwarn << "Hex: " << toHex(b); + cwarn << rs.receipts[j]; + } BOOST_THROW_EXCEPTION(InvalidReceiptsStateRoot()); } @@ -1000,19 +1010,29 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const return true; } -LastHashes State::getLastHashes(BlockChain const& _bc) const +LastHashes State::getLastHashes(BlockChain const& _bc, unsigned _n) const { LastHashes ret; ret.resize(256); if (c_protocolVersion > 49) { - ret[0] = _bc.currentHash(); + ret[0] = _bc.numberHash(_n); for (unsigned i = 1; i < 256; ++i) ret[i] = ret[i - 1] ? _bc.details(ret[i - 1]).parent : h256(); } return ret; } +u256 State::execute(BlockChain const& _bc, bytes const& _rlp, bytes* o_output, bool _commit) +{ + return execute(getLastHashes(_bc, _bc.number()), &_rlp, o_output, _commit); +} + +u256 State::execute(BlockChain const& _bc, bytesConstRef _rlp, bytes* o_output, bool _commit) +{ + return execute(getLastHashes(_bc, _bc.number()), _rlp, o_output, _commit); +} + // TODO: maintain node overlay revisions for stateroots -> each commit gives a stateroot + OverlayDB; allow overlay copying for rewind operations. u256 State::execute(LastHashes const& _lh, bytesConstRef _rlp, bytes* o_output, bool _commit) { diff --git a/libethereum/State.h b/libethereum/State.h index e7e1bbfab..85abd9366 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -147,12 +147,12 @@ public: /// Like sync but only operate on _tq, killing the invalid/old ones. bool cull(TransactionQueue& _tq) const; - LastHashes getLastHashes(BlockChain const& _bc) const; + LastHashes getLastHashes(BlockChain const& _bc, unsigned _n) const; /// Execute a given transaction. /// This will append @a _t to the transaction list and change the state accordingly. - u256 execute(BlockChain const& _bc, bytes const& _rlp, bytes* o_output = nullptr, bool _commit = true) { return execute(getLastHashes(_bc), &_rlp, o_output, _commit); } - u256 execute(BlockChain const& _bc, bytesConstRef _rlp, bytes* o_output = nullptr, bool _commit = true) { return execute(getLastHashes(_bc), _rlp, o_output, _commit); } + u256 execute(BlockChain const& _bc, bytes const& _rlp, bytes* o_output = nullptr, bool _commit = true); + u256 execute(BlockChain const& _bc, bytesConstRef _rlp, bytes* o_output = nullptr, bool _commit = true); u256 execute(LastHashes const& _lh, bytes const& _rlp, bytes* o_output = nullptr, bool _commit = true) { return execute(_lh, &_rlp, o_output, _commit); } u256 execute(LastHashes const& _lh, bytesConstRef _rlp, bytes* o_output = nullptr, bool _commit = true); diff --git a/libqwebthree/QWebThree.cpp b/libqwebthree/QWebThree.cpp index 891d84ffa..3f4b5c67d 100644 --- a/libqwebthree/QWebThree.cpp +++ b/libqwebthree/QWebThree.cpp @@ -140,7 +140,7 @@ void QWebThree::onDataProcessed(QString _json, QString _addInfo) for (int i = 0; i < resultsArray.size(); i++) { QJsonObject elem = resultsArray[i].toObject(); - if (elem.contains("result")) + if (elem["result"].isArray() && elem["result"].toArray().size() > 0) { QJsonObject res; res["_event"] = _addInfo; diff --git a/libsolidity/ASTJsonConverter.cpp b/libsolidity/ASTJsonConverter.cpp new file mode 100644 index 000000000..04ddee0a7 --- /dev/null +++ b/libsolidity/ASTJsonConverter.cpp @@ -0,0 +1,471 @@ +/* + 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 . +*/ +/** + * @author Lefteris + * @date 2015 + * Converts the AST into json format + */ + +#include +#include + +using namespace std; + +namespace dev +{ +namespace solidity +{ + +void ASTJsonConverter::addKeyValue(Json::Value& _obj, string const& _key, string const& _val) +{ + // special handling for booleans + if (_key == "const" || _key == "public" || _key == "local" || + _key == "lvalue" || _key == "local_lvalue" || _key == "prefix") + _obj[_key] = (_val == "1") ? true : false; + else + // else simply add it as a string + _obj[_key] = _val; +} + +void ASTJsonConverter::addJsonNode(string const& _nodeName, + initializer_list> _list, + bool _hasChildren = false) +{ + Json::Value node; + + node["name"] = _nodeName; + if (_list.size() != 0) + { + Json::Value attrs; + for (auto& e: _list) + addKeyValue(attrs, e.first, e.second); + node["attributes"] = attrs; + } + + m_jsonNodePtrs.top()->append(node); + + if (_hasChildren) + { + Json::Value& addedNode = (*m_jsonNodePtrs.top())[m_jsonNodePtrs.top()->size() - 1]; + Json::Value children(Json::arrayValue); + addedNode["children"] = children; + m_jsonNodePtrs.push(&addedNode["children"]); + } +} + +ASTJsonConverter::ASTJsonConverter(ASTNode const& _ast): m_ast(&_ast) +{ + Json::Value children(Json::arrayValue); + + m_astJson["name"] = "root"; + m_astJson["children"] = children; + m_jsonNodePtrs.push(&m_astJson["children"]); +} + +void ASTJsonConverter::print(ostream& _stream) +{ + m_ast->accept(*this); + _stream << m_astJson; +} + +bool ASTJsonConverter::visit(ImportDirective const& _node) +{ + addJsonNode("Import", { make_pair("file", _node.getIdentifier())}); + return true; +} + +bool ASTJsonConverter::visit(ContractDefinition const& _node) +{ + addJsonNode("Contract", { make_pair("name", _node.getName()) }, true); + return true; +} + +bool ASTJsonConverter::visit(StructDefinition const& _node) +{ + addJsonNode("Struct", { make_pair("name", _node.getName()) }, true); + return true; +} + +bool ASTJsonConverter::visit(ParameterList const&) +{ + addJsonNode("ParameterList", {}, true); + return true; +} + +bool ASTJsonConverter::visit(FunctionDefinition const& _node) +{ + addJsonNode("Function", + { make_pair("name", _node.getName()), + make_pair("public", boost::lexical_cast(_node.isPublic())), + make_pair("const", boost::lexical_cast(_node.isDeclaredConst())) }, + true); + return true; +} + +bool ASTJsonConverter::visit(VariableDeclaration const& _node) +{ + addJsonNode("VariableDeclaration", + { make_pair("name", _node.getName()), + make_pair("local", boost::lexical_cast(_node.isLocalVariable()))}, + true); + return true; +} + +bool ASTJsonConverter::visit(TypeName const&) +{ + return true; +} + +bool ASTJsonConverter::visit(ElementaryTypeName const& _node) +{ + addJsonNode("ElementaryTypeName", { make_pair("name", Token::toString(_node.getTypeName())) }); + return true; +} + +bool ASTJsonConverter::visit(UserDefinedTypeName const& _node) +{ + addJsonNode("UserDefinedTypeName", { make_pair("name", _node.getName()) }); + return true; +} + +bool ASTJsonConverter::visit(Mapping const&) +{ + addJsonNode("Mapping", {}, true); + return true; +} + +bool ASTJsonConverter::visit(Statement const&) +{ + addJsonNode("Statement", {}, true); + return true; +} + +bool ASTJsonConverter::visit(Block const&) +{ + addJsonNode("Block", {}, true); + return true; +} + +bool ASTJsonConverter::visit(IfStatement const&) +{ + addJsonNode("IfStatement", {}, true); + return true; +} + +bool ASTJsonConverter::visit(BreakableStatement const&) +{ + return true; +} + +bool ASTJsonConverter::visit(WhileStatement const&) +{ + addJsonNode("WhileStatement", {}, true); + return true; +} + +bool ASTJsonConverter::visit(ForStatement const&) +{ + addJsonNode("ForStatement", {}, true); + return true; +} + +bool ASTJsonConverter::visit(Continue const&) +{ + addJsonNode("Continue", {}); + return true; +} + +bool ASTJsonConverter::visit(Break const&) +{ + addJsonNode("Break", {}); + return true; +} + +bool ASTJsonConverter::visit(Return const&) +{ + addJsonNode("Return", {}, true);; + return true; +} + +bool ASTJsonConverter::visit(VariableDefinition const&) +{ + addJsonNode("VariableDefinition", {}, true); + return true; +} + +bool ASTJsonConverter::visit(ExpressionStatement const&) +{ + addJsonNode("ExpressionStatement", {}, true); + return true; +} + +bool ASTJsonConverter::visit(Expression const& _node) +{ + addJsonNode("Expression", + { make_pair("type", getType(_node)), + make_pair("lvalue", boost::lexical_cast(_node.isLValue())), + make_pair("local_lvalue", boost::lexical_cast(_node.isLocalLValue())) }, + true); + return true; +} + +bool ASTJsonConverter::visit(Assignment const& _node) +{ + addJsonNode("Assignment", + { make_pair("operator", Token::toString(_node.getAssignmentOperator())), + make_pair("type", getType(_node)) }, + true); + return true; +} + +bool ASTJsonConverter::visit(UnaryOperation const& _node) +{ + addJsonNode("UnaryOperation", + { make_pair("prefix", boost::lexical_cast(_node.isPrefixOperation())), + make_pair("operator", Token::toString(_node.getOperator())), + make_pair("type", getType(_node)) }, + true); + return true; +} + +bool ASTJsonConverter::visit(BinaryOperation const& _node) +{ + addJsonNode("BinaryOperation", + { make_pair("operator", Token::toString(_node.getOperator())), + make_pair("type", getType(_node))}, + true); + return true; +} + +bool ASTJsonConverter::visit(FunctionCall const& _node) +{ + addJsonNode("FunctionCall", + { make_pair("type_conversion", boost::lexical_cast(_node.isTypeConversion())), + make_pair("type", getType(_node)) }, + true); + return true; +} + +bool ASTJsonConverter::visit(NewExpression const& _node) +{ + addJsonNode("NewExpression", { make_pair("type", getType(_node)) }, true); + return true; +} + +bool ASTJsonConverter::visit(MemberAccess const& _node) +{ + addJsonNode("MemberAccess", + { make_pair("member_name", _node.getMemberName()), + make_pair("type", getType(_node)) }, + true); + return true; +} + +bool ASTJsonConverter::visit(IndexAccess const& _node) +{ + addJsonNode("IndexAccess", { make_pair("type", getType(_node)) }, true); + return true; +} + +bool ASTJsonConverter::visit(PrimaryExpression const&) +{ + return true; +} + +bool ASTJsonConverter::visit(Identifier const& _node) +{ + addJsonNode("Identifier", + { make_pair("value", _node.getName()), make_pair("type", getType(_node)) }); + return true; +} + +bool ASTJsonConverter::visit(ElementaryTypeNameExpression const& _node) +{ + addJsonNode("ElementaryTypenameExpression", + { make_pair("value", Token::toString(_node.getTypeToken())), make_pair("type", getType(_node)) }); + return true; +} + +bool ASTJsonConverter::visit(Literal const& _node) +{ + char const* tokenString = Token::toString(_node.getToken()); + addJsonNode("Literal", + { make_pair("string", (tokenString) ? tokenString : "null"), + make_pair("value", _node.getValue()), + make_pair("type", getType(_node)) }); + return true; +} + +void ASTJsonConverter::endVisit(ImportDirective const&) +{ +} + +void ASTJsonConverter::endVisit(ContractDefinition const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(StructDefinition const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(ParameterList const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(FunctionDefinition const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(VariableDeclaration const&) +{ +} + +void ASTJsonConverter::endVisit(TypeName const&) +{ +} + +void ASTJsonConverter::endVisit(ElementaryTypeName const&) +{ +} + +void ASTJsonConverter::endVisit(UserDefinedTypeName const&) +{ +} + +void ASTJsonConverter::endVisit(Mapping const&) +{ +} + +void ASTJsonConverter::endVisit(Statement const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(Block const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(IfStatement const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(BreakableStatement const&) +{ +} + +void ASTJsonConverter::endVisit(WhileStatement const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(ForStatement const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(Continue const&) +{ +} + +void ASTJsonConverter::endVisit(Break const&) +{ +} + +void ASTJsonConverter::endVisit(Return const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(VariableDefinition const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(ExpressionStatement const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(Expression const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(Assignment const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(UnaryOperation const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(BinaryOperation const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(FunctionCall const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(NewExpression const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(MemberAccess const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(IndexAccess const&) +{ + goUp(); +} + +void ASTJsonConverter::endVisit(PrimaryExpression const&) +{ +} + +void ASTJsonConverter::endVisit(Identifier const&) +{ +} + +void ASTJsonConverter::endVisit(ElementaryTypeNameExpression const&) +{ +} + +void ASTJsonConverter::endVisit(Literal const&) +{ +} + +string ASTJsonConverter::getType(Expression const& _expression) +{ + return (_expression.getType()) ? _expression.getType()->toString() : "Unknown"; +} + +} +} diff --git a/libsolidity/ASTJsonConverter.h b/libsolidity/ASTJsonConverter.h new file mode 100644 index 000000000..7d9b9bc04 --- /dev/null +++ b/libsolidity/ASTJsonConverter.h @@ -0,0 +1,136 @@ +/* + 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 . +*/ +/** + * @author Lefteris + * @date 2015 + * Converts the AST into json format + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace dev +{ +namespace solidity +{ + +/** + * Converter of the AST into JSON format + */ +class ASTJsonConverter: public ASTConstVisitor +{ +public: + /// Create a converter to JSON for the given abstract syntax tree. + ASTJsonConverter(ASTNode const& _ast); + /// Output the json representation of the AST to _stream. + void print(std::ostream& _stream); + + bool visit(ImportDirective const& _node) override; + bool visit(ContractDefinition const& _node) override; + bool visit(StructDefinition const& _node) override; + bool visit(ParameterList const& _node) override; + bool visit(FunctionDefinition const& _node) override; + bool visit(VariableDeclaration const& _node) override; + bool visit(TypeName const& _node) override; + bool visit(ElementaryTypeName const& _node) override; + bool visit(UserDefinedTypeName const& _node) override; + bool visit(Mapping const& _node) override; + bool visit(Statement const& _node) override; + bool visit(Block const& _node) override; + bool visit(IfStatement const& _node) override; + bool visit(BreakableStatement const& _node) override; + bool visit(WhileStatement const& _node) override; + bool visit(ForStatement const& _node) override; + bool visit(Continue const& _node) override; + bool visit(Break const& _node) override; + bool visit(Return const& _node) override; + bool visit(VariableDefinition const& _node) override; + bool visit(ExpressionStatement const& _node) override; + bool visit(Expression const& _node) override; + bool visit(Assignment const& _node) override; + bool visit(UnaryOperation const& _node) override; + bool visit(BinaryOperation const& _node) override; + bool visit(FunctionCall const& _node) override; + bool visit(NewExpression const& _node) override; + bool visit(MemberAccess const& _node) override; + bool visit(IndexAccess const& _node) override; + bool visit(PrimaryExpression const& _node) override; + bool visit(Identifier const& _node) override; + bool visit(ElementaryTypeNameExpression const& _node) override; + bool visit(Literal const& _node) override; + + void endVisit(ImportDirective const&) override; + void endVisit(ContractDefinition const&) override; + void endVisit(StructDefinition const&) override; + void endVisit(ParameterList const&) override; + void endVisit(FunctionDefinition const&) override; + void endVisit(VariableDeclaration const&) override; + void endVisit(TypeName const&) override; + void endVisit(ElementaryTypeName const&) override; + void endVisit(UserDefinedTypeName const&) override; + void endVisit(Mapping const&) override; + void endVisit(Statement const&) override; + void endVisit(Block const&) override; + void endVisit(IfStatement const&) override; + void endVisit(BreakableStatement const&) override; + void endVisit(WhileStatement const&) override; + void endVisit(ForStatement const&) override; + void endVisit(Continue const&) override; + void endVisit(Break const&) override; + void endVisit(Return const&) override; + void endVisit(VariableDefinition const&) override; + void endVisit(ExpressionStatement const&) override; + void endVisit(Expression const&) override; + void endVisit(Assignment const&) override; + void endVisit(UnaryOperation const&) override; + void endVisit(BinaryOperation const&) override; + void endVisit(FunctionCall const&) override; + void endVisit(NewExpression const&) override; + void endVisit(MemberAccess const&) override; + void endVisit(IndexAccess const&) override; + void endVisit(PrimaryExpression const&) override; + void endVisit(Identifier const&) override; + void endVisit(ElementaryTypeNameExpression const&) override; + void endVisit(Literal const&) override; + +private: + void addKeyValue(Json::Value& _obj, std::string const& _key, std::string const& _val); + void addJsonNode(std::string const& _nodeName, + std::initializer_list> _list, + bool _hasChildren); + std::string getType(Expression const& _expression); + inline void goUp() + { + solAssert(!m_jsonNodePtrs.empty(), "Uneven json nodes stack. Internal error."); + m_jsonNodePtrs.pop(); + }; + + Json::Value m_astJson; + std::stack m_jsonNodePtrs; + std::string m_source; + ASTNode const* m_ast; + int m_depth; +}; + +} +} diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 5003454f0..640ad3679 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -84,7 +84,7 @@ static Json::Value toJson(dev::eth::LocalisedLogEntry const& _e) static Json::Value toJson(dev::eth::LocalisedLogEntries const& _es) // commented to avoid warning. Uncomment once in use @ poC-7. { - Json::Value res; + Json::Value res(Json::arrayValue); for (dev::eth::LocalisedLogEntry const& e: _es) res.append(toJson(e)); return res; diff --git a/neth/main.cpp b/neth/main.cpp index 1252b205b..638e9c624 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -379,13 +379,14 @@ int main(int argc, char** argv) mining = ~(unsigned)0; else if (isFalse(m)) mining = 0; - else if (int i = stoi(m)) - mining = i; else - { - cerr << "Unknown -m/--mining option: " << m << endl; - return -1; - } + try { + mining = stoi(m); + } + catch (...) { + cerr << "Unknown -m/--mining option: " << m << endl; + return -1; + } } else if (arg == "-b" || arg == "--bootstrap") bootstrap = true; diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 8c5192abe..3888f2314 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ static string const g_argAbiStr = "json-abi"; static string const g_argSolAbiStr = "sol-abi"; static string const g_argAsmStr = "asm"; static string const g_argAstStr = "ast"; +static string const g_argAstJson = "ast-json"; static string const g_argBinaryStr = "binary"; static string const g_argOpcodesStr = "opcodes"; static string const g_argNatspecDevStr = "natspec-dev"; @@ -75,9 +77,10 @@ static inline bool argToStdout(po::variables_map const& _args, string const& _na static bool needStdout(po::variables_map const& _args) { + return argToStdout(_args, g_argAbiStr) || argToStdout(_args, g_argSolAbiStr) || - argToStdout(_args, g_argNatspecUserStr) || + argToStdout(_args, g_argNatspecUserStr) || argToStdout(_args, g_argAstJson) || argToStdout(_args, g_argNatspecDevStr) || argToStdout(_args, g_argAsmStr) || argToStdout(_args, g_argOpcodesStr) || argToStdout(_args, g_argBinaryStr); } @@ -215,6 +218,8 @@ bool CommandLineInterface::parseArguments(int argc, char** argv) ("input-file", po::value>(), "input file") (g_argAstStr.c_str(), po::value(), "Request to output the AST of the contract. " OUTPUT_TYPE_STR) + (g_argAstJson.c_str(), po::value(), + "Request to output the AST of the contract in JSON format. " OUTPUT_TYPE_STR) (g_argAsmStr.c_str(), po::value(), "Request to output the EVM assembly of the contract. " OUTPUT_TYPE_STR) (g_argOpcodesStr.c_str(), po::value(), @@ -339,20 +344,44 @@ bool CommandLineInterface::processInput() return true; } -void CommandLineInterface::actOnInput() +void CommandLineInterface::handleAst(string const& _argStr) { + string title; + string suffix; + + if (_argStr == g_argAstStr) + { + title = "Syntax trees:"; + suffix = ".ast"; + } + else if (_argStr == g_argAstJson) + { + title = "JSON AST:"; + suffix = ".json"; + } + else + BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Illegal argStr for AST")); + // do we need AST output? - if (m_args.count(g_argAstStr)) + if (m_args.count(_argStr)) { - auto choice = m_args[g_argAstStr].as(); + auto choice = m_args[_argStr].as(); if (outputToStdout(choice)) { - cout << "Syntax trees:" << endl << endl; + cout << title << endl << endl; for (auto const& sourceCode: m_sourceCodes) { cout << endl << "======= " << sourceCode.first << " =======" << endl; - ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second); - printer.print(cout); + if (_argStr == g_argAstStr) + { + ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second); + printer.print(cout); + } + else + { + ASTJsonConverter converter(m_compiler.getAST(sourceCode.first)); + converter.print(cout); + } } } @@ -362,12 +391,27 @@ void CommandLineInterface::actOnInput() { boost::filesystem::path p(sourceCode.first); ofstream outFile(p.stem().string() + ".ast"); - ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second); - printer.print(outFile); + if (_argStr == g_argAstStr) + { + ASTPrinter printer(m_compiler.getAST(sourceCode.first), sourceCode.second); + printer.print(outFile); + } + else + { + ASTJsonConverter converter(m_compiler.getAST(sourceCode.first)); + converter.print(outFile); + } outFile.close(); } } } +} + +void CommandLineInterface::actOnInput() +{ + // do we need AST output? + handleAst(g_argAstStr); + handleAst(g_argAstJson); vector contracts = m_compiler.getContractNames(); for (string const& contract: contracts) diff --git a/solc/CommandLineInterface.h b/solc/CommandLineInterface.h index 9dfee7199..2862773ba 100644 --- a/solc/CommandLineInterface.h +++ b/solc/CommandLineInterface.h @@ -53,6 +53,7 @@ public: void actOnInput(); private: + void handleAst(std::string const& _argStr); void handleBinary(std::string const& _contract); void handleOpcode(std::string const& _contract); void handleBytecode(std::string const& _contract); diff --git a/standard.js b/standard.js index 74ebc74ad..64126a278 100644 --- a/standard.js +++ b/standard.js @@ -1,10 +1,13 @@ var compile = function(name) { return web3.eth.solidity(env.contents("../../dapp-bin/" + name + "/" + name + ".sol")); }; var create = function(code) { return web3.eth.transact({ 'code': code }); }; +var createVal = function(code, val) { return web3.eth.transact(val ? { 'code': code, 'value': val } : { 'code': code }); }; var send = function(from, val, to) { return web3.eth.transact({ 'from': from, 'value': val, 'to': to }); }; var initService = function(name, dep) { return dep.then(function(){ return compile(name).then(create); }); }; +var initServiceVal = function(name, dep, val) { return dep.then(function(){ return compile(name).then(function(c) { createVal(c, val); }); }); }; var addrConfig = compile("config").then(create); var addrNameReg = initService("namereg", addrConfig); +var addrGavsino = initServiceVal("gavmble", addrNameReg, "1000000000000000000"); var abiNameReg = [{"constant":true,"inputs":[{"name":"name","type":"string32"}],"name":"addressOf","outputs":[{"name":"addr","type":"address"}]},{"constant":false,"inputs":[],"name":"kill","outputs":[]},{"constant":true,"inputs":[{"name":"addr","type":"address"}],"name":"nameOf","outputs":[{"name":"name","type":"string32"}]},{"constant":false,"inputs":[{"name":"name","type":"string32"}],"name":"register","outputs":[]},{"constant":false,"inputs":[],"name":"unregister","outputs":[]}]; var regName = function(account, name) { return web3.contract(addrNameReg, abiNameReg).register(name).transact({'from': account, 'gas': 10000}); }; @@ -26,6 +29,7 @@ addrConfig.then(function() { regName(accounts[1], 'Gav Would'); }); regName(accounts[0], 'Gav'); + // TODO: once we have the exchange. // approve(accounts[0], exchange).then(function(){ offer(accounts[0], coin, '5000', '0', '5000000000000000000'); }); // funded.then(function(){ approve(accounts[1], exchange); });