diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index 2d1dd0481..5b5ce420a 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -51,22 +51,24 @@ bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string return button == QMessageBox::Ok; } -bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t) const +bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t, bool _toProxy) const { - return showAuthenticationPopup("Contract Creation Transaction", "ÐApp is attemping to create a contract; to be endowed with " + formatBalance(_t.value) + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); + return showAuthenticationPopup("Contract Creation Transaction", string("ÐApp is attemping to create a contract; ") + (_toProxy ? "(this transaction is not executed directly, but forwarded to another ÐApp) " : "") + "to be endowed with " + formatBalance(_t.value) + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); } -bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t) const +bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t, bool _toProxy) const { - return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to).toStdString() + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); + return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to).toStdString() + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") + +", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + "."); } -bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t) const +bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t, bool _toProxy) const { return showAuthenticationPopup("DANGEROUS! Unknown Contract Transaction!", "ÐApp is attempting to call into an unknown contract at address " + - m_main->pretty(_t.to).toStdString() + - ".\n\nCall involves sending " + + m_main->pretty(_t.to).toStdString() + ".\n\n" + + (_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") + + "Call involves sending " + formatBalance(_t.value) + " to the recipient, with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + "However, this also does other stuff which we don't understand, and does so in your name.\n\n" + @@ -76,25 +78,25 @@ bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t) "REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!"); } -bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t) +bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t, bool _toProxy) { if (_t.creation) { // recipient has no code - nothing special about this transaction, show basic value transfer info - return showCreationNotice(_t); + return showCreationNotice(_t, _toProxy); } h256 contractCodeHash = m_web3->ethereum()->postState().codeHash(_t.to); if (contractCodeHash == EmptySHA3) { // recipient has no code - nothing special about this transaction, show basic value transfer info - return showSendNotice(_t); + return showSendNotice(_t, _toProxy); } string userNotice = m_main->natSpec()->getUserNotice(contractCodeHash, _t.data); if (userNotice.empty()) - return showUnknownCallNotice(_t); + return showUnknownCallNotice(_t, _toProxy); NatspecExpressionEvaluator evaluator; userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString(); @@ -104,6 +106,7 @@ bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t) "ÐApp attempting to conduct contract interaction with " + m_main->pretty(_t.to).toStdString() + ": " + userNotice + ".\n\n" + + (_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") + (_t.value > 0 ? "In addition, ÐApp is attempting to send " + formatBalance(_t.value) + " to said recipient, with additional network fees of up to " + diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index fbdae7d03..1ab5f813c 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -35,16 +35,16 @@ public: std::vector const& _accounts, Main* main); virtual std::string shh_newIdentity() override; - virtual bool authenticate(dev::eth::TransactionSkeleton const& _t); + virtual bool authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy); signals: void onNewId(QString _s); private: bool showAuthenticationPopup(std::string const& _title, std::string const& _text) const; - bool showCreationNotice(dev::eth::TransactionSkeleton const& _t) const; - bool showSendNotice(dev::eth::TransactionSkeleton const& _t) const; - bool showUnknownCallNotice(dev::eth::TransactionSkeleton const& _t) const; + bool showCreationNotice(dev::eth::TransactionSkeleton const& _t, bool _toProxy) const; + bool showSendNotice(dev::eth::TransactionSkeleton const& _t, bool _toProxy) const; + bool showUnknownCallNotice(dev::eth::TransactionSkeleton const& _t, bool _toProxy) const; dev::WebThreeDirect* m_web3; Main* m_main; diff --git a/libweb3jsonrpc/AccountHolder.cpp b/libweb3jsonrpc/AccountHolder.cpp index a7bdc7a68..6db41cbbf 100644 --- a/libweb3jsonrpc/AccountHolder.cpp +++ b/libweb3jsonrpc/AccountHolder.cpp @@ -22,14 +22,15 @@ */ #include "AccountHolder.h" +#include +#include #include - using namespace std; using namespace dev; using namespace dev::eth; -vector emptyQueue; +vector g_emptyQueue; void AccountHolder::setAccounts(vector const& _accounts) { @@ -63,12 +64,13 @@ Address const& AccountHolder::getDefaultTransactAccount() const int AccountHolder::addProxyAccount(const Address& _account) { - int const c_id = m_transactionQueues.empty() ? 1 : m_transactionQueues.rbegin()->first + 1; - if (isProxyAccount(_account)) + static std::mt19937 s_randomNumberGenerator(time(0)); + int id = std::uniform_int_distribution(1)(s_randomNumberGenerator); + if (isProxyAccount(_account) || id == 0 || m_transactionQueues.count(id)) return 0; - m_proxyAccounts.insert(make_pair(_account, c_id)); - m_transactionQueues[c_id].first = _account; - return c_id; + m_proxyAccounts.insert(make_pair(_account, id)); + m_transactionQueues[id].first = _account; + return id; } bool AccountHolder::removeProxyAccount(unsigned _id) @@ -91,7 +93,7 @@ void AccountHolder::queueTransaction(TransactionSkeleton const& _transaction) vector const& AccountHolder::getQueuedTransactions(int _id) const { if (!m_transactionQueues.count(_id)) - return emptyQueue; + return g_emptyQueue; return m_transactionQueues.at(_id).second; } diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index d5da8a044..3fa22a928 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -41,6 +41,7 @@ using namespace std; using namespace dev; using namespace dev::eth; + static Json::Value toJson(dev::eth::BlockInfo const& _bi) { Json::Value res; @@ -78,7 +79,7 @@ static Json::Value toJson(dev::eth::TransactionSkeleton const& _t) Json::Value res; res["to"] = toJS(_t.to); res["from"] = toJS(_t.from); - res["gas"] = (int)_t.gas; + res["gas"] = toJS(_t.gas); res["gasPrice"] = toJS(_t.gasPrice); res["value"] = toJS(_t.value); res["data"] = jsFromBinary(_t.data); @@ -709,13 +710,11 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json) if (!m_accounts->isRealAccount(t.from)) { if (m_accounts->isProxyAccount(t.from)) - { - // todo "authenticate for proxy" - m_accounts->queueTransaction(t); - } + if (authenticate(t, true)) + m_accounts->queueTransaction(t); return ret; } - if (authenticate(t)) + if (authenticate(t, false)) { if (t.to) // TODO: from qethereum, insert validification hook here. @@ -727,7 +726,7 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json) return ret; } -bool WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t) +bool WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t, bool) { cwarn << "Silently signing transaction from address" << _t.from.abridged() << ": User validation hook goes here."; return true; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 62260d11d..ed2f09d99 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -136,7 +136,7 @@ public: std::map const& ids() const { return m_ids; } protected: - virtual bool authenticate(dev::eth::TransactionSkeleton const& _t); + virtual bool authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy); protected: virtual dev::eth::Interface* client() = 0;