#include "MainWin.h"
#include "DownloadView.h"
#include "MiningView.h"
#include "BuildInfo.h"
#include "OurWebThreeStubServer.h"
+#include "Transact.h"
+#include "Debugger.h"
#include "ui_Main.h"
using namespace std;
using namespace dev;
@@ -62,17 +65,6 @@ using namespace dev::p2p;
using namespace dev::eth;
namespace js = json_spirit;
-#define Small "font-size: small; "
-#define Mono "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; "
-#define Div(S) ""
-#define Span(S) ""
-
-static void initUnits(QComboBox* _b)
-{
- for (auto n = (unsigned)units().size(); n-- != 0; )
- _b->addItem(QString::fromStdString(units()[n].second), n);
-}
-
QString Main::fromRaw(h256 _n, unsigned* _inc)
{
if (_n)
@@ -98,12 +90,6 @@ QString Main::fromRaw(h256 _n, unsigned* _inc)
return QString();
}
-static vector keysAsVector(QList const& keys)
-{
- auto list = keys.toStdList();
- return {begin(list), end(list)};
-}
-
QString contentsOfQResource(string const& res)
{
QFile file(QString::fromStdString(res));
@@ -119,7 +105,8 @@ Address c_newConfig = Address("c6d9d2cd449a754c494264e1809c50e34d64562b");
Main::Main(QWidget *parent) :
QMainWindow(parent),
- ui(new Ui::Main)
+ ui(new Ui::Main),
+ m_transact(this, this)
{
setWindowFlags(Qt::Window);
ui->setupUi(this);
@@ -148,12 +135,6 @@ Main::Main(QWidget *parent) :
ui->configDock->close();
on_verbosity_valueChanged();
- initUnits(ui->gasPriceUnits);
- initUnits(ui->valueUnits);
- ui->valueUnits->setCurrentIndex(6);
- ui->gasPriceUnits->setCurrentIndex(4);
- ui->gasPrice->setValue(10);
- on_destination_currentTextChanged();
statusBar()->addPermanentWidget(ui->balance);
statusBar()->addPermanentWidget(ui->peerCount);
@@ -167,25 +148,26 @@ Main::Main(QWidget *parent) :
bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size());
m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir() + "/AlethZero", false, {"eth", "shh"}, p2p::NetworkPreferences(), network));
- m_qwebConnector.reset(new QWebThreeConnector());
- m_server.reset(new OurWebThreeStubServer(*m_qwebConnector, *web3(), keysAsVector(m_myKeys), this));
+ m_httpConnector.reset(new jsonrpc::HttpServer(8080));
+ m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys), this));
connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString)));
m_server->setIdentities(keysAsVector(owned()));
m_server->StartListening();
connect(ui->webView, &QWebView::loadStarted, [this]()
{
- // NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
- m_qweb = new QWebThree(this);
- auto qweb = m_qweb;
- m_qwebConnector->setQWeb(qweb);
-
QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
- connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qweb));
- connect(m_qweb, SIGNAL(onNewId(QString)), this, SLOT(addNewId(QString)));
+ connect(f, &QWebFrame::javaScriptWindowObjectCleared, [f, this]()
+ {
+ f->disconnect();
+ f->addToJavaScriptWindowObject("env", this, QWebFrame::QtOwnership);
+ f->evaluateJavaScript(contentsOfQResource(":/js/bignumber.min.js"));
+ f->evaluateJavaScript(contentsOfQResource(":/js/webthree.js"));
+ f->evaluateJavaScript(contentsOfQResource(":/js/setup.js"));
+ });
});
connect(ui->webView, &QWebView::loadFinished, [=]()
@@ -216,7 +198,6 @@ Main::~Main()
writeSettings();
// Must do this here since otherwise m_ethereum'll be deleted (and therefore clearWatches() called by the destructor)
// *after* the client is dead.
- m_qweb->clientDieing();
g_logPost = simpleDebugOut;
}
@@ -372,12 +353,6 @@ void Main::on_forceMining_triggered()
ethereum()->setForceMining(ui->forceMining->isChecked());
}
-void Main::on_enableOptimizer_triggered()
-{
- m_enableOptimizer = ui->enableOptimizer->isChecked();
- on_data_textChanged();
-}
-
QString Main::contents(QString _s)
{
return QString::fromStdString(dev::asString(dev::contents(_s.toStdString())));
@@ -411,6 +386,12 @@ void Main::load(QString _s)
}*/
}
+void Main::on_newTransaction_triggered()
+{
+ m_transact.setEnvironment(m_myKeys, ethereum(), &m_natSpecDB);
+ m_transact.exec();
+}
+
void Main::on_loadJS_triggered()
{
QString f = QFileDialog::getOpenFileName(this, "Load Javascript", QString(), "Javascript (*.js);;All files (*)");
@@ -672,7 +653,6 @@ void Main::writeSettings()
s.setValue("paranoia", ui->paranoia->isChecked());
s.setValue("showAll", ui->showAll->isChecked());
s.setValue("showAllAccounts", ui->showAllAccounts->isChecked());
- s.setValue("enableOptimizer", m_enableOptimizer);
s.setValue("clientName", ui->clientName->text());
s.setValue("idealPeers", ui->idealPeers->value());
s.setValue("port", ui->port->value());
@@ -742,8 +722,6 @@ void Main::readSettings(bool _skipGeometry)
ui->paranoia->setChecked(s.value("paranoia", false).toBool());
ui->showAll->setChecked(s.value("showAll", false).toBool());
ui->showAllAccounts->setChecked(s.value("showAllAccounts", false).toBool());
- m_enableOptimizer = s.value("enableOptimizer", true).toBool();
- ui->enableOptimizer->setChecked(m_enableOptimizer);
ui->clientName->setText(s.value("clientName", "").toString());
if (ui->clientName->text().isEmpty())
ui->clientName->setText(QInputDialog::getText(nullptr, "Enter identity", "Enter a name that will identify you on the peer network"));
@@ -990,7 +968,6 @@ void Main::refreshNetwork()
void Main::refreshAll()
{
- refreshDestination();
refreshBlockChain();
refreshBlockCount();
refreshPending();
@@ -1041,20 +1018,6 @@ void Main::refreshAccounts()
}
}
-void Main::refreshDestination()
-{
- cwatch << "refreshDestination()";
- QString s;
- for (auto i: ethereum()->addresses())
- if ((s = pretty(i)).size())
- // A namereg address
- if (ui->destination->findText(s, Qt::MatchExactly | Qt::MatchCaseSensitive) == -1)
- ui->destination->addItem(s);
- for (int i = 0; i < ui->destination->count(); ++i)
- if (ui->destination->itemText(i) != "(Create Contract)" && !fromString(ui->destination->itemText(i)))
- ui->destination->removeItem(i--);
-}
-
void Main::refreshBlockCount()
{
cwatch << "refreshBlockCount()";
@@ -1477,13 +1440,12 @@ void Main::on_debugCurrent_triggered()
if (!item->data(Qt::UserRole + 1).isNull())
{
unsigned txi = item->data(Qt::UserRole + 1).toInt();
- m_executiveState = ethereum()->state(txi + 1, h);
- m_currentExecution = unique_ptr(new Executive(m_executiveState, ethereum()->blockChain(), 0));
- Transaction t = m_executiveState.pending()[txi];
- m_executiveState = m_executiveState.fromPending(txi);
- auto r = t.rlp();
- populateDebugger(&r);
- m_currentExecution.reset();
+ bytes t = ethereum()->blockChain().transaction(h, txi);
+ State s(ethereum()->state(txi, h));
+ Executive e(s, ethereum()->blockChain(), 0);
+ Debugger dw(this, this);
+ dw.populate(e, Transaction(t, CheckSignature::Sender));
+ dw.exec();
}
}
}
@@ -1514,49 +1476,6 @@ void Main::on_debugDumpStatePre_triggered()
on_debugDumpState_triggered(0);
}
-void Main::populateDebugger(dev::bytesConstRef _r)
-{
- bool done = m_currentExecution->setup(_r);
- if (!done)
- {
- debugFinished();
- vector levels;
- m_codes.clear();
- bytes lastExtCode;
- bytesConstRef lastData;
- h256 lastHash;
- h256 lastDataHash;
- auto onOp = [&](uint64_t steps, Instruction inst, dev::bigint newMemSize, dev::bigint gasCost, VM* voidVM, ExtVMFace const* voidExt)
- {
- VM& vm = *voidVM;
- ExtVM const& ext = *static_cast(voidExt);
- if (ext.code != lastExtCode)
- {
- lastExtCode = ext.code;
- lastHash = sha3(lastExtCode);
- if (!m_codes.count(lastHash))
- m_codes[lastHash] = ext.code;
- }
- if (ext.data != lastData)
- {
- lastData = ext.data;
- lastDataHash = sha3(lastData);
- if (!m_codes.count(lastDataHash))
- m_codes[lastDataHash] = ext.data.toBytes();
- }
- if (levels.size() < ext.depth)
- levels.push_back(&m_history.back());
- else
- levels.resize(ext.depth);
- m_history.append(WorldState({steps, ext.myAddress, vm.curPC(), inst, newMemSize, vm.gas(), lastHash, lastDataHash, vm.stack(), vm.memory(), gasCost, ext.state().storage(ext.myAddress), levels}));
- };
- m_currentExecution->go(onOp);
- m_currentExecution->finalize();
- initDebugger();
- updateDebugger();
- }
-}
-
void Main::on_contracts_currentItemChanged()
{
ui->contractInfo->clear();
@@ -1572,7 +1491,7 @@ void Main::on_contracts_currentItemChanged()
auto storage = ethereum()->storageAt(address);
for (auto const& i: storage)
s << "@" << showbase << hex << prettyU256(i.first).toStdString() << " " << showbase << hex << prettyU256(i.second).toStdString() << "
";
- s << "Body Code
" << disassemble(ethereum()->codeAt(address));
+ s << "Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")
" << disassemble(ethereum()->codeAt(address));
s << Div(Mono) << toHex(ethereum()->codeAt(address)) << "
";
ui->contractInfo->appendHtml(QString::fromStdString(s.str()));
}
@@ -1616,19 +1535,6 @@ void Main::on_contracts_doubleClicked()
qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray())));
}
-void Main::on_destination_currentTextChanged()
-{
- if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)")
- if (Address a = fromString(ui->destination->currentText()))
- ui->calculatedName->setText(render(a));
- else
- ui->calculatedName->setText("Unknown Address");
- else
- ui->calculatedName->setText("Create Contract");
- on_data_textChanged();
-// updateFee();
-}
-
static shh::FullTopic topicFromText(QString _s)
{
shh::BuildTopic ret;
@@ -1683,134 +1589,6 @@ static shh::FullTopic topicFromText(QString _s)
return ret;
}
-bool Main::sourceIsSolidity(string const& _source)
-{
- // TODO: Improve this heuristic
- return (_source.substr(0, 8) == "contract" || _source.substr(0, 5) == "//sol");
-}
-
-static bool sourceIsSerpent(string const& _source)
-{
- // TODO: Improve this heuristic
- return (_source.substr(0, 5) == "//ser");
-}
-
-string const Main::getFunctionHashes(dev::solidity::CompilerStack const &_compiler,
- string const& _contractName)
-{
- string ret = "";
- auto const& contract = _compiler.getContractDefinition(_contractName);
- auto interfaceFunctions = contract.getInterfaceFunctions();
-
- for (auto const& it: interfaceFunctions)
- {
- ret += it.first.abridged();
- ret += " :";
- ret += it.second->getDeclaration().getName() + "\n";
- }
- return ret;
-}
-
-void Main::on_data_textChanged()
-{
- m_pcWarp.clear();
- if (isCreation())
- {
- string src = ui->data->toPlainText().toStdString();
- vector errors;
- QString lll;
- QString solidity;
- if (src.find_first_not_of("1234567890abcdefABCDEF") == string::npos && src.size() % 2 == 0)
- {
- m_data = fromHex(src);
- }
- else if (sourceIsSolidity(src))
- {
- dev::solidity::CompilerStack compiler;
- try
- {
-// compiler.addSources(dev::solidity::StandardSources);
- m_data = compiler.compile(src, m_enableOptimizer);
- solidity = "Solidity
";
- solidity += "var " + QString::fromStdString(compiler.getContractNames().front()) + " = web3.eth.contractFromAbi(" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + ");
";
- solidity += "" + QString::fromStdString(compiler.getSolidityInterface()).toHtmlEscaped() + "
";
- solidity += "" + QString::fromStdString(getFunctionHashes(compiler)).toHtmlEscaped() + "
";
- }
- catch (dev::Exception const& exception)
- {
- ostringstream error;
- solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler);
- solidity = "Solidity
" + QString::fromStdString(error.str()).toHtmlEscaped() + "
";
- }
- catch (...)
- {
- solidity = "Solidity
Uncaught exception.
";
- }
- }
-#ifndef _MSC_VER
- else if (sourceIsSerpent(src))
- {
- try
- {
- m_data = dev::asBytes(::compile(src));
- for (auto& i: errors)
- i = "(LLL " + i + ")";
- }
- catch (string err)
- {
- errors.push_back("Serpent " + err);
- }
- }
-#endif
- else
- {
- m_data = compileLLL(src, m_enableOptimizer, &errors);
- if (errors.empty())
- {
- auto asmcode = compileLLLToAsm(src, false);
- lll = "Pre
" + QString::fromStdString(asmcode).toHtmlEscaped() + "
";
- if (m_enableOptimizer)
- {
- asmcode = compileLLLToAsm(src, true);
- lll = "Opt
" + QString::fromStdString(asmcode).toHtmlEscaped() + "
" + lll;
- }
- }
- }
- QString errs;
- if (errors.size())
- {
- errs = "Errors
";
- for (auto const& i: errors)
- errs.append("" + QString::fromStdString(i).toHtmlEscaped() + "
");
- }
- ui->code->setHtml(errs + lll + solidity + "Code
" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "Hex
" Div(Mono) + QString::fromStdString(toHex(m_data)) + "