Browse Source

Transact dialog supports all the NatSpec stuff.

cl-refactor
Gav Wood 10 years ago
parent
commit
bfc037f688
  1. 3
      alethzero/CMakeLists.txt
  2. 33
      alethzero/Context.cpp
  3. 27
      alethzero/Context.h
  4. 34
      alethzero/Debugger.ui
  5. 286
      alethzero/Main.ui
  6. 320
      alethzero/MainWin.cpp
  7. 45
      alethzero/MainWin.h
  8. 5
      alethzero/NatspecHandler.h
  9. 2
      alethzero/OurWebThreeStubServer.cpp
  10. 325
      alethzero/Transact.cpp
  11. 82
      alethzero/Transact.h
  12. 244
      alethzero/Transact.ui
  13. 10
      libethcore/CommonEth.cpp
  14. 33
      libethcore/CommonEth.h

3
alethzero/CMakeLists.txt

@ -16,6 +16,7 @@ include_directories(${JSON_RPC_CPP_INCLUDE_DIRS})
qt5_wrap_ui(ui_Main.h Main.ui)
qt5_wrap_ui(ui_Debugger.h Debugger.ui)
qt5_wrap_ui(ui_Transact.h Transact.ui)
file(GLOB HEADERS "*.h")
@ -28,7 +29,7 @@ endif ()
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake
eth_add_executable(${EXECUTABLE}
ICON alethzero
UI_RESOURCES alethzero.icns Main.ui Debugger.ui
UI_RESOURCES alethzero.icns Main.ui Debugger.ui Transact.ui
WIN_RESOURCES alethzero.rc
)

33
alethzero/Context.cpp

@ -20,7 +20,40 @@
*/
#include "Context.h"
#include <QComboBox>
#include <libethcore/CommonEth.h>
using namespace std;
using namespace dev;
using namespace dev::eth;
NatSpecFace::~NatSpecFace()
{
}
Context::~Context()
{
}
void initUnits(QComboBox* _b)
{
for (auto n = (unsigned)units().size(); n-- != 0; )
_b->addItem(QString::fromStdString(units()[n].second), n);
}
vector<KeyPair> keysAsVector(QList<KeyPair> const& keys)
{
auto list = keys.toStdList();
return {begin(list), end(list)};
}
bool sourceIsSolidity(string const& _source)
{
// TODO: Improve this heuristic
return (_source.substr(0, 8) == "contract" || _source.substr(0, 5) == "//sol");
}
bool sourceIsSerpent(string const& _source)
{
// TODO: Improve this heuristic
return (_source.substr(0, 5) == "//ser");
}

27
alethzero/Context.h

@ -22,11 +22,38 @@
#pragma once
#include <string>
#include <vector>
#include <QString>
#include <QList>
#include <libethcore/CommonEth.h>
class QComboBox;
namespace dev { namespace eth { class StateDiff; } }
#define Small "font-size: small; "
#define Mono "font-family: Ubuntu Mono, Monospace, Lucida Console, Courier New; font-weight: bold; "
#define Div(S) "<div style=\"" S "\">"
#define Span(S) "<span style=\"" S "\">"
void initUnits(QComboBox* _b);
std::vector<dev::KeyPair> keysAsVector(QList<dev::KeyPair> const& _keys);
bool sourceIsSolidity(std::string const& _source);
bool sourceIsSerpent(std::string const& _source);
class NatSpecFace
{
public:
virtual ~NatSpecFace();
virtual void add(dev::h256 const& _contractHash, std::string const& _doc) = 0;
virtual std::string retrieve(dev::h256 const& _contractHash) const = 0;
virtual std::string getUserNotice(std::string const& json, const dev::bytes& _transactionData) = 0;
virtual std::string getUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionDacta) = 0;
};
class Context
{
public:

34
alethzero/Debugger.ui

@ -17,12 +17,24 @@
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="stepOver">
<property name="text">
@ -83,6 +95,12 @@
</item>
<item>
<widget class="QSplitter" name="splitter_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
@ -213,12 +231,24 @@
<item>
<widget class="QFrame" name="frame_2">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QToolButton" name="dump">
<property name="text">

286
alethzero/Main.ui

@ -144,6 +144,7 @@
</property>
<addaction name="mine"/>
<addaction name="separator"/>
<addaction name="newTransaction"/>
<addaction name="newAccount"/>
<addaction name="importKey"/>
<addaction name="importKeyFile"/>
@ -168,7 +169,6 @@
<addaction name="inject"/>
<addaction name="forceMining"/>
<addaction name="turboMining"/>
<addaction name="enableOptimizer"/>
<addaction name="separator"/>
<addaction name="usePrivate"/>
<addaction name="jitvm"/>
@ -516,237 +516,11 @@
<bool>false</bool>
</attribute>
<addaction name="go"/>
<addaction name="newTransaction"/>
<addaction name="preview"/>
<addaction name="mine"/>
<addaction name="refresh"/>
</widget>
<widget class="QDockWidget" name="dockWidget_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>510</width>
<height>386</height>
</size>
</property>
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
</property>
<property name="windowTitle">
<string>Transact</string>
</property>
<attribute name="dockWidgetArea">
<number>1</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents_5">
<layout class="QGridLayout" name="gridLayout">
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;Data</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>data</cstring>
</property>
</widget>
</item>
<item row="5" column="0" colspan="4">
<widget class="QSplitter" name="splitter_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QPlainTextEdit" name="data">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
</widget>
<widget class="QTextEdit" name="code">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>&amp;Gas</string>
</property>
<property name="buddy">
<cstring>gas</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;To</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="gas">
<property name="suffix">
<string> gas</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>430000000</number>
</property>
<property name="value">
<number>10000</number>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QComboBox" name="valueUnits"/>
</item>
<item row="3" column="3">
<widget class="QComboBox" name="gasPriceUnits"/>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="gasPrice">
<property name="prefix">
<string>@ </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>430000000</number>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="calculatedName">
<property name="enabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="placeholderText">
<string/>
</property>
</widget>
</item>
<item row="2" column="1" colspan="2">
<widget class="QSpinBox" name="value">
<property name="suffix">
<string/>
</property>
<property name="maximum">
<number>430000000</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label5_2">
<property name="text">
<string>&amp;Amount</string>
</property>
<property name="buddy">
<cstring>value</cstring>
</property>
</widget>
</item>
<item row="4" column="1" colspan="3">
<widget class="QLabel" name="fee">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QComboBox" name="destination">
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>(Create Contract)</string>
</property>
</item>
</widget>
</item>
<item row="6" column="3">
<widget class="QPushButton" name="send">
<property name="text">
<string>&amp;Execute</string>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QLabel" name="total">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="6" column="2">
<widget class="QPushButton" name="debug">
<property name="text">
<string>De&amp;bug</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QDockWidget" name="dockWidget_7">
<property name="features">
<set>QDockWidget::DockWidgetFeatureMask</set>
@ -1384,9 +1158,6 @@ font-size: 14pt</string>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>data</cstring>
</property>
</widget>
</item>
<item row="3" column="1" colspan="4">
@ -1439,9 +1210,6 @@ font-size: 14pt</string>
<property name="text">
<string>TTL</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="1" column="0">
@ -1455,9 +1223,6 @@ font-size: 14pt</string>
<property name="text">
<string>From</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="0" column="0">
@ -1471,9 +1236,6 @@ font-size: 14pt</string>
<property name="text">
<string>To</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="1" column="1" colspan="4">
@ -1504,9 +1266,6 @@ font-size: 14pt</string>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>data</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
@ -1533,9 +1292,6 @@ font-size: 14pt</string>
<property name="text">
<string>Work to Prove</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
</layout>
@ -1620,7 +1376,7 @@ font-size: 14pt</string>
</action>
<action name="newAccount">
<property name="text">
<string>&amp;New Address</string>
<string>&amp;New Address...</string>
</property>
</action>
<action name="about">
@ -1891,6 +1647,11 @@ font-size: 14pt</string>
<string>&amp;Kill Account</string>
</property>
</action>
<action name="newTransaction">
<property name="text">
<string>New &amp;Transaction...</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
@ -1913,23 +1674,30 @@ font-size: 14pt</string>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>destination</tabstop>
<tabstop>calculatedName</tabstop>
<tabstop>value</tabstop>
<tabstop>valueUnits</tabstop>
<tabstop>gas</tabstop>
<tabstop>gasPrice</tabstop>
<tabstop>gasPriceUnits</tabstop>
<tabstop>data</tabstop>
<tabstop>send</tabstop>
<tabstop>idealPeers</tabstop>
<tabstop>port</tabstop>
<tabstop>clientName</tabstop>
<tabstop>shhTo</tabstop>
<tabstop>shhFrom</tabstop>
<tabstop>shhTtl</tabstop>
<tabstop>shhTopic</tabstop>
<tabstop>shhWork</tabstop>
<tabstop>shhData</tabstop>
<tabstop>log</tabstop>
<tabstop>post</tabstop>
<tabstop>verbosity</tabstop>
<tabstop>jsConsole</tabstop>
<tabstop>tabWidget</tabstop>
<tabstop>urlEdit</tabstop>
<tabstop>webView</tabstop>
<tabstop>idealPeers</tabstop>
<tabstop>forceAddress</tabstop>
<tabstop>port</tabstop>
<tabstop>clientName</tabstop>
<tabstop>transactionQueue</tabstop>
<tabstop>pendingInfo</tabstop>
<tabstop>blockChainFilter</tabstop>
<tabstop>nameReg</tabstop>
<tabstop>nodes</tabstop>
<tabstop>whispers</tabstop>
<tabstop>jsInput</tabstop>
</tabstops>
<resources/>
<connections/>

320
alethzero/MainWin.cpp

@ -56,6 +56,8 @@
#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;
@ -63,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) "<div style=\"" S "\">"
#define Span(S) "<span style=\"" 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)
@ -99,12 +90,6 @@ QString Main::fromRaw(h256 _n, unsigned* _inc)
return QString();
}
static vector<KeyPair> keysAsVector(QList<KeyPair> const& keys)
{
auto list = keys.toStdList();
return {begin(list), end(list)};
}
QString contentsOfQResource(string const& res)
{
QFile file(QString::fromStdString(res));
@ -120,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);
@ -149,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);
@ -373,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())));
@ -412,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 (*)");
@ -673,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());
@ -743,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"));
@ -991,7 +968,6 @@ void Main::refreshNetwork()
void Main::refreshAll()
{
refreshDestination();
refreshBlockChain();
refreshBlockCount();
refreshPending();
@ -1042,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()";
@ -1573,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;
@ -1640,133 +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()
{
if (isCreation())
{
string src = ui->data->toPlainText().toStdString();
vector<string> 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 = "<h4>Solidity</h4>";
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(getFunctionHashes(compiler)).toHtmlEscaped() + "</pre>";
}
catch (dev::Exception const& exception)
{
ostringstream error;
solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler);
solidity = "<h4>Solidity</h4><pre>" + QString::fromStdString(error.str()).toHtmlEscaped() + "</pre>";
}
catch (...)
{
solidity = "<h4>Solidity</h4><pre>Uncaught exception.</pre>";
}
}
#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 = "<h4>Pre</h4><pre>" + QString::fromStdString(asmcode).toHtmlEscaped() + "</pre>";
if (m_enableOptimizer)
{
asmcode = compileLLLToAsm(src, true);
lll = "<h4>Opt</h4><pre>" + QString::fromStdString(asmcode).toHtmlEscaped() + "</pre>" + lll;
}
}
}
QString errs;
if (errors.size())
{
errs = "<h4>Errors</h4>";
for (auto const& i: errors)
errs.append("<div style=\"border-left: 6px solid #c00; margin-top: 2px\">" + QString::fromStdString(i).toHtmlEscaped() + "</div>");
}
ui->code->setHtml(errs + lll + solidity + "<h4>Code</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "<h4>Hex</h4>" Div(Mono) + QString::fromStdString(toHex(m_data)) + "</div>");
ui->gas->setMinimum((qint64)Client::txGas(m_data, 0));
if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true);
}
else
{
m_data = parseData(ui->data->toPlainText().toStdString());
ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true)));
if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size())
{
ui->gas->setMinimum((qint64)Client::txGas(m_data, 1));
if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true);
}
else
{
if (ui->gas->isEnabled())
m_backupGas = ui->gas->value();
ui->gas->setValue((qint64)Client::txGas(m_data));
ui->gas->setEnabled(false);
}
}
updateFee();
}
void Main::on_clearPending_triggered()
{
writeSettings();
@ -1791,54 +1613,6 @@ void Main::on_killBlockchain_triggered()
refreshAll();
}
bool Main::isCreation() const
{
return ui->destination->currentText().isEmpty() || ui->destination->currentText() == "(Create Contract)";
}
u256 Main::fee() const
{
return ui->gas->value() * gasPrice();
}
u256 Main::value() const
{
if (ui->valueUnits->currentIndex() == -1)
return 0;
return ui->value->value() * units()[units().size() - 1 - ui->valueUnits->currentIndex()].first;
}
u256 Main::gasPrice() const
{
if (ui->gasPriceUnits->currentIndex() == -1)
return 0;
return ui->gasPrice->value() * units()[units().size() - 1 - ui->gasPriceUnits->currentIndex()].first;
}
u256 Main::total() const
{
return value() + fee();
}
void Main::updateFee()
{
ui->fee->setText(QString("(gas sub-total: %1)").arg(formatBalance(fee()).c_str()));
auto totalReq = total();
ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str()));
bool ok = false;
for (auto i: m_myKeys)
if (ethereum()->balanceAt(i.address()) >= totalReq)
{
ok = true;
break;
}
ui->send->setEnabled(ok);
QPalette p = ui->total->palette();
p.setColor(QPalette::WindowText, QColor(ok ? 0x00 : 0x80, 0x00, 0x00));
ui->total->setPalette(p);
}
void Main::on_net_triggered()
{
ui->port->setEnabled(!ui->net->isChecked());
@ -1900,76 +1674,12 @@ void Main::on_mine_triggered()
ethereum()->stopMining();
}
void Main::on_send_clicked()
{
u256 totalReq = value() + fee();
for (auto i: m_myKeys)
if (ethereum()->balanceAt(i.address(), 0) >= totalReq)
{
Secret s = i.secret();
if (isCreation())
{
// If execution is a contract creation, add Natspec to
// a local Natspec LEVELDB
ethereum()->transact(s, value(), m_data, ui->gas->value(), gasPrice());
string src = ui->data->toPlainText().toStdString();
if (sourceIsSolidity(src))
try
{
dev::solidity::CompilerStack compiler;
m_data = compiler.compile(src, m_enableOptimizer);
for (string& s: compiler.getContractNames())
{
h256 contractHash = compiler.getContractCodeHash(s);
m_natspecDB.add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser));
}
}
catch (...)
{
statusBar()->showMessage("Couldn't compile Solidity Contract.");
}
}
else
ethereum()->transact(s, value(), fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice());
return;
}
statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount.");
}
void Main::keysChanged()
{
onBalancesChange();
m_server->setAccounts(keysAsVector(m_myKeys));
}
void Main::on_debug_clicked()
{
try
{
u256 totalReq = value() + fee();
for (auto i: m_myKeys)
if (ethereum()->balanceAt(i.address()) >= totalReq)
{
State st(ethereum()->postState());
Secret s = i.secret();
Transaction t = isCreation() ?
Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) :
Transaction(value(), gasPrice(), ui->gas->value(), fromString(ui->destination->currentText()), m_data, st.transactionsFrom(dev::toAddress(s)), s);
Debugger dw(this, this);
Executive e(st, ethereum()->blockChain(), 0);
dw.populate(e, t);
dw.exec();
return;
}
statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount.");
}
catch (dev::Exception const& _e)
{
statusBar()->showMessage("Error running transaction: " + QString::fromStdString(diagnostic_information(_e)));
// this output is aimed at developers, reconsider using _e.what for more user friendly output.
}
}
bool beginsWith(Address _a, bytes const& _b)
{
for (unsigned i = 0; i < min<unsigned>(20, _b.size()); ++i)
@ -2095,16 +1805,6 @@ void Main::on_post_clicked()
whisper()->inject(m.seal(from, topicFromText(ui->shhTopic->toPlainText()), ui->shhTtl->value(), ui->shhWork->value()));
}
string Main::lookupNatSpec(dev::h256 const& _contractHash) const
{
return m_natspecDB.retrieve(_contractHash);
}
string Main::lookupNatSpecUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionData)
{
return m_natspecDB.getUserNotice(_contractHash, _transactionData);
}
int Main::authenticate(QString _title, QString _text)
{
QMessageBox userInput(this);

45
alethzero/MainWin.h

@ -37,7 +37,7 @@
#include <libwebthree/WebThree.h>
#include <libsolidity/CompilerStack.h>
#include "Context.h"
#include "Debugger.h"
#include "Transact.h"
#include "NatspecHandler.h"
namespace Ui {
@ -72,10 +72,7 @@ public:
dev::eth::Client* ethereum() const { return m_webThree->ethereum(); }
std::shared_ptr<dev::shh::WhisperHost> whisper() const { return m_webThree->whisper(); }
std::string lookupNatSpec(dev::h256 const& _contractHash) const;
std::string lookupNatSpecUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionData);
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
NatSpecFace* natSpec() { return &m_natSpecDB; }
QVariant evalRaw(QString const& _js);
@ -85,6 +82,10 @@ public:
dev::Address fromString(QString const& _a) const override;
std::string renderDiff(dev::eth::StateDiff const& _d) const override;
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
dev::u256 gasPrice() const { return 10 * dev::eth::szabo; }
public slots:
void load(QString _file);
void note(QString _entry);
@ -118,17 +119,6 @@ private slots:
void on_showAllAccounts_triggered() { refreshAccounts(); }
void on_preview_triggered();
// Transacting
void on_value_valueChanged() { updateFee(); }
void on_gas_valueChanged() { updateFee(); }
void on_valueUnits_currentIndexChanged() { updateFee(); }
void on_gasPriceUnits_currentIndexChanged() { updateFee(); }
void on_gasPrice_valueChanged() { updateFee(); }
void on_destination_currentTextChanged();
void on_data_textChanged();
void on_send_clicked();
void on_debug_clicked();
// Account management
void on_newAccount_triggered();
void on_killAccount_triggered();
@ -137,6 +127,7 @@ private slots:
void on_exportKey_triggered();
// Tools
void on_newTransaction_triggered();
void on_loadJS_triggered();
// Stuff concerning the blocks/transactions/accounts panels
@ -165,7 +156,6 @@ private slots:
void on_inject_triggered();
void on_forceMining_triggered();
void on_usePrivate_triggered();
void on_enableOptimizer_triggered();
void on_turboMining_triggered();
void on_jitvm_triggered();
@ -196,12 +186,6 @@ private:
void readSettings(bool _skipGeometry = false);
void writeSettings();
bool isCreation() const;
dev::u256 fee() const;
dev::u256 total() const;
dev::u256 value() const;
dev::u256 gasPrice() const;
unsigned installWatch(dev::eth::LogFilter const& _tf, WatchHandler const& _f);
unsigned installWatch(dev::h256 _tf, WatchHandler const& _f);
void uninstallWatch(unsigned _w);
@ -228,15 +212,9 @@ private:
void refreshAll();
void refreshPending();
void refreshAccounts();
void refreshDestination();
void refreshBlockCount();
void refreshBalances();
/// Attempts to infer that @c _source contains Solidity code
bool sourceIsSolidity(std::string const& _source);
/// @eturns all method hashes of a Solidity contract in a string
std::string const getFunctionHashes(dev::solidity::CompilerStack const &_compiler, std::string const& _contractName = "");
std::unique_ptr<Ui::Main> ui;
std::unique_ptr<dev::WebThreeDirect> m_webThree;
@ -251,13 +229,8 @@ private:
QList<dev::KeyPair> m_myKeys;
QList<dev::KeyPair> m_myIdentities;
QString m_privateChain;
dev::bytes m_data;
dev::Address m_nameReg;
unsigned m_backupGas;
bool m_enableOptimizer = true;
QNetworkAccessManager m_webCtrl;
QList<QPair<QString, QString>> m_consoleHistory;
@ -269,5 +242,7 @@ private:
std::unique_ptr<OurWebThreeStubServer> m_server;
static QString fromRaw(dev::h256 _n, unsigned* _inc = nullptr);
NatspecHandler m_natspecDB;
NatspecHandler m_natSpecDB;
Transact m_transact;
};

5
alethzero/NatspecHandler.h

@ -28,10 +28,11 @@
#pragma warning(pop)
#include <json/json.h>
#include <libdevcore/FixedHash.h>
#include "Context.h"
namespace ldb = leveldb;
class NatspecHandler
class NatspecHandler: public NatSpecFace
{
public:
NatspecHandler();
@ -40,7 +41,7 @@ class NatspecHandler
/// Stores locally in a levelDB a key value pair of contract code hash to natspec documentation
void add(dev::h256 const& _contractHash, std::string const& _doc);
/// Retrieves the natspec documentation as a string given a contract code hash
std::string retrieve(dev::h256 const& _contractHash) const;
std::string retrieve(dev::h256 const& _contractHash) const override;
/// Given a json natspec string and the transaction data return the user notice
std::string getUserNotice(std::string const& json, const dev::bytes& _transactionData);

2
alethzero/OurWebThreeStubServer.cpp

@ -92,7 +92,7 @@ bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t)
}
// TODO: include total cost in Ether
string userNotice = m_main->lookupNatSpecUserNotice(contractCodeHash, _t.data);
string userNotice = m_main->natSpec()->getUserNotice(contractCodeHash, _t.data);
if (userNotice.empty())
return showUnknownCallNotice(_t);

325
alethzero/Transact.cpp

@ -0,0 +1,325 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Transact.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#include "Transact.h"
#include <fstream>
#include <QFileDialog>
#include <QMessageBox>
#include <liblll/Compiler.h>
#include <liblll/CodeFragment.h>
#include <libsolidity/CompilerStack.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/AST.h>
#include <libsolidity/SourceReferenceFormatter.h>
#include <libethereum/Client.h>
#include <libethereum/Utility.h>
#ifndef _MSC_VER
#include <libserpent/funcs.h>
#include <libserpent/util.h>
#endif
#include "Debugger.h"
#include "ui_Transact.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
Transact::Transact(Context* _c, QWidget* _parent):
QDialog(_parent),
ui(new Ui::Transact),
m_context(_c)
{
ui->setupUi(this);
initUnits(ui->gasPriceUnits);
initUnits(ui->valueUnits);
ui->valueUnits->setCurrentIndex(6);
ui->gasPriceUnits->setCurrentIndex(4);
ui->gasPrice->setValue(10);
on_destination_currentTextChanged();
}
Transact::~Transact()
{
delete ui;
}
void Transact::setEnvironment(QList<dev::KeyPair> _myKeys, dev::eth::Client* _eth, NatSpecFace* _natSpecDB)
{
m_myKeys = _myKeys;
m_ethereum = _eth;
m_natSpecDB = _natSpecDB;
}
bool Transact::isCreation() const
{
return ui->destination->currentText().isEmpty() || ui->destination->currentText() == "(Create Contract)";
}
u256 Transact::fee() const
{
return ui->gas->value() * gasPrice();
}
u256 Transact::value() const
{
if (ui->valueUnits->currentIndex() == -1)
return 0;
return ui->value->value() * units()[units().size() - 1 - ui->valueUnits->currentIndex()].first;
}
u256 Transact::gasPrice() const
{
if (ui->gasPriceUnits->currentIndex() == -1)
return 0;
return ui->gasPrice->value() * units()[units().size() - 1 - ui->gasPriceUnits->currentIndex()].first;
}
u256 Transact::total() const
{
return value() + fee();
}
void Transact::updateDestination()
{
cwatch << "updateDestination()";
QString s;
for (auto i: ethereum()->addresses())
if ((s = m_context->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)" && !m_context->fromString(ui->destination->itemText(i)))
ui->destination->removeItem(i--);
}
void Transact::updateFee()
{
ui->fee->setText(QString("(gas sub-total: %1)").arg(formatBalance(fee()).c_str()));
auto totalReq = total();
ui->total->setText(QString("Total: %1").arg(formatBalance(totalReq).c_str()));
bool ok = false;
for (auto i: m_myKeys)
if (ethereum()->balanceAt(i.address()) >= totalReq)
{
ok = true;
break;
}
ui->send->setEnabled(ok);
QPalette p = ui->total->palette();
p.setColor(QPalette::WindowText, QColor(ok ? 0x00 : 0x80, 0x00, 0x00));
ui->total->setPalette(p);
}
string Transact::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 Transact::on_destination_currentTextChanged()
{
if (ui->destination->currentText().size() && ui->destination->currentText() != "(Create Contract)")
if (Address a = m_context->fromString(ui->destination->currentText()))
ui->calculatedName->setText(m_context->render(a));
else
ui->calculatedName->setText("Unknown Address");
else
ui->calculatedName->setText("Create Contract");
rejigData();
// updateFee();
}
void Transact::rejigData()
{
if (isCreation())
{
string src = ui->data->toPlainText().toStdString();
vector<string> 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, ui->optimize->isChecked());
solidity = "<h4>Solidity</h4>";
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(getFunctionHashes(compiler)).toHtmlEscaped() + "</pre>";
}
catch (dev::Exception const& exception)
{
ostringstream error;
solidity::SourceReferenceFormatter::printExceptionInformation(error, exception, "Error", compiler);
solidity = "<h4>Solidity</h4><pre>" + QString::fromStdString(error.str()).toHtmlEscaped() + "</pre>";
}
catch (...)
{
solidity = "<h4>Solidity</h4><pre>Uncaught exception.</pre>";
}
}
#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, ui->optimize->isChecked(), &errors);
if (errors.empty())
{
auto asmcode = compileLLLToAsm(src, false);
lll = "<h4>Pre</h4><pre>" + QString::fromStdString(asmcode).toHtmlEscaped() + "</pre>";
if (ui->optimize->isChecked())
{
asmcode = compileLLLToAsm(src, true);
lll = "<h4>Opt</h4><pre>" + QString::fromStdString(asmcode).toHtmlEscaped() + "</pre>" + lll;
}
}
}
QString errs;
if (errors.size())
{
errs = "<h4>Errors</h4>";
for (auto const& i: errors)
errs.append("<div style=\"border-left: 6px solid #c00; margin-top: 2px\">" + QString::fromStdString(i).toHtmlEscaped() + "</div>");
}
ui->code->setHtml(errs + lll + solidity + "<h4>Code</h4>" + QString::fromStdString(disassemble(m_data)).toHtmlEscaped() + "<h4>Hex</h4>" Div(Mono) + QString::fromStdString(toHex(m_data)) + "</div>");
ui->gas->setMinimum((qint64)Interface::txGas(m_data, 0));
if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true);
}
else
{
m_data = parseData(ui->data->toPlainText().toStdString());
ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true)));
if (ethereum()->codeAt(m_context->fromString(ui->destination->currentText()), 0).size())
{
ui->gas->setMinimum((qint64)Interface::txGas(m_data, 1));
if (!ui->gas->isEnabled())
ui->gas->setValue(m_backupGas);
ui->gas->setEnabled(true);
}
else
{
if (ui->gas->isEnabled())
m_backupGas = ui->gas->value();
ui->gas->setValue((qint64)Interface::txGas(m_data));
ui->gas->setEnabled(false);
}
}
updateFee();
}
void Transact::on_send_clicked()
{
u256 totalReq = value() + fee();
for (auto const& i: m_myKeys)
if (ethereum()->balanceAt(i.address(), 0) >= totalReq)
{
Secret s = i.secret();
if (isCreation())
{
// If execution is a contract creation, add Natspec to
// a local Natspec LEVELDB
ethereum()->transact(s, value(), m_data, ui->gas->value(), gasPrice());
string src = ui->data->toPlainText().toStdString();
if (sourceIsSolidity(src))
try
{
dev::solidity::CompilerStack compiler;
m_data = compiler.compile(src, ui->optimize->isChecked());
for (string const& s: compiler.getContractNames())
{
h256 contractHash = compiler.getContractCodeHash(s);
m_natSpecDB->add(contractHash, compiler.getMetadata(s, dev::solidity::DocumentationType::NatspecUser));
}
}
catch (...)
{
}
close();
return;
}
else
ethereum()->transact(s, value(), m_context->fromString(ui->destination->currentText()), m_data, ui->gas->value(), gasPrice());
return;
}
QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount.");
}
void Transact::on_debug_clicked()
{
try
{
u256 totalReq = value() + fee();
for (auto i: m_myKeys)
if (ethereum()->balanceAt(i.address()) >= totalReq)
{
State st(ethereum()->postState());
Secret s = i.secret();
Transaction t = isCreation() ?
Transaction(value(), gasPrice(), ui->gas->value(), m_data, st.transactionsFrom(dev::toAddress(s)), s) :
Transaction(value(), gasPrice(), ui->gas->value(), m_context->fromString(ui->destination->currentText()), m_data, st.transactionsFrom(dev::toAddress(s)), s);
Debugger dw(m_context, this);
Executive e(st, ethereum()->blockChain(), 0);
dw.populate(e, t);
dw.exec();
close();
return;
}
QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction: no single account contains at least the required amount.");
}
catch (dev::Exception const& _e)
{
QMessageBox::critical(this, "Transaction Failed", "Couldn't make transaction. Low-level error: " + QString::fromStdString(diagnostic_information(_e)));
// this output is aimed at developers, reconsider using _e.what for more user friendly output.
}
}

82
alethzero/Transact.h

@ -0,0 +1,82 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Transact.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#pragma once
#include <libdevcore/RLP.h>
#include <libethcore/CommonEth.h>
#include <libethereum/Transaction.h>
#include <QDialog>
#include <QMap>
#include <QList>
#include "Context.h"
namespace Ui { class Transact; }
namespace dev { namespace eth { class Client; } }
namespace dev { namespace solidity { class CompilerStack; } }
class Transact: public QDialog
{
Q_OBJECT
public:
explicit Transact(Context* _context, QWidget* _parent = 0);
~Transact();
void setEnvironment(QList<dev::KeyPair> _myKeys, dev::eth::Client* _eth, NatSpecFace* _natSpecDB);
private slots:
void on_destination_currentTextChanged();
void on_value_valueChanged() { updateFee(); }
void on_gas_valueChanged() { updateFee(); }
void on_valueUnits_currentIndexChanged() { updateFee(); }
void on_gasPriceUnits_currentIndexChanged() { updateFee(); }
void on_gasPrice_valueChanged() { updateFee(); }
void on_data_textChanged() { rejigData(); }
void on_optimize_clicked() { rejigData(); }
void on_send_clicked();
void on_debug_clicked();
void on_cancel_clicked() { close(); }
private:
dev::eth::Client* ethereum() { return m_ethereum; }
void rejigData();
void updateDestination();
void updateFee();
bool isCreation() const;
dev::u256 fee() const;
dev::u256 total() const;
dev::u256 value() const;
dev::u256 gasPrice() const;
std::string getFunctionHashes(dev::solidity::CompilerStack const& _compiler, std::string const& _contractName = std::string());
Ui::Transact* ui;
unsigned m_backupGas;
dev::bytes m_data;
QList<dev::KeyPair> m_myKeys;
dev::eth::Client* m_ethereum;
Context* m_context;
NatSpecFace* m_natSpecDB;
};

244
alethzero/Transact.ui

@ -0,0 +1,244 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Transact</class>
<widget class="QDialog" name="Transact">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>543</width>
<height>695</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="2" column="1" colspan="2">
<widget class="QSpinBox" name="value">
<property name="suffix">
<string/>
</property>
<property name="maximum">
<number>430000000</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label5_2">
<property name="text">
<string>&amp;Amount</string>
</property>
<property name="buddy">
<cstring>value</cstring>
</property>
</widget>
</item>
<item row="1" column="1" colspan="3">
<widget class="QLineEdit" name="calculatedName">
<property name="enabled">
<bool>false</bool>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
<property name="placeholderText">
<string/>
</property>
</widget>
</item>
<item row="5" column="0" colspan="4">
<widget class="QSplitter" name="splitter_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QPlainTextEdit" name="data">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
</widget>
<widget class="QTextEdit" name="code">
<property name="focusPolicy">
<enum>Qt::ClickFocus</enum>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
<item row="3" column="3">
<widget class="QComboBox" name="gasPriceUnits"/>
</item>
<item row="4" column="1" colspan="2">
<widget class="QLabel" name="fee">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&amp;To</string>
</property>
<property name="buddy">
<cstring>destination</cstring>
</property>
</widget>
</item>
<item row="2" column="3">
<widget class="QComboBox" name="valueUnits"/>
</item>
<item row="7" column="2">
<widget class="QPushButton" name="debug">
<property name="text">
<string>&amp;Debug</string>
</property>
</widget>
</item>
<item row="7" column="3">
<widget class="QPushButton" name="send">
<property name="text">
<string>&amp;Execute</string>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_6">
<property name="text">
<string>&amp;Gas</string>
</property>
<property name="buddy">
<cstring>gas</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="gas">
<property name="suffix">
<string> gas</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>430000000</number>
</property>
<property name="value">
<number>10000</number>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="QSpinBox" name="gasPrice">
<property name="prefix">
<string>@ </string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>430000000</number>
</property>
</widget>
</item>
<item row="4" column="3">
<widget class="QCheckBox" name="optimize">
<property name="text">
<string>&amp;Optimise</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>D&amp;ata</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
<property name="buddy">
<cstring>data</cstring>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QComboBox" name="destination">
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string>(Create Contract)</string>
</property>
</item>
</widget>
</item>
<item row="6" column="0" colspan="4">
<widget class="QLabel" name="total">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QPushButton" name="cancel">
<property name="text">
<string>&amp;Cancel</string>
</property>
<property name="shortcut">
<string>Esc</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

10
libethcore/CommonEth.cpp

@ -35,16 +35,6 @@ namespace eth
const unsigned c_protocolVersion = 53;
const unsigned c_databaseVersion = 5;
template <size_t n> u256 exp10()
{
return exp10<n - 1>() * u256(10);
}
template <> u256 exp10<0>()
{
return u256(1);
}
vector<pair<u256, string>> const& units()
{
static const vector<pair<u256, string>> s_units =

33
libethcore/CommonEth.h

@ -47,26 +47,21 @@ std::vector<std::pair<u256, std::string>> const& units();
/// The log bloom's size (512 bit).
using LogBloom = h512;
template <size_t n> inline u256 exp10()
{
return exp10<n - 1>() * u256(10);
}
template <> inline u256 exp10<0>()
{
return u256(1);
}
// The various denominations; here for ease of use where needed within code.
/*static const u256 Uether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000;
static const u256 Vether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000;
static const u256 Dether = ((((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000;
static const u256 Nether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000000;
static const u256 Yether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000000;
static const u256 Zether = (((u256(1000000000) * 1000000000) * 1000000000) * 1000000000) * 1000;
static const u256 Eether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000000000;
static const u256 Pether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000000;
static const u256 Tether = ((u256(1000000000) * 1000000000) * 1000000000) * 1000;
static const u256 Gether = (u256(1000000000) * 1000000000) * 1000000000;
static const u256 Mether = (u256(1000000000) * 1000000000) * 1000000;
static const u256 grand = (u256(1000000000) * 1000000000) * 1000;*/
static const u256 ether = u256(1000000000) * 1000000000;
static const u256 finney = u256(1000000000) * 1000000;
static const u256 szabo = u256(1000000000) * 1000;
/*static const u256 Gwei = u256(1000000000);
static const u256 Mwei = u256(1000000);
static const u256 Kwei = u256(1000);*/
static const u256 wei = u256(1);
static const u256 ether = exp10<18>();
static const u256 finney = exp10<15>();
static const u256 szabo = exp10<12>();
static const u256 wei = exp10<0>();
}
}

Loading…
Cancel
Save