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;