Browse Source

Working, albeit slowly, non-NatSpec transaction confirmations.

cl-refactor
Gav Wood 10 years ago
parent
commit
809df5cdc5
  1. 14
      alethzero/MainWin.cpp
  2. 14
      alethzero/MainWin.h
  3. 70
      alethzero/OurWebThreeStubServer.cpp
  4. 4
      alethzero/OurWebThreeStubServer.h
  5. 1
      libethcore/CommonJS.h
  6. 5
      libsolidity/CompilerStack.cpp
  7. 1
      libsolidity/CompilerStack.h
  8. 2
      libweb3jsonrpc/WebThreeStubServerBase.cpp

14
alethzero/MainWin.cpp

@ -1733,7 +1733,7 @@ void Main::on_data_textChanged()
// compiler.addSources(dev::solidity::StandardSources); // compiler.addSources(dev::solidity::StandardSources);
m_data = compiler.compile(src, m_enableOptimizer); m_data = compiler.compile(src, m_enableOptimizer);
solidity = "<h4>Solidity</h4>"; solidity = "<h4>Solidity</h4>";
solidity += "<pre>var " + QString::fromStdString(compiler.getContractNames().front()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");</pre>"; solidity += "<pre>var " + QString::fromStdString(compiler.defaultContractName()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");</pre>";
solidity += "<pre>" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped() + "</pre>"; solidity += "<pre>" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped() + "</pre>";
solidity += "<pre>" + QString::fromStdString(getFunctionHashes(compiler)).toHtmlEscaped() + "</pre>"; solidity += "<pre>" + QString::fromStdString(getFunctionHashes(compiler)).toHtmlEscaped() + "</pre>";
} }
@ -2442,6 +2442,18 @@ string Main::lookupNatSpecUserNotice(dev::h256 const& _contractHash, dev::bytes
return m_natspecDB.getUserNotice(_contractHash, _transactionData); 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() void Main::refreshWhispers()
{ {
ui->whispers->clear(); ui->whispers->clear();

14
alethzero/MainWin.h

@ -79,6 +79,12 @@ public:
QVariant evalRaw(QString const& _js); 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: public slots:
void load(QString _file); void load(QString _file);
void note(QString _entry); void note(QString _entry);
@ -86,6 +92,8 @@ public slots:
void warn(QString _entry); void warn(QString _entry);
QString contents(QString _file); QString contents(QString _file);
int authenticate(QString _title, QString _text);
void onKeysChanged(); void onKeysChanged();
private slots: private slots:
@ -175,12 +183,6 @@ private:
void updateDebugger(); void updateDebugger();
void debugFinished(); 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 alterDebugStateGroup(bool _enable) const;
void updateFee(); void updateFee();

70
alethzero/OurWebThreeStubServer.cpp

@ -46,48 +46,72 @@ string OurWebThreeStubServer::shh_newIdentity()
bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string const& _text) const bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string const& _text) const
{ {
QMessageBox userInput; int button;
userInput.setText(QString::fromStdString(_title)); QMetaObject::invokeMethod(m_main, "authenticate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, button), Q_ARG(QString, QString::fromStdString(_title)), Q_ARG(QString, QString::fromStdString(_text)));
userInput.setInformativeText(QString::fromStdString(_text + "\n Do you wish to allow this?")); return button == QMessageBox::Ok;
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;
} }
void OurWebThreeStubServer::showBasicValueTransferNotice(u256 _value) const bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t) const
{ {
QMessageBox notice; 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 <b>" + formatBalance(_t.value + _t.gas * _t.gasPrice) + "</b>.");
notice.setText("Basic Value Transfer Transaction"); }
notice.setInformativeText(QString::fromStdString("Value is " + toString(_value)));
notice.setStandardButtons(QMessageBox::Ok); bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t) const
notice.exec(); {
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 <b>" + formatBalance(_t.value + _t.gas * _t.gasPrice) + "</b>.");
}
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) 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); h256 contractCodeHash = m_web3->ethereum()->postState().codeHash(_t.to);
if (contractCodeHash == EmptySHA3) 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 // recipient has no code - nothing special about this transaction, show basic value transfer info
showBasicValueTransferNotice(_t.value); return showSendNotice(_t);
return true;
} }
// TODO: include total cost in Ether
string userNotice = m_main->lookupNatSpecUserNotice(contractCodeHash, _t.data); string userNotice = m_main->lookupNatSpecUserNotice(contractCodeHash, _t.data);
if (userNotice.empty()) if (userNotice.empty())
return showAuthenticationPopup("Unverified Pending Transaction", return showUnknownCallNotice(_t);
"An undocumented transaction is about to be executed.");
NatspecExpressionEvaluator evaluator; NatspecExpressionEvaluator evaluator;
userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString(); userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString();
// otherwise it's a transaction to a contract for which we have the natspec // 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() +
": <b>" + userNotice + "</b>.\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) + " = <b>" +
formatBalance(_t.value + _t.gas * _t.gasPrice) + "</b>."
:
"Additional network fees are at most" +
formatBalance(_t.gas * _t.gasPrice) + ".")
);
} }

4
alethzero/OurWebThreeStubServer.h

@ -42,7 +42,9 @@ signals:
private: private:
bool showAuthenticationPopup(std::string const& _title, std::string const& _text) const; 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; dev::WebThreeDirect* m_web3;
Main* m_main; Main* m_main;

1
libethcore/CommonJS.h

@ -144,6 +144,7 @@ inline Address jsToAddress(std::string const& _s) { return jsToFixed<sizeof(dev:
struct TransactionSkeleton struct TransactionSkeleton
{ {
bool creation = false;
Address from; Address from;
Address to; Address to;
u256 value; u256 value;

5
libsolidity/CompilerStack.cpp

@ -333,6 +333,11 @@ void CompilerStack::resolveImports()
swap(m_sourceOrder, sourceOrder); swap(m_sourceOrder, sourceOrder);
} }
std::string CompilerStack::defaultContractName() const
{
return getContract("").contract->getName();
}
CompilerStack::Contract const& CompilerStack::getContract(string const& _contractName) const CompilerStack::Contract const& CompilerStack::getContract(string const& _contractName) const
{ {
if (m_contracts.empty()) if (m_contracts.empty())

1
libsolidity/CompilerStack.h

@ -73,6 +73,7 @@ public:
void parse(std::string const& _sourceCode); void parse(std::string const& _sourceCode);
/// Returns a list of the contract names in the sources. /// Returns a list of the contract names in the sources.
std::vector<std::string> getContractNames() const; std::vector<std::string> getContractNames() const;
std::string defaultContractName() const;
/// Compiles the source units that were previously added and parsed. /// Compiles the source units that were previously added and parsed.
void compile(bool _optimize = false); void compile(bool _optimize = false);

2
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -279,6 +279,8 @@ static TransactionSkeleton toTransaction(Json::Value const& _json)
ret.from = jsToAddress(_json["from"].asString()); ret.from = jsToAddress(_json["from"].asString());
if (_json["to"].isString()) if (_json["to"].isString())
ret.to = jsToAddress(_json["to"].asString()); ret.to = jsToAddress(_json["to"].asString());
else
ret.creation = true;
if (!_json["value"].empty()) if (!_json["value"].empty())
{ {
if (_json["value"].isString()) if (_json["value"].isString())

Loading…
Cancel
Save