diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 865cfec3e..ec58fd559 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -1733,7 +1733,7 @@ void Main::on_data_textChanged() // compiler.addSources(dev::solidity::StandardSources); m_data = compiler.compile(src, m_enableOptimizer); solidity = "
var " + QString::fromStdString(compiler.getContractNames().front()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");"; + solidity += "
var " + QString::fromStdString(compiler.defaultContractName()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");"; solidity += "
" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped() + ""; solidity += "
" + QString::fromStdString(getFunctionHashes(compiler)).toHtmlEscaped() + ""; } @@ -2442,6 +2442,18 @@ string Main::lookupNatSpecUserNotice(dev::h256 const& _contractHash, dev::bytes return m_natspecDB.getUserNotice(_contractHash, _transactionData); } +int Main::authenticate(QString _title, QString _text) +{ + QMessageBox userInput(this); + userInput.setText(_title); + userInput.setInformativeText(_text); + userInput.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); + userInput.button(QMessageBox::Ok)->setText("Allow"); + userInput.button(QMessageBox::Cancel)->setText("Reject"); + userInput.setDefaultButton(QMessageBox::Cancel); + return userInput.exec(); +} + void Main::refreshWhispers() { ui->whispers->clear(); diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 5298a28a2..fa451b63f 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -79,6 +79,12 @@ public: QVariant evalRaw(QString const& _js); + QString pretty(dev::Address _a) const override; + QString prettyU256(dev::u256 _n) const override; + QString render(dev::Address _a) const override; + dev::Address fromString(QString const& _a) const override; + std::string renderDiff(dev::eth::StateDiff const& _d) const override; + public slots: void load(QString _file); void note(QString _entry); @@ -86,6 +92,8 @@ public slots: void warn(QString _entry); QString contents(QString _file); + int authenticate(QString _title, QString _text); + void onKeysChanged(); private slots: @@ -175,12 +183,6 @@ private: void updateDebugger(); void debugFinished(); - QString pretty(dev::Address _a) const override; - QString prettyU256(dev::u256 _n) const override; - QString render(dev::Address _a) const override; - dev::Address fromString(QString const& _a) const override; - std::string renderDiff(dev::eth::StateDiff const& _d) const override; - void alterDebugStateGroup(bool _enable) const; void updateFee(); diff --git a/alethzero/OurWebThreeStubServer.cpp b/alethzero/OurWebThreeStubServer.cpp index 02d7236df..89d616756 100644 --- a/alethzero/OurWebThreeStubServer.cpp +++ b/alethzero/OurWebThreeStubServer.cpp @@ -46,48 +46,72 @@ string OurWebThreeStubServer::shh_newIdentity() bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string const& _text) const { - QMessageBox userInput; - userInput.setText(QString::fromStdString(_title)); - userInput.setInformativeText(QString::fromStdString(_text + "\n Do you wish to allow this?")); - userInput.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel); - userInput.button(QMessageBox::Ok)->setText("Allow"); - userInput.button(QMessageBox::Cancel)->setText("Reject"); - userInput.setDefaultButton(QMessageBox::Cancel); - return userInput.exec() == QMessageBox::Ok; + int button; + QMetaObject::invokeMethod(m_main, "authenticate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, button), Q_ARG(QString, QString::fromStdString(_title)), Q_ARG(QString, QString::fromStdString(_text))); + return button == QMessageBox::Ok; } -void OurWebThreeStubServer::showBasicValueTransferNotice(u256 _value) const +bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t) const { - QMessageBox notice; - notice.setText("Basic Value Transfer Transaction"); - notice.setInformativeText(QString::fromStdString("Value is " + toString(_value))); - notice.setStandardButtons(QMessageBox::Ok); - notice.exec(); + 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) + "."); +} + +bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t) 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) + "."); +} + +bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t) 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 " + + 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" + + "WARNING: This is probably going to cost you at least " + + formatBalance(_t.value + _t.gas * _t.gasPrice) + + ", however this doesn't include any side-effects, which could be of far greater importance.\n\n" + + "REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!"); } bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t) { + if (_t.creation) + { + // recipient has no code - nothing special about this transaction, show basic value transfer info + return showCreationNotice(_t); + } + h256 contractCodeHash = m_web3->ethereum()->postState().codeHash(_t.to); if (contractCodeHash == EmptySHA3) - // contract creation - return true; - - if (false) //TODO: When is is just a value transfer? { // recipient has no code - nothing special about this transaction, show basic value transfer info - showBasicValueTransferNotice(_t.value); - return true; + return showSendNotice(_t); } + // TODO: include total cost in Ether string userNotice = m_main->lookupNatSpecUserNotice(contractCodeHash, _t.data); if (userNotice.empty()) - return showAuthenticationPopup("Unverified Pending Transaction", - "An undocumented transaction is about to be executed."); + return showUnknownCallNotice(_t); NatspecExpressionEvaluator evaluator; userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString(); // otherwise it's a transaction to a contract for which we have the natspec - return showAuthenticationPopup("Pending Transaction", userNotice); + return showAuthenticationPopup("Contract Transaction", + "ÐApp attempting to conduct contract interaction with " + + m_main->pretty(_t.to).toStdString() + + ": " + userNotice + ".\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 " + + formatBalance(_t.gas * _t.gasPrice) + " = " + + formatBalance(_t.value + _t.gas * _t.gasPrice) + "." + : + "Additional network fees are at most" + + formatBalance(_t.gas * _t.gasPrice) + ".") + ); } diff --git a/alethzero/OurWebThreeStubServer.h b/alethzero/OurWebThreeStubServer.h index 303b73111..fbdae7d03 100644 --- a/alethzero/OurWebThreeStubServer.h +++ b/alethzero/OurWebThreeStubServer.h @@ -42,7 +42,9 @@ signals: private: bool showAuthenticationPopup(std::string const& _title, std::string const& _text) const; - void showBasicValueTransferNotice(dev::u256 _value) 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; dev::WebThreeDirect* m_web3; Main* m_main; diff --git a/libethcore/CommonJS.h b/libethcore/CommonJS.h index 2f82d8945..abe74f0af 100644 --- a/libethcore/CommonJS.h +++ b/libethcore/CommonJS.h @@ -144,6 +144,7 @@ inline Address jsToAddress(std::string const& _s) { return jsToFixed