Browse Source

Merge remote-tracking branch 'upstream/develop' into winsvegaBlock2

cl-refactor
CJentzsch 10 years ago
parent
commit
be88673c9a
  1. 3
      alethzero/CMakeLists.txt
  2. 29
      alethzero/Main.ui
  3. 5
      alethzero/MainFace.h
  4. 82
      alethzero/MainWin.cpp
  5. 6
      alethzero/MainWin.h
  6. 15
      alethzero/Transact.cpp
  7. 26
      alethzero/plugins/blockchain/AllAccounts.cpp
  8. 2
      alethzero/plugins/blockchain/AllAccounts.h
  9. 11
      alethzero/plugins/blockchain/AllAccounts.ui
  10. 91
      alethzero/plugins/blockchain/ExportState.cpp
  11. 15
      alethzero/plugins/blockchain/ExportState.h
  12. 0
      alethzero/plugins/blockchain/ExportState.ui
  13. 222
      alethzero/plugins/keys/ImportKey.cpp
  14. 44
      alethzero/plugins/keys/ImportKey.h
  15. 336
      alethzero/plugins/keys/ImportKey.ui
  16. 19
      alethzero/plugins/namers/OtherAccounts.cpp
  17. 87
      alethzero/plugins/special/InjectTransactions.cpp
  18. 48
      alethzero/plugins/special/InjectTransactions.h
  19. 95
      alethzero/plugins/special/InjectTransactions.ui
  20. 72
      eth/main.cpp
  21. 553
      ethkey/KeyAux.h
  22. 2
      evmjit/libevmjit/Array.h
  23. 8
      evmjit/libevmjit/BasicBlock.cpp
  24. 86
      evmjit/libevmjit/Compiler.cpp
  25. 4
      evmjit/libevmjit/Compiler.h
  26. 2
      evmjit/libevmjit/Stack.cpp
  27. 9
      libdevcore/FixedHash.cpp
  28. 3
      libdevcore/vector_ref.h
  29. 20
      libdevcrypto/SecretStore.cpp
  30. 3
      libdevcrypto/SecretStore.h
  31. 4
      libethcore/Common.cpp
  32. 17
      libethcore/KeyManager.cpp
  33. 6
      libethcore/KeyManager.h
  34. 24
      libjsqrc/ethereumjs/dist/web3-light.js
  35. 4
      libjsqrc/ethereumjs/dist/web3-light.min.js
  36. 24
      libjsqrc/ethereumjs/dist/web3.js
  37. 4
      libjsqrc/ethereumjs/dist/web3.js.map
  38. 4
      libjsqrc/ethereumjs/dist/web3.min.js
  39. 24
      libjsqrc/ethereumjs/lib/web3/shh.js
  40. 26
      mix/qml/Block.qml
  41. 21
      mix/qml/Watchers.qml
  42. BIN
      mix/qml/img/rightarrowcircle.png
  43. 1
      mix/res.qrc
  44. 4
      templates/dockplugin.cpp
  45. 4
      templates/plugin.cpp

3
alethzero/CMakeLists.txt

@ -42,7 +42,6 @@ qt5_wrap_ui(ui_Main.h Main.ui)
qt5_wrap_ui(ui_Connect.h Connect.ui) qt5_wrap_ui(ui_Connect.h Connect.ui)
qt5_wrap_ui(ui_Debugger.h Debugger.ui) qt5_wrap_ui(ui_Debugger.h Debugger.ui)
qt5_wrap_ui(ui_Transact.h Transact.ui) qt5_wrap_ui(ui_Transact.h Transact.ui)
qt5_wrap_ui(ui_ExportState.h ExportState.ui)
qt5_wrap_ui(ui_GetPassword.h GetPassword.ui) qt5_wrap_ui(ui_GetPassword.h GetPassword.ui)
qt5_wrap_ui(ui_GasPricing.h GasPricing.ui) qt5_wrap_ui(ui_GasPricing.h GasPricing.ui)
@ -60,7 +59,7 @@ endif ()
# eth_add_executable is defined in cmake/EthExecutableHelper.cmake # eth_add_executable is defined in cmake/EthExecutableHelper.cmake
eth_add_executable(${EXECUTABLE} eth_add_executable(${EXECUTABLE}
ICON alethzero ICON alethzero
UI_RESOURCES ${PLUGIN_UI} alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui GetPassword.ui GasPricing.ui UI_RESOURCES ${PLUGIN_UI} alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui GetPassword.ui GasPricing.ui
WIN_RESOURCES alethzero.rc WIN_RESOURCES alethzero.rc
) )

29
alethzero/Main.ui

@ -132,7 +132,7 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1617</width> <width>1617</width>
<height>22</height> <height>24</height>
</rect> </rect>
</property> </property>
<widget class="QMenu" name="menuFile"> <widget class="QMenu" name="menuFile">
@ -164,6 +164,7 @@
<addaction name="newTransaction"/> <addaction name="newTransaction"/>
<addaction name="importKey"/> <addaction name="importKey"/>
<addaction name="importKeyFile"/> <addaction name="importKeyFile"/>
<addaction name="importPresale"/>
<addaction name="claimPresale"/> <addaction name="claimPresale"/>
<addaction name="exportKey"/> <addaction name="exportKey"/>
<addaction name="reencryptAll"/> <addaction name="reencryptAll"/>
@ -172,7 +173,6 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="loadJS"/> <addaction name="loadJS"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="exportState"/>
</widget> </widget>
<widget class="QMenu" name="menuHelp"> <widget class="QMenu" name="menuHelp">
<property name="title"> <property name="title">
@ -188,7 +188,6 @@
<addaction name="paranoia"/> <addaction name="paranoia"/>
<addaction name="clearPending"/> <addaction name="clearPending"/>
<addaction name="killBlockchain"/> <addaction name="killBlockchain"/>
<addaction name="inject"/>
<addaction name="injectBlock"/> <addaction name="injectBlock"/>
<addaction name="forceMining"/> <addaction name="forceMining"/>
<addaction name="separator"/> <addaction name="separator"/>
@ -213,6 +212,7 @@
<property name="title"> <property name="title">
<string>&amp;Debug</string> <string>&amp;Debug</string>
</property> </property>
<addaction name="debugPending"/>
<addaction name="debugCurrent"/> <addaction name="debugCurrent"/>
<addaction name="debugDumpState"/> <addaction name="debugDumpState"/>
<addaction name="debugDumpStatePre"/> <addaction name="debugDumpStatePre"/>
@ -1097,11 +1097,6 @@ font-size: 14pt</string>
<string>&amp;Load Javascript...</string> <string>&amp;Load Javascript...</string>
</property> </property>
</action> </action>
<action name="exportState">
<property name="text">
<string>&amp;Export State...</string>
</property>
</action>
<action name="debugStepBack"> <action name="debugStepBack">
<property name="enabled"> <property name="enabled">
<bool>false</bool> <bool>false</bool>
@ -1387,6 +1382,24 @@ font-size: 14pt</string>
<string>Dump &amp;Block State as JSON...</string> <string>Dump &amp;Block State as JSON...</string>
</property> </property>
</action> </action>
<action name="bulkTransactions">
<property name="text">
<string>&amp;Bulk Inject Transactions...</string>
</property>
</action>
<action name="debugPending">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Debug &amp;Pending Transaction</string>
</property>
</action>
<action name="importPresale">
<property name="text">
<string>Import Ether &amp;Presale Wallet...</string>
</property>
</action>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<customwidgets> <customwidgets>

5
alethzero/MainFace.h

@ -43,8 +43,13 @@ namespace shh { class WhisperHost; }
namespace az namespace az
{ {
#ifndef _MSC_VER // MSVC does not like gcc compiler attributes
#define DEV_AZ_NOTE_PLUGIN(ClassName) \
static bool s_notePlugin __attribute__((unused)) = [](){ MainFace::notePlugin([](MainFace* m){ return new ClassName(m); }); return true; }()
#else
#define DEV_AZ_NOTE_PLUGIN(ClassName) \ #define DEV_AZ_NOTE_PLUGIN(ClassName) \
static bool s_notePlugin = [](){ MainFace::notePlugin([](MainFace* m){ return new ClassName(m); }); return true; }() static bool s_notePlugin = [](){ MainFace::notePlugin([](MainFace* m){ return new ClassName(m); }); return true; }()
#endif
class Plugin; class Plugin;
class MainFace; class MainFace;

82
alethzero/MainWin.cpp

@ -73,7 +73,6 @@
#include "DappLoader.h" #include "DappLoader.h"
#include "DappHost.h" #include "DappHost.h"
#include "WebPage.h" #include "WebPage.h"
#include "ExportState.h"
#include "ui_Main.h" #include "ui_Main.h"
#include "ui_GetPassword.h" #include "ui_GetPassword.h"
#include "ui_GasPricing.h" #include "ui_GasPricing.h"
@ -241,7 +240,7 @@ Main::Main(QWidget* _parent):
ui->vmSmart->setEnabled(false); ui->vmSmart->setEnabled(false);
#endif #endif
readSettings(); readSettings(true, false);
m_transact = new Transact(this, this); m_transact = new Transact(this, this);
m_transact->setWindowFlags(Qt::Dialog); m_transact->setWindowFlags(Qt::Dialog);
@ -263,6 +262,8 @@ Main::Main(QWidget* _parent):
for (auto const& i: *s_linkedPlugins) for (auto const& i: *s_linkedPlugins)
initPlugin(i(this)); initPlugin(i(this));
readSettings(false, true);
} }
Main::~Main() Main::~Main()
@ -668,9 +669,10 @@ std::string Main::render(dev::Address const& _a) const
if (p.size() == 9 && p.find_first_not_of("QWERYUOPASDFGHJKLZXCVBNM1234567890") == string::npos) if (p.size() == 9 && p.find_first_not_of("QWERYUOPASDFGHJKLZXCVBNM1234567890") == string::npos)
p = ICAP(p, "XREG").encoded(); p = ICAP(p, "XREG").encoded();
else else
DEV_IGNORE_EXCEPTIONS(n = ICAP(_a).encoded()); DEV_IGNORE_EXCEPTIONS(n = ICAP(_a).encoded().substr(0, 8));
if (n.empty()) if (!n.empty())
n = _a.abridged(); n += " ";
n += _a.abridged();
return p.empty() ? n : (p + " " + n); return p.empty() ? n : (p + " " + n);
} }
@ -850,13 +852,15 @@ Secret Main::retrieveSecret(Address const& _address) const
} }
} }
void Main::readSettings(bool _skipGeometry) void Main::readSettings(bool _skipGeometry, bool _onlyGeometry)
{ {
QSettings s("ethereum", "alethzero"); QSettings s("ethereum", "alethzero");
if (!_skipGeometry) if (!_skipGeometry)
restoreGeometry(s.value("geometry").toByteArray()); restoreGeometry(s.value("geometry").toByteArray());
restoreState(s.value("windowState").toByteArray()); restoreState(s.value("windowState").toByteArray());
if (_onlyGeometry)
return;
forEach([&](std::shared_ptr<Plugin> p) forEach([&](std::shared_ptr<Plugin> p)
{ {
@ -1018,6 +1022,28 @@ void Main::on_claimPresale_triggered()
} }
} }
void Main::on_importPresale_triggered()
{
QString s = QFileDialog::getOpenFileName(this, "Claim Account Contents", QDir::homePath(), "JSON Files (*.json);;All Files (*)");
try
{
string pass;
KeyPair k = m_keyManager.presaleSecret(dev::contentsString(s.toStdString()), [&](bool){ return (pass = QInputDialog::getText(this, "Enter Password", "Enter the wallet's passphrase", QLineEdit::Password).toStdString()); });
cnote << k.address();
if (!m_keyManager.hasAccount(k.address()))
keyManager().import(k.secret(), "Presale wallet (" + s.toStdString() + ")", pass, "Same password as for the presale wallet");
else
QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account.");
}
catch (dev::eth::PasswordUnknown&) {}
catch (...)
{
cerr << "Unhandled exception!" << endl <<
boost::current_exception_diagnostic_information();
QMessageBox::warning(this, "Key File Invalid", "Could not find secret key definition. This is probably not an Ethereum key file.");
}
}
void Main::on_exportKey_triggered() void Main::on_exportKey_triggered()
{ {
if (ui->ourAccounts->currentRow() >= 0) if (ui->ourAccounts->currentRow() >= 0)
@ -1029,12 +1055,6 @@ void Main::on_exportKey_triggered()
} }
} }
void Main::on_exportState_triggered()
{
ExportStateDialog dialog(this);
dialog.exec();
}
void Main::on_usePrivate_triggered() void Main::on_usePrivate_triggered()
{ {
QString pc; QString pc;
@ -1549,6 +1569,7 @@ void Main::on_transactionQueue_currentItemChanged()
int i = ui->transactionQueue->currentRow(); int i = ui->transactionQueue->currentRow();
if (i >= 0 && i < (int)ethereum()->pending().size()) if (i >= 0 && i < (int)ethereum()->pending().size())
{ {
ui->debugPending->setEnabled(true);
Transaction tx(ethereum()->pending()[i]); Transaction tx(ethereum()->pending()[i]);
TransactionReceipt receipt(ethereum()->postState().receipt(i)); TransactionReceipt receipt(ethereum()->postState().receipt(i));
auto ss = tx.safeSender(); auto ss = tx.safeSender();
@ -1588,30 +1609,13 @@ void Main::on_transactionQueue_currentItemChanged()
// s << "Pre: " << fs.rootHash() << "<br/>"; // s << "Pre: " << fs.rootHash() << "<br/>";
// s << "Post: <b>" << ts.rootHash() << "</b>"; // s << "Post: <b>" << ts.rootHash() << "</b>";
} }
else
ui->debugPending->setEnabled(false);
ui->pendingInfo->setHtml(QString::fromStdString(s.str())); ui->pendingInfo->setHtml(QString::fromStdString(s.str()));
ui->pendingInfo->moveCursor(QTextCursor::Start); ui->pendingInfo->moveCursor(QTextCursor::Start);
} }
void Main::on_inject_triggered()
{
QString s = QInputDialog::getText(this, "Inject Transaction", "Enter transaction dump in hex");
try
{
bytes b = fromHex(s.toStdString(), WhenError::Throw);
ethereum()->injectTransaction(b);
}
catch (BadHexCharacter& _e)
{
cwarn << "invalid hex character, transaction rejected";
cwarn << boost::diagnostic_information(_e);
}
catch (...)
{
cwarn << "transaction rejected";
}
}
void Main::on_injectBlock_triggered() void Main::on_injectBlock_triggered()
{ {
QString s = QInputDialog::getText(this, "Inject Block", "Enter block dump in hex"); QString s = QInputDialog::getText(this, "Inject Block", "Enter block dump in hex");
@ -1804,6 +1808,22 @@ void Main::on_debugCurrent_triggered()
} }
} }
void Main::on_debugPending_triggered()
{
int txi = ui->transactionQueue->currentRow();
if (txi == -1)
return;
Block b = ethereum()->postState();
bytes t = b.pending()[txi].rlp();
State s(ethereum()->state(txi));
BlockInfo bi(b.info());
Executive e(s, ethereum()->blockChain(), EnvInfo(bi));
Debugger dw(this, this);
dw.populate(e, Transaction(t, CheckTransaction::Everything));
dw.exec();
}
std::string minHex(h256 const& _h) std::string minHex(h256 const& _h)
{ {
unsigned i = 0; unsigned i = 0;

6
alethzero/MainWin.h

@ -157,12 +157,12 @@ private slots:
void on_reencryptAll_triggered(); void on_reencryptAll_triggered();
void on_importKeyFile_triggered(); void on_importKeyFile_triggered();
void on_claimPresale_triggered(); void on_claimPresale_triggered();
void on_importPresale_triggered();
void on_exportKey_triggered(); void on_exportKey_triggered();
// Tools // Tools
void on_newTransaction_triggered(); void on_newTransaction_triggered();
void on_loadJS_triggered(); void on_loadJS_triggered();
void on_exportState_triggered();
// Stuff concerning the blocks/transactions/accounts panels // Stuff concerning the blocks/transactions/accounts panels
void on_ourAccounts_itemClicked(QListWidgetItem* _i); void on_ourAccounts_itemClicked(QListWidgetItem* _i);
@ -180,7 +180,6 @@ private slots:
void on_paranoia_triggered(); void on_paranoia_triggered();
void on_killBlockchain_triggered(); void on_killBlockchain_triggered();
void on_clearPending_triggered(); void on_clearPending_triggered();
void on_inject_triggered();
void on_injectBlock_triggered(); void on_injectBlock_triggered();
void on_forceMining_triggered(); void on_forceMining_triggered();
void on_usePrivate_triggered(); void on_usePrivate_triggered();
@ -193,6 +192,7 @@ private slots:
// Debugger // Debugger
void on_debugCurrent_triggered(); void on_debugCurrent_triggered();
void on_debugPending_triggered();
void on_debugDumpState_triggered() { debugDumpState(1); } void on_debugDumpState_triggered() { debugDumpState(1); }
void on_debugDumpStatePre_triggered() { debugDumpState(0); } void on_debugDumpStatePre_triggered() { debugDumpState(0); }
void on_dumpBlockState_triggered(); void on_dumpBlockState_triggered();
@ -225,7 +225,7 @@ private:
Address getCurrencies() const; Address getCurrencies() const;
void updateFee(); void updateFee();
void readSettings(bool _skipGeometry = false); void readSettings(bool _skipGeometry = false, bool _onlyGeometry = false);
void writeSettings(); void writeSettings();
void setPrivateChain(QString const& _private, bool _forceConfigure = false); void setPrivateChain(QString const& _private, bool _forceConfigure = false);

15
alethzero/Transact.cpp

@ -136,11 +136,12 @@ void Transact::updateDestination()
// TODO: should be a Qt model. // TODO: should be a Qt model.
ui->destination->clear(); ui->destination->clear();
ui->destination->addItem("(Create Contract)"); ui->destination->addItem("(Create Contract)");
QMultiMap<QString, QString> in;
for (Address const& a: m_main->allKnownAddresses()) for (Address const& a: m_main->allKnownAddresses())
{ in.insert(QString::fromStdString(m_main->toName(a) + " (" + ICAP(a).encoded() + ")"), QString::fromStdString(a.hex()));
cdebug << "Adding" << a << m_main->toName(a) << " -> " << (m_main->toName(a) + " (" + ICAP(a).encoded() + ")"); for (auto i = in.begin(); i != in.end(); ++i)
ui->destination->addItem(QString::fromStdString(m_main->toName(a) + " (" + ICAP(a).encoded() + ")"), QString::fromStdString(a.hex())); ui->destination->addItem(i.key(), i.value());
}
} }
void Transact::updateFee() void Transact::updateFee()
@ -361,9 +362,8 @@ void Transact::timerEvent(QTimerEvent*)
} }
updateBounds(); updateBounds();
if (m_lowerBound == m_upperBound)
finaliseBounds();
} }
finaliseBounds();
} }
void Transact::updateBounds() void Transact::updateBounds()
@ -380,6 +380,8 @@ void Transact::updateBounds()
void Transact::finaliseBounds() void Transact::finaliseBounds()
{ {
killTimer(m_gasCalcTimer);
quint64 baseGas = (quint64)Transaction::gasRequired(m_data, 0); quint64 baseGas = (quint64)Transaction::gasRequired(m_data, 0);
ui->progressGas->setVisible(false); ui->progressGas->setVisible(false);
@ -420,7 +422,6 @@ void Transact::finaliseBounds()
updateFee(); updateFee();
ui->code->setHtml(htmlInfo + m_dataInfo); ui->code->setHtml(htmlInfo + m_dataInfo);
ui->send->setEnabled(true); ui->send->setEnabled(true);
killTimer(m_gasCalcTimer);
} }
GasRequirements Transact::determineGasRequirements() GasRequirements Transact::determineGasRequirements()

26
alethzero/plugins/blockchain/AllAccounts.cpp

@ -14,12 +14,12 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file AllAccounts.h /** @file AllAccounts.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2015 * @date 2015
*/ */
#if ETH_FATDB #if ETH_FATDB || !ETH_TRUE
#include "AllAccounts.h" #include "AllAccounts.h"
#include <sstream> #include <sstream>
@ -51,7 +51,7 @@ AllAccounts::AllAccounts(MainFace* _m):
connect(m_ui->accountsFilter, SIGNAL(textChanged(QString)), SLOT(onAllChange())); connect(m_ui->accountsFilter, SIGNAL(textChanged(QString)), SLOT(onAllChange()));
connect(m_ui->showBasic, SIGNAL(toggled(bool)), SLOT(onAllChange())); connect(m_ui->showBasic, SIGNAL(toggled(bool)), SLOT(onAllChange()));
connect(m_ui->showContracts, SIGNAL(toggled(bool)), SLOT(onAllChange())); connect(m_ui->showContracts, SIGNAL(toggled(bool)), SLOT(onAllChange()));
connect(m_ui->onlyNamed, SIGNAL(toggled(bool)), SLOT(onAllChange())); connect(m_ui->onlyKnown, SIGNAL(toggled(bool)), SLOT(onAllChange()));
} }
AllAccounts::~AllAccounts() AllAccounts::~AllAccounts()
@ -72,20 +72,24 @@ void AllAccounts::refresh()
m_ui->accounts->clear(); m_ui->accounts->clear();
bool showContract = m_ui->showContracts->isChecked(); bool showContract = m_ui->showContracts->isChecked();
bool showBasic = m_ui->showBasic->isChecked(); bool showBasic = m_ui->showBasic->isChecked();
bool onlyNamed = m_ui->onlyNamed->isChecked(); bool onlyKnown = m_ui->onlyKnown->isChecked();
auto as = ethereum()->addresses();
sort(as.begin(), as.end()); Addresses as;
if (onlyKnown)
as = main()->allKnownAddresses();
else
as = ethereum()->addresses();
for (auto const& i: as) for (auto const& i: as)
{ {
bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3); bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3);
if (!((showContract && isContract) || (showBasic && !isContract))) if (!((showContract && isContract) || (showBasic && !isContract)))
continue; continue;
string r = static_cast<Context*>(main())->render(i); string r = static_cast<Context*>(main())->render(i);
if (onlyNamed && !(r.find('"') != string::npos || r.substr(0, 2) == "XE"))
continue;
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), m_ui->accounts)) (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), m_ui->accounts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
} }
m_ui->accounts->sortItems();
#endif #endif
m_ui->refreshAccounts->setEnabled(false); m_ui->refreshAccounts->setEnabled(false);
} }
@ -108,8 +112,10 @@ void AllAccounts::on_accounts_currentItemChanged()
try try
{ {
auto storage = ethereum()->storageAt(address); auto storage = ethereum()->storageAt(address);
for (auto const& i: storage) u256s keys = keysOf(storage);
s << "@" << showbase << hex << main()->prettyU256(i.first) << "&nbsp;&nbsp;&nbsp;&nbsp;" << showbase << hex << main()->prettyU256(i.second) << "<br/>"; sort(keys.begin(), keys.end());
for (auto const& i: keys)
s << "@" << showbase << hex << main()->prettyU256(i) << "&nbsp;&nbsp;&nbsp;&nbsp;" << showbase << hex << main()->prettyU256(storage[i]) << "<br/>";
s << "<h4>Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")</h4>" << disassemble(ethereum()->codeAt(address)); s << "<h4>Body Code (" << sha3(ethereum()->codeAt(address)).abridged() << ")</h4>" << disassemble(ethereum()->codeAt(address));
s << ETH_HTML_DIV(ETH_HTML_MONO) << toHex(ethereum()->codeAt(address)) << "</div>"; s << ETH_HTML_DIV(ETH_HTML_MONO) << toHex(ethereum()->codeAt(address)) << "</div>";
s << "<h4>Creation Addresses (" << ethereum()->countAt(address) << "+)</h4>"; s << "<h4>Creation Addresses (" << ethereum()->countAt(address) << "+)</h4>";

2
alethzero/plugins/blockchain/AllAccounts.h

@ -21,7 +21,7 @@
#pragma once #pragma once
#if ETH_FATDB #if ETH_FATDB || !ETH_TRUE
#include <QListWidget> #include <QListWidget>
#include <QPlainTextEdit> #include <QPlainTextEdit>

11
alethzero/plugins/blockchain/AllAccounts.ui

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>400</width> <width>405</width>
<height>300</height> <height>300</height>
</rect> </rect>
</property> </property>
@ -46,6 +46,9 @@
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="checked">
<bool>true</bool>
</property>
</widget> </widget>
</item> </item>
<item> <item>
@ -62,15 +65,15 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QToolButton" name="onlyNamed"> <widget class="QToolButton" name="onlyKnown">
<property name="text"> <property name="text">
<string>Only Named</string> <string>Only Known</string>
</property> </property>
<property name="checkable"> <property name="checkable">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="checked"> <property name="checked">
<bool>false</bool> <bool>true</bool>
</property> </property>
</widget> </widget>
</item> </item>

91
alethzero/ExportState.cpp → alethzero/plugins/blockchain/ExportState.cpp

@ -19,77 +19,86 @@
* @date 2015 * @date 2015
*/ */
#if ETH_FATDB
#include "ExportState.h" #include "ExportState.h"
#include <fstream>
#include <QFileDialog> #include <QFileDialog>
#include <QTextStream> #include <QTextStream>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include "MainWin.h"
#include "ui_ExportState.h" #include "ui_ExportState.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace az; using namespace az;
using namespace eth; using namespace eth;
ExportStateDialog::ExportStateDialog(Main* _parent): DEV_AZ_NOTE_PLUGIN(ExportStateDialog);
QDialog(_parent),
ui(new Ui::ExportState), ExportStateDialog::ExportStateDialog(MainFace* _m):
m_main(_parent) QDialog(_m),
Plugin(_m, "Export State"),
m_ui(new Ui::ExportState)
{ {
ui->setupUi(this); m_ui->setupUi(this);
connect(ui->close, &QPushButton::clicked, this, &ExportStateDialog::close); connect(m_ui->close, &QPushButton::clicked, this, &ExportStateDialog::close);
connect(ui->accounts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON); connect(m_ui->accounts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON);
connect(ui->contracts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON); connect(m_ui->contracts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON);
fillBlocks(); fillBlocks();
connect(addMenuItem("Export State...", "menuTools", true), SIGNAL(triggered()), SLOT(exec()));
} }
ExportStateDialog::~ExportStateDialog() ExportStateDialog::~ExportStateDialog()
{ {
}
Client* ExportStateDialog::ethereum() const }
void ExportStateDialog::showEvent(QShowEvent*)
{ {
return m_main->ethereum(); m_ui->block->clear();
m_ui->block->clearEditText();
m_ui->accounts->clear();
m_ui->contracts->clear();
fillBlocks();
} }
void ExportStateDialog::on_block_editTextChanged() void ExportStateDialog::on_block_editTextChanged()
{ {
QString text = ui->block->currentText(); QString text = m_ui->block->currentText();
int i = ui->block->count(); int i = m_ui->block->count();
while (i-- >= 0) while (i-- >= 0)
if (ui->block->itemText(i) == text) if (m_ui->block->itemText(i) == text)
return; return;
fillBlocks(); fillBlocks();
} }
void ExportStateDialog::on_block_currentIndexChanged(int _index) void ExportStateDialog::on_block_currentIndexChanged(int _index)
{ {
m_block = ui->block->itemData(_index).toUInt(); m_block = m_ui->block->itemData(_index).toUInt();
fillContracts(); fillContracts();
} }
void ExportStateDialog::fillBlocks() void ExportStateDialog::fillBlocks()
{ {
BlockChain const& bc = ethereum()->blockChain(); BlockChain const& bc = ethereum()->blockChain();
QStringList filters = ui->block->currentText().toLower().split(QRegExp("\\s+"), QString::SkipEmptyParts); QStringList filters = m_ui->block->currentText().toLower().split(QRegExp("\\s+"), QString::SkipEmptyParts);
const unsigned numLastBlocks = 10; const unsigned numLastBlocks = 10;
if (ui->block->count() == 0) if (m_ui->block->count() == 0)
{ {
unsigned i = numLastBlocks; unsigned i = numLastBlocks;
for (auto h = bc.currentHash(); bc.details(h) && i; h = bc.details(h).parent, --i) for (auto h = bc.currentHash(); bc.details(h) && i; h = bc.details(h).parent, --i)
{ {
auto d = bc.details(h); auto d = bc.details(h);
ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number); m_ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number);
if (h == bc.genesisHash()) if (h == bc.genesisHash())
break; break;
} }
if (ui->block->currentIndex() < 0) if (m_ui->block->currentIndex() < 0)
ui->block->setCurrentIndex(0); m_ui->block->setCurrentIndex(0);
m_recentBlocks = numLastBlocks - i; m_recentBlocks = numLastBlocks - i;
} }
int i = ui->block->count(); int i = m_ui->block->count();
while (i > 0 && i >= m_recentBlocks) while (i > 0 && i >= m_recentBlocks)
ui->block->removeItem(i--); m_ui->block->removeItem(i--);
h256Hash blocks; h256Hash blocks;
for (QString f: filters) for (QString f: filters)
@ -117,31 +126,31 @@ void ExportStateDialog::fillBlocks()
for (auto const& h: blocks) for (auto const& h: blocks)
{ {
auto d = bc.details(h); auto d = bc.details(h);
ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number); m_ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number);
} }
} }
void ExportStateDialog::fillContracts() void ExportStateDialog::fillContracts()
{ {
ui->accounts->clear(); m_ui->accounts->clear();
ui->contracts->clear(); m_ui->contracts->clear();
ui->accounts->setEnabled(true); m_ui->accounts->setEnabled(true);
ui->contracts->setEnabled(true); m_ui->contracts->setEnabled(true);
try try
{ {
for (auto i: ethereum()->addresses(m_block)) for (auto i: ethereum()->addresses(m_block))
{ {
string r = m_main->render(i); string r = main()->render(i);
(new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts)) (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(QString::fromStdString(r)).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? m_ui->accounts : m_ui->contracts))
->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size));
} }
} }
catch (InterfaceNotSupported const&) catch (InterfaceNotSupported const&)
{ {
ui->accounts->setEnabled(false); m_ui->accounts->setEnabled(false);
ui->contracts->setEnabled(false); m_ui->contracts->setEnabled(false);
ui->json->setEnabled(false); m_ui->json->setEnabled(false);
ui->json->setText(QString("This feature requires compilation with FATDB support.")); m_ui->json->setText(QString("This feature requires compilation with FATDB support."));
} }
} }
@ -150,14 +159,14 @@ void ExportStateDialog::generateJSON()
std::stringstream json; std::stringstream json;
json << "{\n"; json << "{\n";
std::string prefix; std::string prefix;
for(QListWidgetItem* item: ui->accounts->selectedItems()) for(QListWidgetItem* item: m_ui->accounts->selectedItems())
{ {
auto hba = item->data(Qt::UserRole).toByteArray(); auto hba = item->data(Qt::UserRole).toByteArray();
auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer); auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer);
json << prefix << "\t\"" << toHex(address.ref()) << "\": { \"wei\": \"" << ethereum()->balanceAt(address, m_block) << "\" }"; json << prefix << "\t\"" << toHex(address.ref()) << "\": { \"wei\": \"" << ethereum()->balanceAt(address, m_block) << "\" }";
prefix = ",\n"; prefix = ",\n";
} }
for(QListWidgetItem* item: ui->contracts->selectedItems()) for(QListWidgetItem* item: m_ui->contracts->selectedItems())
{ {
auto hba = item->data(Qt::UserRole).toByteArray(); auto hba = item->data(Qt::UserRole).toByteArray();
auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer); auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer);
@ -181,9 +190,9 @@ void ExportStateDialog::generateJSON()
json << "\n}"; json << "\n}";
json.flush(); json.flush();
ui->json->setEnabled(true); m_ui->json->setEnabled(true);
ui->json->setText(QString::fromStdString(json.str())); m_ui->json->setText(QString::fromStdString(json.str()));
ui->saveButton->setEnabled(true); m_ui->saveButton->setEnabled(true);
} }
void ExportStateDialog::on_saveButton_clicked() void ExportStateDialog::on_saveButton_clicked()
@ -193,5 +202,7 @@ void ExportStateDialog::on_saveButton_clicked()
fn = fn.append(".json"); fn = fn.append(".json");
ofstream file(fn.toStdString()); ofstream file(fn.toStdString());
if (file.is_open()) if (file.is_open())
file << ui->json->toPlainText().toStdString(); file << m_ui->json->toPlainText().toStdString();
} }
#endif //ETH_FATDB

15
alethzero/ExportState.h → alethzero/plugins/blockchain/ExportState.h

@ -21,9 +21,12 @@
#pragma once #pragma once
#if ETH_FATDB
#include <memory> #include <memory>
#include <QDialog> #include <QDialog>
#include <libethcore/Common.h> #include <libethcore/Common.h>
#include "MainFace.h"
namespace Ui { class ExportState; } namespace Ui { class ExportState; }
@ -35,14 +38,13 @@ namespace eth { class Client; }
namespace az namespace az
{ {
class Main;
class ExportStateDialog: public QDialog class ExportStateDialog: public QDialog, public Plugin
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ExportStateDialog(Main* _parent = 0); ExportStateDialog(MainFace* _m);
virtual ~ExportStateDialog(); virtual ~ExportStateDialog();
private slots: private slots:
@ -51,17 +53,18 @@ private slots:
void on_saveButton_clicked(); void on_saveButton_clicked();
private: private:
eth::Client* ethereum() const; void showEvent(QShowEvent* _event) override;
void fillBlocks(); void fillBlocks();
void fillContracts(); void fillContracts();
void generateJSON(); void generateJSON();
private: private:
std::unique_ptr<Ui::ExportState> ui; std::unique_ptr<Ui::ExportState> m_ui;
Main* m_main;
int m_recentBlocks = 0; int m_recentBlocks = 0;
eth::BlockNumber m_block = eth::LatestBlock; eth::BlockNumber m_block = eth::LatestBlock;
}; };
} }
} }
#endif //ETH_FATDB

0
alethzero/ExportState.ui → alethzero/plugins/blockchain/ExportState.ui

222
alethzero/plugins/keys/ImportKey.cpp

@ -0,0 +1,222 @@
/*
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 ImportKey.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#include "ImportKey.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QInputDialog>
#include <libdevcore/Log.h>
#include <libethcore/KeyManager.h>
#include <libethcore/ICAP.h>
#include <libethereum/Client.h>
#include "ui_ImportKey.h"
using namespace std;
using namespace dev;
using namespace az;
using namespace eth;
DEV_AZ_NOTE_PLUGIN(ImportKey);
ImportKey::ImportKey(MainFace* _m):
Plugin(_m, "ImportKey")
{
connect(addMenuItem("Import Key...", "menuTools", true), SIGNAL(triggered()), SLOT(import()));
}
ImportKey::~ImportKey()
{
}
void ImportKey::import()
{
QDialog d;
Ui_ImportKey u;
u.setupUi(&d);
d.setWindowTitle("Import Key");
string lastKey;
Secret lastSecret;
string lastPassword;
Address lastAddress;
auto updateAction = [&](){
if (!u.import_2->isEnabled())
u.action->clear();
else if (lastKey.empty() && !lastSecret)
u.action->setText("Import brainwallet with given address and hint");
else if (!lastKey.empty() && !lastSecret)
{
h256 ph;
DEV_IGNORE_EXCEPTIONS(ph = h256(u.passwordHash->text().toStdString()));
if (ph)
u.action->setText("Import untouched key with given address and hint");
else
u.action->setText("Import untouched key with given address, password hash and hint");
}
else
{
bool mp = u.noPassword->isChecked();
if (mp)
u.action->setText("Import recast key using master password and given hint");
else
u.action->setText("Import recast key with given password and hint");
}
};
auto updateImport = [&](){
u.import_2->setDisabled(u.addressOut->text().isEmpty() || u.name->text().isEmpty() || !(u.oldPassword->isChecked() || u.newPassword->isChecked() || u.noPassword->isChecked()));
updateAction();
};
auto updateAddress = [&](){
lastAddress.clear();
string as = u.address->text().toStdString();
try
{
lastAddress = eth::toAddress(as);
u.addressOut->setText(QString::fromStdString(main()->render(lastAddress)));
}
catch (...)
{
u.addressOut->setText("");
}
updateImport();
};
auto updatePassword = [&](){
u.passwordHash->setText(QString::fromStdString(sha3(u.password->text().toStdString()).hex()));
updateAction();
};
function<void()> updateKey = [&](){
// update according to key.
if (lastKey == u.key->text().toStdString())
return;
lastKey = u.key->text().toStdString();
lastSecret.clear();
u.address->clear();
u.oldPassword->setEnabled(false);
u.oldPassword->setChecked(false);
bytes b;
DEV_IGNORE_EXCEPTIONS(b = fromHex(lastKey, WhenError::Throw));
if (b.size() == 32)
{
lastSecret = Secret(b);
bytesRef(&b).cleanse();
}
while (!lastKey.empty() && !lastSecret)
{
bool ok;
lastPassword = QInputDialog::getText(&d, "Open Key File", "Enter the password protecting this key file. Cancel if you do not want to provide te password.", QLineEdit::Password, QString(), &ok).toStdString();
if (!ok)
{
lastSecret.clear();
break;
}
// Try to open as a file.
lastSecret = KeyManager::presaleSecret(contentsString(lastKey), [&](bool first){ return first ? lastPassword : string(); }).secret();
if (!lastSecret)
lastSecret = Secret(SecretStore::secret(contentsString(lastKey), lastPassword));
if (!lastSecret && QMessageBox::warning(&d, "Invalid Password or Key File", "The given password could not be used to decrypt the key file given. Are you sure it is a valid key file and that the password is correct?", QMessageBox::Abort, QMessageBox::Retry) == QMessageBox::Abort)
{
u.key->clear();
updateKey();
return;
}
}
u.oldPassword->setEnabled(!!lastSecret);
u.newPassword->setEnabled(!!lastSecret);
u.noPassword->setEnabled(!!lastSecret);
u.masterLabel->setEnabled(!!lastSecret);
u.oldLabel->setEnabled(!!lastSecret);
u.showPassword->setEnabled(!!lastSecret);
u.password->setEnabled(!!lastSecret);
u.passwordHash->setReadOnly(!!lastSecret);
u.address->setReadOnly(!!lastSecret);
if (lastSecret)
{
u.oldPassword->setEnabled(!lastPassword.empty());
if (lastPassword.empty())
u.oldPassword->setChecked(false);
u.address->setText(QString::fromStdString(ICAP(toAddress(lastSecret)).encoded()));
updateAddress();
}
else
u.address->clear();
updateImport();
};
connect(u.noPassword, &QRadioButton::clicked, [&](){
u.passwordHash->clear();
u.hint->setText("No additional password (same as master password).");
updateAction();
});
connect(u.oldPassword, &QRadioButton::clicked, [&](){
u.passwordHash->setText(QString::fromStdString(sha3(lastPassword).hex()));
u.hint->setText("Same as original password for file " + QString::fromStdString(lastKey));
updateAction();
});
connect(u.newPassword, &QRadioButton::clicked, [&](){
u.hint->setText("");
updatePassword();
});
connect(u.password, &QLineEdit::textChanged, [&](){ updatePassword(); });
connect(u.address, &QLineEdit::textChanged, [&](){ updateAddress(); });
connect(u.key, &QLineEdit::textEdited, [&](){ updateKey(); });
connect(u.name, &QLineEdit::textEdited, [&](){ updateImport(); });
connect(u.showPassword, &QCheckBox::toggled, [&](bool show){ u.password->setEchoMode(show ? QLineEdit::Normal : QLineEdit::Password); });
connect(u.openKey, &QToolButton::clicked, [&](){
QString fn = QFileDialog::getOpenFileName(main(), "Open Key File", QDir::homePath(), "JSON Files (*.json);;All Files (*)");
if (!fn.isEmpty())
{
u.key->setText(fn);
updateKey();
}
});
if (d.exec() == QDialog::Accepted)
{
Address a = lastAddress;
string n = u.name->text().toStdString();
string h = u.hint->text().toStdString();
// check for a brain wallet import
if (lastKey.empty() && !lastSecret)
main()->keyManager().importExistingBrain(a, n, h);
else if (!lastKey.empty() && !lastSecret)
{
h256 ph;
DEV_IGNORE_EXCEPTIONS(ph = h256(u.passwordHash->text().toStdString()));
main()->keyManager().importExisting(main()->keyManager().store().importKey(lastKey), n, a, ph, h);
}
else
{
bool mp = u.noPassword->isChecked();
string p = mp ? string() : u.oldPassword ? lastPassword : u.password->text().toStdString();
if (mp)
main()->keyManager().import(lastSecret, n);
else
main()->keyManager().import(lastSecret, n, p, h);
}
main()->noteKeysChanged();
}
}

44
alethzero/plugins/keys/ImportKey.h

@ -0,0 +1,44 @@
/*
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 ImportKey.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#pragma once
#include "MainFace.h"
namespace dev
{
namespace az
{
class ImportKey: public QObject, public Plugin
{
Q_OBJECT
public:
ImportKey(MainFace* _m);
~ImportKey();
private slots:
void import();
};
}
}

336
alethzero/plugins/keys/ImportKey.ui

@ -0,0 +1,336 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImportKey</class>
<widget class="QDialog" name="ImportKey">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>530</width>
<height>389</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="10" column="2" colspan="3">
<widget class="QLineEdit" name="passwordHash">
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
<item row="8" column="3" colspan="2">
<widget class="QCheckBox" name="showPassword">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Show</string>
</property>
</widget>
</item>
<item row="4" column="0" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>&amp;Address:</string>
</property>
<property name="buddy">
<cstring>address</cstring>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QToolButton" name="openKey">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item row="8" column="0" colspan="2">
<widget class="QRadioButton" name="newPassword">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>New &amp;Password:</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item row="4" column="2" colspan="3">
<widget class="QLineEdit" name="address">
<property name="placeholderText">
<string>Place the address of the key here</string>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="label_4">
<property name="text">
<string>&amp;Name:</string>
</property>
<property name="buddy">
<cstring>name</cstring>
</property>
</widget>
</item>
<item row="6" column="0" colspan="2">
<widget class="QRadioButton" name="noPassword">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Master password</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item row="11" column="2" colspan="3">
<widget class="QLineEdit" name="hint"/>
</item>
<item row="7" column="0" colspan="2">
<widget class="QRadioButton" name="oldPassword">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Old password</string>
</property>
<attribute name="buttonGroup">
<string notr="true">buttonGroup</string>
</attribute>
</widget>
</item>
<item row="8" column="2">
<widget class="QLineEdit" name="password">
<property name="placeholderText">
<string>Enter the password you wish to use for the key here</string>
</property>
</widget>
</item>
<item row="2" column="2" colspan="3">
<widget class="QLineEdit" name="name">
<property name="placeholderText">
<string>Enter this key's name here</string>
</property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Password &amp;Hash:</string>
</property>
<property name="buddy">
<cstring>passwordHash</cstring>
</property>
</widget>
</item>
<item row="11" column="0" colspan="2">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Password Hin&amp;t:</string>
</property>
<property name="buddy">
<cstring>hint</cstring>
</property>
</widget>
</item>
<item row="6" column="2" colspan="3">
<widget class="QLabel" name="masterLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Use same password for the key as for the master.</string>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
</widget>
</item>
<item row="3" column="2" colspan="2">
<widget class="QLineEdit" name="key">
<property name="placeholderText">
<string>Brain wallet (no key file)</string>
</property>
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="QLabel" name="label">
<property name="text">
<string>&amp;Key:</string>
</property>
<property name="buddy">
<cstring>key</cstring>
</property>
</widget>
</item>
<item row="7" column="2" colspan="3">
<widget class="QLabel" name="oldLabel">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Use the same password as in the key file.</string>
</property>
</widget>
</item>
<item row="5" column="2" colspan="3">
<widget class="QLineEdit" name="addressOut">
<property name="readOnly">
<bool>true</bool>
</property>
<property name="placeholderText">
<string>Unknown Address</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="action">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancel">
<property name="text">
<string>Cancel</string>
</property>
<property name="shortcut">
<string>Esc</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="import_2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>&amp;Import</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<tabstops>
<tabstop>name</tabstop>
<tabstop>key</tabstop>
<tabstop>openKey</tabstop>
<tabstop>address</tabstop>
<tabstop>addressOut</tabstop>
<tabstop>noPassword</tabstop>
<tabstop>oldPassword</tabstop>
<tabstop>newPassword</tabstop>
<tabstop>password</tabstop>
<tabstop>showPassword</tabstop>
<tabstop>passwordHash</tabstop>
<tabstop>hint</tabstop>
<tabstop>cancel</tabstop>
<tabstop>import_2</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>import_2</sender>
<signal>clicked()</signal>
<receiver>ImportKey</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>519</x>
<y>378</y>
</hint>
<hint type="destinationlabel">
<x>449</x>
<y>388</y>
</hint>
</hints>
</connection>
<connection>
<sender>cancel</sender>
<signal>clicked()</signal>
<receiver>ImportKey</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>433</x>
<y>378</y>
</hint>
<hint type="destinationlabel">
<x>351</x>
<y>388</y>
</hint>
</hints>
</connection>
<connection>
<sender>newPassword</sender>
<signal>pressed()</signal>
<receiver>password</receiver>
<slot>setFocus()</slot>
<hints>
<hint type="sourcelabel">
<x>80</x>
<y>211</y>
</hint>
<hint type="destinationlabel">
<x>185</x>
<y>215</y>
</hint>
</hints>
</connection>
</connections>
<buttongroups>
<buttongroup name="buttonGroup"/>
</buttongroups>
</ui>

19
alethzero/plugins/namers/OtherAccounts.cpp

@ -21,6 +21,7 @@
#include "OtherAccounts.h" #include "OtherAccounts.h"
#include <QSettings> #include <QSettings>
#include <QMessageBox>
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <ui_OtherAccounts.h> #include <ui_OtherAccounts.h>
@ -46,12 +47,22 @@ void OtherAccounts::import()
if (d.exec() == QDialog::Accepted) if (d.exec() == QDialog::Accepted)
{ {
QStringList sl = u.accounts->toPlainText().split("\n"); QStringList sl = u.accounts->toPlainText().split("\n");
unsigned line = 1;
for (QString const& s: sl) for (QString const& s: sl)
{ {
Address addr = dev::eth::toAddress(s.section(QRegExp("[ \\0\\t]+"), 0, 0).toStdString()); try
string name = s.section(QRegExp("[ \\0\\t]+"), 1).toStdString(); {
m_toName[addr] = name; Address addr = dev::eth::toAddress(s.section(QRegExp("[ \\0\\t]+"), 0, 0).trimmed().toStdString());
m_toAddress[name] = addr; string name = s.section(QRegExp("[ \\0\\t]+"), 1).trimmed().toStdString();
m_toName[addr] = name;
m_toAddress[name] = addr;
}
catch (...)
{
if (QMessageBox::warning(&d, "Invalid Line Format", "Line format or address given on line " + QString::number(line) + " is invalid:\n" + s, QMessageBox::Abort, QMessageBox::Ignore) == QMessageBox::Abort)
break;
}
line++;
} }
main()->noteSettingsChanged(); main()->noteSettingsChanged();
noteKnownChanged(); noteKnownChanged();

87
alethzero/plugins/special/InjectTransactions.cpp

@ -0,0 +1,87 @@
/*
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 InjectTransactions.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#include "InjectTransactions.h"
#include <QMessageBox>
#include <QInputDialog>
#include <libdevcore/Log.h>
#include <libethereum/Client.h>
#include "ui_InjectTransactions.h"
using namespace std;
using namespace dev;
using namespace az;
using namespace eth;
DEV_AZ_NOTE_PLUGIN(InjectTransactions);
InjectTransactions::InjectTransactions(MainFace* _m):
Plugin(_m, "InjectTransactions")
{
connect(addMenuItem("Inject Transaction...", "menuSpecial", true), SIGNAL(triggered()), SLOT(injectOne()));
connect(addMenuItem("Bulk Inject Transactions...", "menuSpecial", false), SIGNAL(triggered()), SLOT(injectBulk()));
}
InjectTransactions::~InjectTransactions()
{
}
void InjectTransactions::injectOne()
{
bool ok;
QString s = QInputDialog::getText(main(), "Inject Transaction", "Enter transaction dump in hex", QLineEdit::Normal, QString(), &ok);
if (ok)
doInject(s);
}
void InjectTransactions::injectBulk()
{
QDialog d;
Ui_InjectTransactions u;
u.setupUi(&d);
d.setWindowTitle("Bulk Inject Transactions");
if (d.exec() == QDialog::Accepted)
for (QString const& s: u.transactions->toPlainText().split("\n"))
doInject(s);
}
void InjectTransactions::doInject(QString _txHex)
{
try
{
bytes b = fromHex(_txHex.toStdString(), WhenError::Throw);
main()->ethereum()->injectTransaction(b);
}
catch (BadHexCharacter& _e)
{
if (QMessageBox::warning(main(), "Invalid Transaction Hex", "Invalid hex character in:\n" + _txHex + "\nTransaction rejected.", QMessageBox::Ignore, QMessageBox::Abort) == QMessageBox::Abort)
return;
}
catch (Exception& _e)
{
if (QMessageBox::warning(main(), "Transaction Rejected", "Invalid transaction; due to" + QString::fromStdString(_e.what()) + "\n" + _txHex + "\nTransaction rejected.", QMessageBox::Ignore, QMessageBox::Abort) == QMessageBox::Abort)
return;
}
catch (...)
{
// Should not happen under normal circumstances.
return;
}
}

48
alethzero/plugins/special/InjectTransactions.h

@ -0,0 +1,48 @@
/*
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 InjectTransactions.h
* @author Gav Wood <i@gavwood.com>
* @date 2015
*/
#pragma once
#include "MainFace.h"
namespace dev
{
namespace az
{
class InjectTransactions: public QObject, public Plugin
{
Q_OBJECT
public:
InjectTransactions(MainFace* _m);
~InjectTransactions();
private slots:
void injectOne();
void injectBulk();
private:
void doInject(QString _txHex);
};
}
}

95
alethzero/plugins/special/InjectTransactions.ui

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>InjectTransactions</class>
<widget class="QDialog" name="InjectTransactions">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>511</width>
<height>508</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTextEdit" name="transactions">
<property name="placeholderText">
<string>Write the transactions you wish to inject here, in hex, one per line.</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="cancel">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="inject">
<property name="text">
<string>&amp;Import</string>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>inject</sender>
<signal>clicked()</signal>
<receiver>InjectTransactions</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>462</x>
<y>484</y>
</hint>
<hint type="destinationlabel">
<x>449</x>
<y>504</y>
</hint>
</hints>
</connection>
<connection>
<sender>cancel</sender>
<signal>clicked()</signal>
<receiver>InjectTransactions</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>381</x>
<y>483</y>
</hint>
<hint type="destinationlabel">
<x>351</x>
<y>506</y>
</hint>
</hints>
</connection>
</connections>
</ui>

72
eth/main.cpp

@ -14,8 +14,10 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file main.cpp /**
* @file main.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @author Tasha Carl <tasha@carl.pro> - I here by place all my contributions in this file under MIT licence, as specified by http://opensource.org/licenses/MIT.
* @date 2014 * @date 2014
* Ethereum client. * Ethereum client.
*/ */
@ -83,20 +85,20 @@ void help()
<< " --olympic Use the Olympic (0.9) protocol." << endl << " --olympic Use the Olympic (0.9) protocol." << endl
<< " --frontier Use the Frontier (1.0) protocol." << endl << " --frontier Use the Frontier (1.0) protocol." << endl
<< " --private <name> Use a private chain." << endl << " --private <name> Use a private chain." << endl
<< " --genesis-json <file> Import the genesis block information from the given json file." << endl << " --genesis-json <file> Import the genesis block information from the given JSON file." << endl
<< endl << endl
<< " -o,--mode <full/peer> Start a full node or a peer node (default: full)." << endl << " -o,--mode <full/peer> Start a full node or a peer node (default: full)." << endl
<< endl << endl
#if ETH_JSONRPC || !ETH_TRUE #if ETH_JSONRPC || !ETH_TRUE
<< " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl << " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl
<< " --json-rpc-port <n> Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl << " --json-rpc-port <n> Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl
<< " --admin <password> Specify admin session key for JSON-RPC (default: auto-generated and printed at startup)." << endl << " --admin <password> Specify admin session key for JSON-RPC (default: auto-generated and printed at start-up)." << endl
#endif #endif
<< " -K,--kill First kill the blockchain." << endl << " -K,--kill Kill the blockchain first." << endl
<< " -R,--rebuild Rebuild the blockchain from the existing database." << endl << " -R,--rebuild Rebuild the blockchain from the existing database." << endl
<< " --rescue Attempt to rescue a corrupt database." << endl << " --rescue Attempt to rescue a corrupt database." << endl
<< endl << endl
<< " --import-presale <file> Import a presale key; you'll need to type the password to this." << endl << " --import-presale <file> Import a pre-sale key; you'll need to specify the password to this key." << endl
<< " -s,--import-secret <secret> Import a secret key into the key store and use as the default." << endl << " -s,--import-secret <secret> Import a secret key into the key store and use as the default." << endl
<< " -S,--import-session-secret <secret> Import a secret key into the key store and use as the default for this session only." << endl << " -S,--import-session-secret <secret> Import a secret key into the key store and use as the default for this session only." << endl
<< " --sign-key <address> Sign all transactions with the key of the given address." << endl << " --sign-key <address> Sign all transactions with the key of the given address." << endl
@ -106,54 +108,54 @@ void help()
<< " --sentinel <server> Set the sentinel for reporting bad blocks or chain issues." << endl << " --sentinel <server> Set the sentinel for reporting bad blocks or chain issues." << endl
<< endl << endl
<< "Client transacting:" << endl << "Client transacting:" << endl
/*<< " -B,--block-fees <n> Set the block fee profit in the reference unit e.g. ¢ (default: 15)." << endl /*<< " -B,--block-fees <n> Set the block fee profit in the reference unit, e.g. ¢ (default: 15)." << endl
<< " -e,--ether-price <n> Set the ether price in the reference unit e.g. ¢ (default: 30.679)." << endl << " -e,--ether-price <n> Set the ether price in the reference unit, e.g. ¢ (default: 30.679)." << endl
<< " -P,--priority <0 - 100> Default % priority of a transaction (default: 50)." << endl*/ << " -P,--priority <0 - 100> Set the default priority percentage (%) of a transaction (default: 50)." << endl*/
<< " --ask <wei> Set the minimum ask gas price under which no transactions will be mined (default " << toString(DefaultGasPrice) << " )." << endl << " --ask <wei> Set the minimum ask gas price under which no transaction will be mined (default " << toString(DefaultGasPrice) << " )." << endl
<< " --bid <wei> Set the bid gas price for to pay for transactions (default " << toString(DefaultGasPrice) << " )." << endl << " --bid <wei> Set the bid gas price to pay for transactions (default " << toString(DefaultGasPrice) << " )." << endl
<< endl << endl
<< "Client mining:" << endl << "Client mining:" << endl
<< " -a,--address <addr> Set the coinbase (mining payout) address to addr (default: auto)." << endl << " -a,--address <addr> Set the coinbase (mining payout) address to given address (default: auto)." << endl
<< " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (default: off)" << endl << " -m,--mining <on/off/number> Enable mining, optionally for a specified number of blocks (default: off)." << endl
<< " -f,--force-mining Mine even when there are no transactions to mine (default: off)" << endl << " -f,--force-mining Mine even when there are no transactions to mine (default: off)." << endl
<< " --mine-on-wrong-chain Mine even when we know it's the wrong chain (default: off)" << endl << " --mine-on-wrong-chain Mine even when we know that it is the wrong chain (default: off)." << endl
<< " -C,--cpu When mining, use the CPU." << endl << " -C,--cpu When mining, use the CPU." << endl
<< " -G,--opencl When mining use the GPU via OpenCL." << endl << " -G,--opencl When mining, use the GPU via OpenCL." << endl
<< " --opencl-platform <n> When mining using -G/--opencl use OpenCL platform n (default: 0)." << endl << " --opencl-platform <n> When mining using -G/--opencl, use OpenCL platform n (default: 0)." << endl
<< " --opencl-device <n> When mining using -G/--opencl use OpenCL device n (default: 0)." << endl << " --opencl-device <n> When mining using -G/--opencl, use OpenCL device n (default: 0)." << endl
<< " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)" << endl << " -t, --mining-threads <n> Limit number of CPU/GPU miners to n (default: use everything available on selected platform)." << endl
<< endl << endl
<< "Client networking:" << endl << "Client networking:" << endl
<< " --client-name <name> Add a name to your client's version string (default: blank)." << endl << " --client-name <name> Add a name to your client's version string (default: blank)." << endl
<< " --bootstrap Connect to the default Ethereum peerservers (default unless --no-discovery used)." << endl << " --bootstrap Connect to the default Ethereum peer servers (default unless --no-discovery used)." << endl
<< " --no-bootstrap Do not connect to the default Ethereum peerservers (default only when --no-discovery is used)." << endl << " --no-bootstrap Do not connect to the default Ethereum peer servers (default only when --no-discovery is used)." << endl
<< " -x,--peers <number> Attempt to connect to given number of peers (default: 11)." << endl << " -x,--peers <number> Attempt to connect to a given number of peers (default: 11)." << endl
<< " --peer-stretch <number> Accepted connection multiplier (default: 7)." << endl << " --peer-stretch <number> Give the accepted connection multiplier (default: 7)." << endl
<< " --public-ip <ip> Force advertised public ip to given (default: auto)." << endl << " --public-ip <ip> Force advertised public IP to the given IP (default: auto)." << endl
<< " --listen-ip <ip>(:<port>) Listen on the given IP for incoming connections (default: 0.0.0.0)." << endl << " --listen-ip <ip>(:<port>) Listen on the given IP for incoming connections (default: 0.0.0.0)." << endl
<< " --listen <port> Listen on the given port for incoming connections (default: 30303)." << endl << " --listen <port> Listen on the given port for incoming connections (default: 30303)." << endl
<< " -r,--remote <host>(:<port>) Connect to remote host (default: none)." << endl << " -r,--remote <host>(:<port>) Connect to the given remote host (default: none)." << endl
<< " --port <port> Connect to remote port (default: 30303)." << endl << " --port <port> Connect to the given remote port (default: 30303)." << endl
<< " --network-id <n> Only connect to other hosts with this network id." << endl << " --network-id <n> Only connect to other hosts with this network id." << endl
<< " --upnp <on/off> Use UPnP for NAT (default: on)." << endl << " --upnp <on/off> Use UPnP for NAT (default: on)." << endl
<< " --peerset <list> Space delimited list of type type:publickey@ipAddress[:port]" << endl << " --peerset <list> Space delimited list of peers; element format: type:publickey@ipAddress[:port]." << endl
<< " Types:" << endl << " Types:" << endl
<< " default Attempt connection when no other peers are available and pinning is disable." << endl << " default Attempt connection when no other peers are available and pinning is disabled." << endl
<< " require Keep connected at all times." << endl << " require Keep connected at all times." << endl
// TODO: // TODO:
// << " --trust-peers <filename> Space delimited list of publickeys." << endl // << " --trust-peers <filename> Space delimited list of publickeys." << endl
<< " --no-discovery Disable Node discovery, implies --no-bootstrap." << endl << " --no-discovery Disable node discovery, implies --no-bootstrap." << endl
<< " --pin Only accept or connect to trusted peers." << endl << " --pin Only accept or connect to trusted peers." << endl
<< " --hermit Equivalent to --no-discovery --pin." << endl << " --hermit Equivalent to --no-discovery --pin." << endl
<< " --sociable Forces discovery and no pinning." << endl << " --sociable Force discovery and no pinning." << endl
<< endl; << endl;
MinerCLI::streamHelp(cout); MinerCLI::streamHelp(cout);
cout cout
<< "Client structured logging:" << endl << "Client structured logging:" << endl
<< " --structured-logging Enable structured logging (default output to stdout)." << endl << " --structured-logging Enable structured logging (default: output to stdout)." << endl
<< " --structured-logging-format <format> Set the structured logging time format." << endl << " --structured-logging-format <format> Set the structured logging time format." << endl
<< " --structured-logging-url <URL> Set the structured logging destination (currently only file:// supported)." << endl << " --structured-logging-url <URL> Set the structured logging destination (currently only file:// supported)." << endl
<< endl << endl
@ -161,19 +163,19 @@ void help()
<< " --from <n> Export only from block n; n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl << " --from <n> Export only from block n; n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl
<< " --to <n> Export only to block n (inclusive); n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl << " --to <n> Export only to block n (inclusive); n may be a decimal, a '0x' prefixed hash, or 'latest'." << endl
<< " --only <n> Equivalent to --export-from n --export-to n." << endl << " --only <n> Equivalent to --export-from n --export-to n." << endl
<< " --dont-check Avoids checking some of the aspects of blocks. Faster importing, but only do if you know the data is valid." << endl << " --dont-check Prevent checking some block aspects. Faster importing, but to apply only when the data is known to be valid." << endl
<< endl << endl
<< "General Options:" << endl << "General Options:" << endl
<< " -d,--db-path <path> Load database from path (default: " << getDataDir() << ")" << endl << " -d,--db-path <path> Load database from path (default: " << getDataDir() << ")." << endl
#if ETH_EVMJIT || !ETH_TRUE #if ETH_EVMJIT || !ETH_TRUE
<< " --vm <vm-kind> Select VM. Options are: interpreter, jit, smart. (default: interpreter)" << endl << " --vm <vm-kind> Select VM; options are: interpreter, jit or smart (default: interpreter)." << endl
#endif #endif
<< " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl << " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl
<< " -V,--version Show the version and exit." << endl << " -V,--version Show the version and exit." << endl
<< " -h,--help Show this help message and exit." << endl << " -h,--help Show this help message and exit." << endl
<< endl << endl
<< "Experimental / Proof of Concept:" << endl << "Experimental / Proof of Concept:" << endl
<< " --shh Enable Whisper" << endl << " --shh Enable Whisper." << endl
<< endl << endl
; ;
exit(0); exit(0);

553
ethkey/KeyAux.h

@ -33,6 +33,7 @@
#include <libethcore/KeyManager.h> #include <libethcore/KeyManager.h>
#include <libethcore/ICAP.h> #include <libethcore/ICAP.h>
#include <libethcore/Transaction.h> #include <libethcore/Transaction.h>
#include <libdevcrypto/WordList.h>
#include "BuildInfo.h" #include "BuildInfo.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -108,6 +109,9 @@ public:
Export, Export,
Recode, Recode,
Kill, Kill,
NewBrain,
ImportBrain,
InspectBrain,
SignTx, SignTx,
DecodeTx, DecodeTx,
}; };
@ -140,6 +144,67 @@ public:
m_mode = OperationMode::SignTx; m_mode = OperationMode::SignTx;
m_signKey = argv[++i]; m_signKey = argv[++i];
} }
else if (arg == "--tx-data" && i + 1 < argc)
try
{
m_toSign.data = fromHex(argv[++i]);
}
catch (...)
{
cerr << "Invalid argument to " << arg << endl;
exit(-1);
}
else if (arg == "--tx-nonce" && i + 1 < argc)
try
{
m_toSign.nonce = u256(argv[++i]);
}
catch (...)
{
cerr << "Invalid argument to " << arg << endl;
exit(-1);
}
else if ((arg == "--tx-dest" || arg == "--tx-to" || arg == "--tx-destination") && i + 1 < argc)
try
{
m_toSign.creation = false;
m_toSign.to = toAddress(argv[++i]);
}
catch (...)
{
cerr << "Invalid argument to " << arg << endl;
exit(-1);
}
else if (arg == "--tx-gas" && i + 1 < argc)
try
{
m_toSign.gas = u256(argv[++i]);
}
catch (...)
{
cerr << "Invalid argument to " << arg << endl;
exit(-1);
}
else if (arg == "--tx-gasprice" && i + 1 < argc)
try
{
m_toSign.gasPrice = u256(argv[++i]);
}
catch (...)
{
cerr << "Invalid argument to " << arg << endl;
exit(-1);
}
else if (arg == "--tx-value" && i + 1 < argc)
try
{
m_toSign.value = u256(argv[++i]);
}
catch (...)
{
cerr << "Invalid argument to " << arg << endl;
exit(-1);
}
else if (arg == "--decode-tx") else if (arg == "--decode-tx")
m_mode = OperationMode::DecodeTx; m_mode = OperationMode::DecodeTx;
else if (arg == "--import-bare") else if (arg == "--import-bare")
@ -175,6 +240,18 @@ public:
m_inputs = strings(1, argv[++i]); m_inputs = strings(1, argv[++i]);
m_name = argv[++i]; m_name = argv[++i];
} }
else if (arg == "--new-brain" && i + 1 < argc)
{
m_mode = OperationMode::NewBrain;
m_name = argv[++i];
}
else if (arg == "--import-brain" && i + 1 < argc)
{
m_mode = OperationMode::ImportBrain;
m_name = argv[++i];
}
else if (arg == "--inspect-brain")
m_mode = OperationMode::InspectBrain;
else if (arg == "--import-with-address" && i + 3 < argc) else if (arg == "--import-with-address" && i + 3 < argc)
{ {
m_mode = OperationMode::ImportWithAddress; m_mode = OperationMode::ImportWithAddress;
@ -203,9 +280,35 @@ public:
return k; return k;
} }
Secret getSecret(std::string const& _signKey)
{
string json = contentsString(_signKey);
if (!json.empty())
return Secret(secretStore().secret(secretStore().readKeyContent(json), [&](){ return getPassword("Enter password for key: "); }));
else
{
if (h128 u = fromUUID(_signKey))
return Secret(secretStore().secret(u, [&](){ return getPassword("Enter password for key: "); }));
if (_signKey.substr(0, 6) == "brain#" && _signKey.find(":") != string::npos)
return KeyManager::subkey(KeyManager::brain(_signKey.substr(_signKey.find(":"))), stoul(_signKey.substr(6, _signKey.find(":") - 7)));
if (_signKey.substr(0, 6) == "brain:")
return KeyManager::brain(_signKey.substr(6));
if (_signKey == "brain")
return KeyManager::brain(getPassword("Enter brain wallet phrase: "));
Address a;
DEV_IGNORE_EXCEPTIONS(a = Address(_signKey));
if (a)
return keyManager().secret(a, [&](){ return getPassword("Enter password for key (hint:" + keyManager().passwordHint(a) + "): "); });
cerr << "Bad file, UUID and address: " << _signKey << endl;
exit(-1);
}
}
void execute() void execute()
{ {
if (m_mode == OperationMode::CreateWallet) switch (m_mode)
{
case OperationMode::CreateWallet:
{ {
KeyManager wallet(m_walletPath, m_secretsPath); KeyManager wallet(m_walletPath, m_secretsPath);
if (m_masterPassword.empty()) if (m_masterPassword.empty())
@ -223,8 +326,9 @@ public:
cerr << "unable to create wallet" << endl << boost::diagnostic_information(_e); cerr << "unable to create wallet" << endl << boost::diagnostic_information(_e);
} }
} }
break;
} }
else if (m_mode == OperationMode::DecodeTx) case OperationMode::DecodeTx:
{ {
bytes b = inputData(m_inputs[0]); bytes b = inputData(m_inputs[0]);
if (b.empty()) if (b.empty())
@ -269,251 +373,236 @@ public:
{ {
cerr << "Invalid transaction: " << ex.what() << endl; cerr << "Invalid transaction: " << ex.what() << endl;
} }
break;
} }
else if (m_mode == OperationMode::SignTx) case OperationMode::SignTx:
{ {
Secret s; Secret s = getSecret(m_signKey);
if (m_inputs.empty())
string json = contentsString(m_signKey); m_inputs.push_back(string());
if (!json.empty()) for (string const& i: m_inputs)
{
SecretStore store(m_secretsPath);
s = Secret(store.secret(store.readKeyContent(json), [&](){ return getPassword("Enter password for key: "); }));
}
else
{ {
if (h128 u = fromUUID(m_signKey)) bool isFile = false;
{ try
SecretStore store(m_secretsPath);
s = Secret(store.secret(u, [&](){ return getPassword("Enter password for key: "); }));
}
else if (Address a = Address(m_signKey))
{ {
KeyManager wallet(m_walletPath, m_secretsPath); TransactionBase t = i.empty() ? TransactionBase(m_toSign) : TransactionBase(inputData(i, &isFile), CheckTransaction::None);
if (wallet.exists()) t.sign(s);
cout << t.sha3() << ": ";
if (isFile)
{ {
openWallet(wallet); writeFile(i + ".signed", toHex(t.rlp()));
s = wallet.secret(a, [&](){ return getPassword("Enter password for key: "); }); cout << i + ".signed" << endl;
} }
else else
{ cout << toHex(t.rlp()) << endl;
cerr << "Wallet doesn't exist." << endl;
exit(-1);
}
} }
else catch (Exception& ex)
{ {
cerr << "Bad file, UUID and address: " << m_signKey << endl; cerr << "Invalid transaction: " << ex.what() << endl;
exit(-1);
} }
} }
if (!s) break;
{
cerr << "UUID/address not found: " << m_signKey << endl;
exit(-1);
}
for (string const& i: m_inputs)
{
bool isFile;
bytes b = inputData(i, &isFile);
if (b.empty())
cerr << "Unknown file or bad hex: '" << i << "'" << endl;
else
try
{
TransactionBase t(b, CheckTransaction::None);
t.sign(s);
cout << t.sha3() << ": ";
if (isFile)
{
writeFile(i + ".signed", toHex(t.rlp()));
cout << i + ".signed" << endl;
}
else
cout << toHex(t.rlp()) << endl;
}
catch (Exception& ex)
{
cerr << "Invalid transaction: " << ex.what() << endl;
}
}
} }
else if (m_mode < OperationMode::CreateWallet) case OperationMode::NewBrain:
{ {
SecretStore store(m_secretsPath); if (m_name != "--")
switch (m_mode) keyManager();
{ boost::random_device d;
case OperationMode::ListBare: boost::random::uniform_int_distribution<unsigned> pickWord(0, WordList.size() - 1);
for (h128 const& u: std::set<h128>() + store.keys()) string seed;
cout << toUUID(u) << endl; for (int i = 0; i < 13; ++i)
break; seed += (seed.size() ? " " : "") + WordList[pickWord(d)];
case OperationMode::NewBare: cout << "Your brain key phrase: <<" << seed << ">>" << endl;
if (m_name != "--")
{ {
if (m_lock.empty()) std::string hint;
m_lock = createPassword("Enter a password with which to secure this account: "); cout << "Enter a hint for the phrase if you want: " << flush;
auto k = makeKey(); getline(cin, hint);
h128 u = store.importSecret(k.secret().ref(), m_lock); Address a = keyManager().importBrain(seed, m_name, hint);
cout << "Created key " << toUUID(u) << endl; cout << a.abridged() << endl;
cout << " Address: " << k.address().hex() << endl; cout << " ICAP: " << ICAP(a).encoded() << endl;
cout << " ICAP: " << ICAP(k.address()).encoded() << endl; cout << " Address: " << a.hex() << endl;
break;
}
case OperationMode::ImportBare:
for (string const& input: m_inputs)
{
h128 u;
bytesSec b;
b.writable() = fromHex(input);
if (b.size() != 32)
{
std::string s = contentsString(input);
b.writable() = fromHex(s);
if (b.size() != 32)
u = store.importKey(input);
}
if (!u && b.size() == 32)
u = store.importSecret(b, lockPassword(toAddress(Secret(b)).abridged()));
if (!u)
{
cerr << "Cannot import " << input << " not a file or secret." << endl;
continue;
}
cout << "Successfully imported " << input << " as " << toUUID(u);
}
break;
case OperationMode::InspectBare:
for (auto const& i: m_inputs)
if (!contents(i).empty())
{
h128 u = store.readKey(i, false);
bytesSec s = store.secret(u, [&](){ return getPassword("Enter password for key " + i + ": "); });
cout << "Key " << i << ":" << endl;
cout << " UUID: " << toUUID(u) << ":" << endl;
cout << " Address: " << toAddress(Secret(s)).hex() << endl;
cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
}
else if (h128 u = fromUUID(i))
{
bytesSec s = store.secret(u, [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); });
cout << "Key " << i << ":" << endl;
cout << " Address: " << toAddress(Secret(s)).hex() << endl;
cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
}
else
cerr << "Couldn't inspect " << i << "; not found." << endl;
break;
case OperationMode::ExportBare: break;
case OperationMode::RecodeBare:
for (auto const& i: m_inputs)
if (h128 u = fromUUID(i))
if (store.recode(u, lockPassword(toUUID(u)), [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); }, kdf()))
cerr << "Re-encoded " << toUUID(u) << endl;
else
cerr << "Couldn't re-encode " << toUUID(u) << "; key corrupt or incorrect password supplied." << endl;
else
cerr << "Couldn't re-encode " << i << "; not found." << endl;
break;
case OperationMode::KillBare:
for (auto const& i: m_inputs)
if (h128 u = fromUUID(i))
store.kill(u);
else
cerr << "Couldn't kill " << i << "; not found." << endl;
break;
default: break;
} }
break;
} }
else case OperationMode::InspectBrain:
{ {
KeyManager wallet(m_walletPath, m_secretsPath); Address a = toAddress(KeyManager::brain(getPassword("Enter brain wallet key phrase: ")));
if (wallet.exists()) cout << a.abridged() << endl;
openWallet(wallet); cout << " ICAP: " << ICAP(a).encoded() << endl;
else cout << " Address: " << a.hex() << endl;
{ break;
cerr << "Couldn't open wallet. Does it exist?" << endl; }
exit(-1); case OperationMode::ListBare:
} for (h128 const& u: std::set<h128>() + secretStore().keys())
switch (m_mode) cout << toUUID(u) << endl;
{ break;
case OperationMode::New: case OperationMode::NewBare:
{ {
tie(m_lock, m_lockHint) = createPassword(wallet, "Enter a password with which to secure this account (or nothing to use the master password): ", m_lock, m_lockHint); if (m_lock.empty())
auto k = makeKey(); m_lock = createPassword("Enter a password with which to secure this account: ");
bool usesMaster = m_lock.empty(); auto k = makeKey();
h128 u = usesMaster ? wallet.import(k.secret(), m_name) : wallet.import(k.secret(), m_name, m_lock, m_lockHint); h128 u = secretStore().importSecret(k.secret().ref(), m_lock);
cout << "Created key " << toUUID(u) << endl; cout << "Created key " << toUUID(u) << endl;
cout << " Name: " << m_name << endl; cout << " Address: " << k.address().hex() << endl;
if (usesMaster) cout << " ICAP: " << ICAP(k.address()).encoded() << endl;
cout << " Uses master password." << endl; break;
else }
cout << " Password hint: " << m_lockHint << endl; case OperationMode::ImportBare:
cout << " Address: " << k.address().hex() << endl; for (string const& input: m_inputs)
cout << " ICAP: " << ICAP(k.address()).encoded() << endl;
break;
}
case OperationMode::ImportWithAddress:
{ {
string const& i = m_inputs[0];
h128 u; h128 u;
bytesSec b; bytesSec b;
b.writable() = fromHex(i); b.writable() = fromHex(input);
if (b.size() != 32) if (b.size() != 32)
{ {
std::string s = contentsString(i); std::string s = contentsString(input);
b.writable() = fromHex(s); b.writable() = fromHex(s);
if (b.size() != 32) if (b.size() != 32)
u = wallet.store().importKey(i); u = secretStore().importKey(input);
} }
if (!u && b.size() == 32) if (!u && b.size() == 32)
u = wallet.store().importSecret(b, lockPassword(toAddress(Secret(b)).abridged())); u = secretStore().importSecret(b, lockPassword(toAddress(Secret(b)).abridged()));
if (!u) if (!u)
{ {
cerr << "Cannot import " << i << " not a file or secret." << endl; cerr << "Cannot import " << input << " not a file or secret." << endl;
break; continue;
} }
wallet.importExisting(u, m_name, m_address); cout << "Successfully imported " << input << " as " << toUUID(u);
cout << "Successfully imported " << i << ":" << endl;
cout << " Name: " << m_name << endl;
cout << " Address: " << m_address << endl;
cout << " UUID: " << toUUID(u) << endl;
break;
} }
case OperationMode::ImportPresale: break;
case OperationMode::InspectBare:
for (auto const& i: m_inputs)
if (!contents(i).empty())
{
h128 u = secretStore().readKey(i, false);
bytesSec s = secretStore().secret(u, [&](){ return getPassword("Enter password for key " + i + ": "); });
cout << "Key " << i << ":" << endl;
cout << " UUID: " << toUUID(u) << ":" << endl;
cout << " Address: " << toAddress(Secret(s)).hex() << endl;
cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
}
else if (h128 u = fromUUID(i))
{
bytesSec s = secretStore().secret(u, [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); });
cout << "Key " << i << ":" << endl;
cout << " Address: " << toAddress(Secret(s)).hex() << endl;
cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
}
else
cerr << "Couldn't inspect " << i << "; not found." << endl;
break;
case OperationMode::ExportBare: break;
case OperationMode::RecodeBare:
for (auto const& i: m_inputs)
if (h128 u = fromUUID(i))
if (secretStore().recode(u, lockPassword(toUUID(u)), [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); }, kdf()))
cerr << "Re-encoded " << toUUID(u) << endl;
else
cerr << "Couldn't re-encode " << toUUID(u) << "; key corrupt or incorrect password supplied." << endl;
else
cerr << "Couldn't re-encode " << i << "; not found." << endl;
break;
case OperationMode::KillBare:
for (auto const& i: m_inputs)
if (h128 u = fromUUID(i))
secretStore().kill(u);
else
cerr << "Couldn't kill " << i << "; not found." << endl;
break;
case OperationMode::New:
{
keyManager();
tie(m_lock, m_lockHint) = createPassword(keyManager(), "Enter a password with which to secure this account (or nothing to use the master password): ", m_lock, m_lockHint);
auto k = makeKey();
bool usesMaster = m_lock.empty();
h128 u = usesMaster ? keyManager().import(k.secret(), m_name) : keyManager().import(k.secret(), m_name, m_lock, m_lockHint);
cout << "Created key " << toUUID(u) << endl;
cout << " Name: " << m_name << endl;
if (usesMaster)
cout << " Uses master password." << endl;
else
cout << " Password hint: " << m_lockHint << endl;
cout << " Address: " << k.address().hex() << endl;
cout << " ICAP: " << ICAP(k.address()).encoded() << endl;
break;
}
case OperationMode::ImportWithAddress:
{
keyManager();
string const& i = m_inputs[0];
h128 u;
bytesSec b;
b.writable() = fromHex(i);
if (b.size() != 32)
{ {
std::string pw; std::string s = contentsString(i);
KeyPair k = wallet.presaleSecret(contentsString(m_inputs[0]), [&](bool){ return (pw = getPassword("Enter the password for the presale key: ")); }); b.writable() = fromHex(s);
wallet.import(k.secret(), m_name, pw, "Same password as used for presale key"); if (b.size() != 32)
break; u = keyManager().store().importKey(i);
} }
case OperationMode::List: if (!u && b.size() == 32)
u = keyManager().store().importSecret(b, lockPassword(toAddress(Secret(b)).abridged()));
if (!u)
{ {
vector<u128> bare; cerr << "Cannot import " << i << " not a file or secret." << endl;
vector<u128> nonIcap; break;
for (auto const& u: wallet.store().keys())
if (Address a = wallet.address(u))
if (a[0])
nonIcap.push_back(u);
else
{
cout << toUUID(u) << " " << a.abridged();
cout << " " << ICAP(a).encoded();
cout << " " << wallet.accountName(a) << endl;
}
else
bare.push_back(u);
for (auto const& u: nonIcap)
if (Address a = wallet.address(u))
{
cout << toUUID(u) << " " << a.abridged();
cout << " " << ICAP(a).encoded();
cout << " " << wallet.accountName(a) << endl;
}
for (auto const& u: bare)
cout << toUUID(u) << " (Bare)" << endl;
}
default: break;
} }
keyManager().importExisting(u, m_name, m_address);
cout << "Successfully imported " << i << ":" << endl;
cout << " Name: " << m_name << endl;
cout << " Address: " << m_address << endl;
cout << " UUID: " << toUUID(u) << endl;
break;
}
case OperationMode::ImportBrain:
{
keyManager();
std::string seed = getPassword("Enter brain wallet key phrase: ");
std::string hint;
cout << "Enter a hint for the phrase if you want: " << flush;
getline(cin, hint);
Address a = keyManager().importBrain(seed, m_name, hint);
cout << a << endl;
cout << " ICAP: " << ICAP(a).encoded() << endl;
cout << " Address: " << a.hex() << endl;
break;
}
case OperationMode::ImportPresale:
{
keyManager();
std::string pw;
KeyPair k = keyManager().presaleSecret(contentsString(m_inputs[0]), [&](bool){ return (pw = getPassword("Enter the password for the presale key: ")); });
keyManager().import(k.secret(), m_name, pw, "Same password as used for presale key");
break;
}
case OperationMode::List:
{
vector<u128> bare;
AddressHash got;
for (auto const& u: keyManager().store().keys())
if (Address a = keyManager().address(u))
{
got.insert(a);
cout << toUUID(u) << " " << a.abridged();
string s = ICAP(a).encoded();
cout << " " << s << string(35 - s.size(), ' ');
cout << " " << keyManager().accountName(a) << endl;
}
else
bare.push_back(u);
for (auto const& a: keyManager().accounts())
if (!got.count(a))
{
cout << " (Brain) " << a.abridged();
cout << " " << ICAP(a).encoded() << " ";
cout << " " << keyManager().accountName(a) << endl;
}
for (auto const& u: bare)
cout << toUUID(u) << " (Bare)" << endl;
}
default: break;
} }
} }
@ -544,6 +633,12 @@ public:
<< " --import-with-address [<uuid>|<file>|<secret-hex>] <address> <name> Import keys from given source with given address and place in wallet." << endl << " --import-with-address [<uuid>|<file>|<secret-hex>] <address> <name> Import keys from given source with given address and place in wallet." << endl
<< " -e,--export [ <address>|<uuid> , ... ] Export given keys." << endl << " -e,--export [ <address>|<uuid> , ... ] Export given keys." << endl
<< " -r,--recode [ <address>|<uuid>|<file> , ... ] Decrypt and re-encrypt given keys." << endl << " -r,--recode [ <address>|<uuid>|<file> , ... ] Decrypt and re-encrypt given keys." << endl
<< "Brain wallet operating modes:" << endl
<< "WARNING: Brain wallets with human-generated passphrasses are highly susceptible to attack. Don't use such a thing for" << endl
<< "anything important." << endl
<< " --new-brain [ <name>|-- ] Create a new 13-word brain wallet; argument is the name or if --, do not add to wallet."<< endl
<< " --import-brain <name> Import your own brain wallet." << endl
<< " --inspect-brain Check the address of a particular brain wallet." << endl
<< "Wallet configuration:" << endl << "Wallet configuration:" << endl
<< " --create-wallet Create an Ethereum master wallet." << endl << " --create-wallet Create an Ethereum master wallet." << endl
<< " --wallet-path <path> Specify Ethereum wallet path (default: " << KeyManager::defaultPath() << ")" << endl << " --wallet-path <path> Specify Ethereum wallet path (default: " << KeyManager::defaultPath() << ")" << endl
@ -551,7 +646,7 @@ public:
<< endl << endl
<< "Transaction operating modes:" << endl << "Transaction operating modes:" << endl
<< " -d,--decode-tx [<hex>|<file>] Decode given transaction." << endl << " -d,--decode-tx [<hex>|<file>] Decode given transaction." << endl
<< " -s,--sign-tx [ <address>|<uuid>|<file> ] [ <hex>|<file> , ... ] (Re-)Sign given transaction." << endl << " -s,--sign-tx [ <address>|<uuid>|<file>|brain((#<HD-index>):<brain-phrase>) ] [ <hex>|<file> , ... ] (Re-)Sign given transaction." << endl
<< endl << endl
<< "Encryption configuration:" << endl << "Encryption configuration:" << endl
<< " --kdf <kdfname> Specify KDF to use when encrypting (default: sc rypt)" << endl << " --kdf <kdfname> Specify KDF to use when encrypting (default: sc rypt)" << endl
@ -613,6 +708,35 @@ private:
KDF kdf() const { return m_kdf == "pbkdf2" ? KDF::PBKDF2_SHA256 : KDF::Scrypt; } KDF kdf() const { return m_kdf == "pbkdf2" ? KDF::PBKDF2_SHA256 : KDF::Scrypt; }
KeyManager& keyManager()
{
if (!m_keyManager)
{
m_keyManager.reset(new KeyManager(m_walletPath, m_secretsPath));
if (m_keyManager->exists())
openWallet(*m_keyManager);
else
{
cerr << "Couldn't open wallet. Does it exist?" << endl;
exit(-1);
}
}
return *m_keyManager;
}
SecretStore& secretStore()
{
if (m_keyManager)
return m_keyManager->store();
if (!m_secretStore)
m_secretStore.reset(new SecretStore(m_secretsPath));
return *m_secretStore;
}
/// Where the keys are.
unique_ptr<SecretStore> m_secretStore;
unique_ptr<KeyManager> m_keyManager;
/// Operating mode. /// Operating mode.
OperationMode m_mode; OperationMode m_mode;
@ -636,6 +760,7 @@ private:
/// Signing /// Signing
string m_signKey; string m_signKey;
TransactionSkeleton m_toSign;
string m_kdf = "scrypt"; string m_kdf = "scrypt";
map<string, string> m_kdfParams; map<string, string> m_kdfParams;

2
evmjit/libevmjit/Array.h

@ -58,7 +58,7 @@ private:
llvm::Function* createExtendFunc(); llvm::Function* createExtendFunc();
llvm::Function* getReallocFunc(); llvm::Function* getReallocFunc();
LazyFunction m_pushFunc = {[this](){ return createArrayPushFunc(); }}; // TODO: If works on MSVC, remove form initialization list LazyFunction m_pushFunc = {[this](){ return createArrayPushFunc(); }};
LazyFunction m_setFunc = {[this](){ return createArraySetFunc(); }}; LazyFunction m_setFunc = {[this](){ return createArraySetFunc(); }};
LazyFunction m_getPtrFunc = {[this](){ return createGetPtrFunc(); }}; LazyFunction m_getPtrFunc = {[this](){ return createGetPtrFunc(); }};
LazyFunction m_getFunc = {[this](){ return createArrayGetFunc(); }}; LazyFunction m_getFunc = {[this](){ return createArrayGetFunc(); }};

8
evmjit/libevmjit/BasicBlock.cpp

@ -110,11 +110,13 @@ void LocalStack::set(size_t _index, llvm::Value* _word)
void LocalStack::finalize(llvm::IRBuilder<>& _builder, llvm::BasicBlock& _bb) void LocalStack::finalize(llvm::IRBuilder<>& _builder, llvm::BasicBlock& _bb)
{ {
auto blockTerminator = _bb.getTerminator(); auto blockTerminator = _bb.getTerminator();
assert(blockTerminator); if (!blockTerminator || blockTerminator->getOpcode() != llvm::Instruction::Ret)
if (blockTerminator->getOpcode() != llvm::Instruction::Ret)
{ {
// Not needed in case of ret instruction. Ret invalidates the stack. // Not needed in case of ret instruction. Ret invalidates the stack.
_builder.SetInsertPoint(blockTerminator); if (blockTerminator)
_builder.SetInsertPoint(blockTerminator);
else
_builder.SetInsertPoint(&_bb);
// Update items fetched from global stack ignoring the poped ones // Update items fetched from global stack ignoring the poped ones
assert(m_globalPops <= m_input.size()); // pop() always does get() assert(m_globalPops <= m_input.size()); // pop() always does get()

86
evmjit/libevmjit/Compiler.cpp

@ -29,6 +29,8 @@ namespace eth
namespace jit namespace jit
{ {
static const auto c_destIdxLabel = "destIdx";
Compiler::Compiler(Options const& _options): Compiler::Compiler(Options const& _options):
m_options(_options), m_options(_options),
m_builder(llvm::getGlobalContext()) m_builder(llvm::getGlobalContext())
@ -93,21 +95,34 @@ std::vector<BasicBlock> Compiler::createBasicBlocks(code_iterator _codeBegin, co
return blocks; return blocks;
} }
void Compiler::fillJumpTable() void Compiler::resolveJumps()
{ {
assert(m_jumpTableBB); // Iterate through all EVM instructions blocks (skip first 4 - special blocks).
if (llvm::pred_empty(m_jumpTableBB)) for (auto it = std::next(m_mainFunc->begin(), 4); it != m_mainFunc->end(); ++it)
{
m_jumpTableBB->eraseFromParent(); // remove if unused
return;
}
// TODO: Extend this function as `resolveJumps()` and fill gaps in branch instructions.
auto target = llvm::cast<llvm::PHINode>(m_jumpTableBB->begin());
for (auto pred: llvm::predecessors(m_jumpTableBB))
{ {
auto targetMd = llvm::cast<llvm::LocalAsMetadata>(pred->getTerminator()->getMetadata("target")->getOperand(0)); auto jumpTable = llvm::cast<llvm::SwitchInst>(m_jumpTableBB->getTerminator());
target->addIncoming(targetMd->getValue(), pred); auto jumpTableInput = llvm::cast<llvm::PHINode>(m_jumpTableBB->begin());
auto nextBlock = it->getNextNode() != m_mainFunc->end() ? it->getNextNode() : m_stopBB;
auto term = it->getTerminator();
if (!term) // Block may have no terminator if the next instruction is a jump destination.
llvm::IRBuilder<>{it}.CreateBr(nextBlock);
else if (auto jump = llvm::dyn_cast<llvm::BranchInst>(term))
if (jump->getSuccessor(0) == m_jumpTableBB)
{
auto destIdx = llvm::cast<llvm::ValueAsMetadata>(jump->getMetadata(c_destIdxLabel)->getOperand(0))->getValue();
if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(destIdx))
{
// If destination index is a constant do direct jump to the destination block.
auto bb = jumpTable->findCaseValue(constant).getCaseSuccessor();
jump->setSuccessor(0, bb);
}
else
jumpTableInput->addIncoming(destIdx, it); // Fill up PHI node
if (jump->isConditional())
jump->setSuccessor(1, nextBlock); // Set next block for conditional jumps
}
} }
} }
@ -160,13 +175,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_itera
auto firstBB = blocks.empty() ? m_stopBB : blocks.front().llvm(); auto firstBB = blocks.empty() ? m_stopBB : blocks.front().llvm();
m_builder.CreateCondBr(normalFlow, firstBB, m_abortBB, Type::expectTrue); m_builder.CreateCondBr(normalFlow, firstBB, m_abortBB, Type::expectTrue);
for (auto it = blocks.begin(); it != blocks.end(); ++it) for (auto& block: blocks)
{ compileBasicBlock(block, runtimeManager, arith, memory, ext, gasMeter, stack);
// TODO: Rewrite
auto nextIt = it + 1;
auto nextBasicBlock = (nextIt != blocks.end()) ? nextIt->llvm() : nullptr; // TODO: What with Stop block?
compileBasicBlock(*it, runtimeManager, arith, memory, ext, gasMeter, nextBasicBlock, stack, jumpTable);
}
// Code for special blocks: // Code for special blocks:
m_builder.SetInsertPoint(m_stopBB); m_builder.SetInsertPoint(m_stopBB);
@ -175,19 +185,15 @@ std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_itera
m_builder.SetInsertPoint(m_abortBB); m_builder.SetInsertPoint(m_abortBB);
runtimeManager.exit(ReturnCode::OutOfGas); runtimeManager.exit(ReturnCode::OutOfGas);
fillJumpTable(); resolveJumps();
return module; return module;
} }
void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runtimeManager, void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runtimeManager,
Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock, Stack& _globalStack, Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter, Stack& _globalStack)
llvm::SwitchInst& jumpTable)
{ {
if (!_nextBasicBlock) // this is the last block in the code
_nextBasicBlock = m_stopBB;
m_builder.SetInsertPoint(_basicBlock.llvm()); m_builder.SetInsertPoint(_basicBlock.llvm());
LocalStack stack{_globalStack}; LocalStack stack{_globalStack};
@ -556,24 +562,16 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti
case Instruction::JUMP: case Instruction::JUMP:
case Instruction::JUMPI: case Instruction::JUMPI:
{ {
auto jumpBlock = m_jumpTableBB; auto destIdx = llvm::MDNode::get(m_builder.getContext(), llvm::ValueAsMetadata::get(stack.pop()));
auto target = stack.pop();
// Create branch instruction, initially to jump table.
// Destination will be optimized with direct jump during jump resolving if destination index is a constant.
auto jumpInst = (inst == Instruction::JUMP) ? auto jumpInst = (inst == Instruction::JUMP) ?
m_builder.CreateBr(jumpBlock) : m_builder.CreateBr(m_jumpTableBB) :
m_builder.CreateCondBr(m_builder.CreateICmpNE(stack.pop(), Constant::get(0), "jump.check"), jumpBlock, _nextBasicBlock); m_builder.CreateCondBr(m_builder.CreateICmpNE(stack.pop(), Constant::get(0), "jump.check"), m_jumpTableBB, nullptr);
if (auto constant = llvm::dyn_cast<llvm::ConstantInt>(target)) // Attach medatada to branch instruction with information about destination index.
{ jumpInst->setMetadata(c_destIdxLabel, destIdx);
// If target index is a constant do direct jump to the target block.
auto bb = jumpTable.findCaseValue(constant).getCaseSuccessor();
jumpInst->setSuccessor(0, bb);
}
else
{
// Attach medatada to branch instruction with information about target index.
auto targetMd = llvm::MDNode::get(jumpInst->getContext(), llvm::LocalAsMetadata::get(target));
jumpInst->setMetadata("target", targetMd);
}
break; break;
} }
@ -790,10 +788,6 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti
_gasMeter.commitCostBlock(); _gasMeter.commitCostBlock();
// Block may have no terminator if the next instruction is a jump destination.
if (!_basicBlock.llvm()->getTerminator())
m_builder.CreateBr(_nextBasicBlock);
stack.finalize(m_builder, *_basicBlock.llvm()); // TODO: Use references stack.finalize(m_builder, *_basicBlock.llvm()); // TODO: Use references
m_builder.SetInsertPoint(_basicBlock.llvm()->getFirstNonPHI()); // TODO: Move to LocalStack::finalize m_builder.SetInsertPoint(_basicBlock.llvm()->getFirstNonPHI()); // TODO: Move to LocalStack::finalize

4
evmjit/libevmjit/Compiler.h

@ -31,9 +31,9 @@ private:
std::vector<BasicBlock> createBasicBlocks(code_iterator _begin, code_iterator _end, llvm::SwitchInst& _switchInst); std::vector<BasicBlock> createBasicBlocks(code_iterator _begin, code_iterator _end, llvm::SwitchInst& _switchInst);
void compileBasicBlock(BasicBlock& _basicBlock, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, void compileBasicBlock(BasicBlock& _basicBlock, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter,
llvm::BasicBlock* _nextBasicBlock, class Stack& _globalStack, llvm::SwitchInst& _jumpTable); class Stack& _globalStack);
void fillJumpTable(); void resolveJumps();
/// Compiler options /// Compiler options
Options const& m_options; Options const& m_options;

2
evmjit/libevmjit/Stack.cpp

@ -7,8 +7,6 @@
#include "RuntimeManager.h" #include "RuntimeManager.h"
#include "Utils.h" #include "Utils.h"
#include <set> // DEBUG only
namespace dev namespace dev
{ {
namespace eth namespace eth

9
libdevcore/FixedHash.cpp

@ -30,7 +30,14 @@ boost::random_device dev::s_fixedHashEngine;
h128 dev::fromUUID(std::string const& _uuid) h128 dev::fromUUID(std::string const& _uuid)
{ {
return h128(boost::replace_all_copy(_uuid, "-", "")); try
{
return h128(boost::replace_all_copy(_uuid, "-", ""));
}
catch (...)
{
return h128();
}
} }
std::string dev::toUUID(h128 const& _uuid) std::string dev::toUUID(h128 const& _uuid)

3
libdevcore/vector_ref.h

@ -86,7 +86,7 @@ public:
void cleanse() void cleanse()
{ {
uint8_t* p = (uint8_t*)begin(); uint8_t* p = (uint8_t*)begin();
size_t len = (uint8_t*)end() - p; size_t const len = (uint8_t*)end() - p;
size_t loop = len; size_t loop = len;
size_t count = s_cleanseCounter; size_t count = s_cleanseCounter;
while (loop--) while (loop--)
@ -98,6 +98,7 @@ public:
if (p) if (p)
count += (63 + (size_t)p); count += (63 + (size_t)p);
s_cleanseCounter = (uint8_t)count; s_cleanseCounter = (uint8_t)count;
memset((uint8_t*)begin(), 0, len);
} }
_T* begin() { return m_data; } _T* begin() { return m_data; }

20
libdevcrypto/SecretStore.cpp

@ -107,6 +107,14 @@ bytesSec SecretStore::secret(h128 const& _uuid, function<string()> const& _pass,
return key; return key;
} }
bytesSec SecretStore::secret(string const& _content, string const& _pass)
{
js::mValue u = upgraded(_content);
if (u.type() != js::obj_type)
return bytesSec();
return decrypt(js::write_string(u.get_obj()["crypto"], false), _pass);
}
h128 SecretStore::importSecret(bytesSec const& _s, string const& _pass) h128 SecretStore::importSecret(bytesSec const& _s, string const& _pass)
{ {
h128 r; h128 r;
@ -169,11 +177,13 @@ void SecretStore::save(string const& _keysPath)
void SecretStore::load(string const& _keysPath) void SecretStore::load(string const& _keysPath)
{ {
fs::path p(_keysPath); fs::path p(_keysPath);
fs::create_directories(p); try
DEV_IGNORE_EXCEPTIONS(fs::permissions(p, fs::owner_all)); {
for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it) for (fs::directory_iterator it(p); it != fs::directory_iterator(); ++it)
if (fs::is_regular_file(it->path())) if (fs::is_regular_file(it->path()))
readKey(it->path().string(), true); readKey(it->path().string(), true);
}
catch (...) {}
} }
h128 SecretStore::readKey(string const& _file, bool _takeFileOwnership) h128 SecretStore::readKey(string const& _file, bool _takeFileOwnership)

3
libdevcrypto/SecretStore.h

@ -53,6 +53,9 @@ public:
/// @param _pass function that returns the password for the key. /// @param _pass function that returns the password for the key.
/// @param _useCache if true, allow previously decrypted keys to be returned directly. /// @param _useCache if true, allow previously decrypted keys to be returned directly.
bytesSec secret(h128 const& _uuid, std::function<std::string()> const& _pass, bool _useCache = true) const; bytesSec secret(h128 const& _uuid, std::function<std::string()> const& _pass, bool _useCache = true) const;
/// @returns the secret key stored by the given @a _uuid.
/// @param _pass function that returns the password for the key.
static bytesSec secret(std::string const& _content, std::string const& _pass);
/// Imports the (encrypted) key stored in the file @a _file and copies it to the managed directory. /// Imports the (encrypted) key stored in the file @a _file and copies it to the managed directory.
h128 importKey(std::string const& _file) { auto ret = readKey(_file, false); if (ret) save(); return ret; } h128 importKey(std::string const& _file) { auto ret = readKey(_file, false); if (ret) save(); return ret; }
/// Imports the (encrypted) key contained in the json formatted @a _content and stores it in /// Imports the (encrypted) key contained in the json formatted @a _content and stores it in

4
libethcore/Common.cpp

@ -112,14 +112,14 @@ std::string formatBalance(bigint const& _b)
else else
b = (u256)_b; b = (u256)_b;
if (b > units()[0].first * 10000) if (b > units()[0].first * 1000)
{ {
ret << (b / units()[0].first) << " " << units()[0].second; ret << (b / units()[0].first) << " " << units()[0].second;
return ret.str(); return ret.str();
} }
ret << setprecision(5); ret << setprecision(5);
for (auto const& i: units()) for (auto const& i: units())
if (i.first != 1 && b >= i.first * 100) if (i.first != 1 && b >= i.first * 1)
{ {
ret << (double(b / (i.first / 1000)) / 1000.0) << " " << i.second; ret << (double(b / (i.first / 1000)) / 1000.0) << " " << i.second;
return ret.str(); return ret.str();

17
libethcore/KeyManager.cpp

@ -224,6 +224,16 @@ Secret KeyManager::brain(string const& _seed)
return ret; return ret;
} }
Secret KeyManager::subkey(Secret const& _s, unsigned _index)
{
RLPStream out(2);
out << _s.ref();
out << _index;
bytesSec r;
out.swapOut(r.writable());
return sha3(r);
}
Address KeyManager::importBrain(string const& _seed, string const& _accountName, string const& _passwordHint) Address KeyManager::importBrain(string const& _seed, string const& _accountName, string const& _passwordHint)
{ {
Address addr = toAddress(brain(_seed)); Address addr = toAddress(brain(_seed));
@ -233,6 +243,13 @@ Address KeyManager::importBrain(string const& _seed, string const& _accountName,
return addr; return addr;
} }
void KeyManager::importExistingBrain(Address const& _a, string const& _accountName, string const& _passwordHint)
{
m_keyInfo[_a].accountName = _accountName;
m_keyInfo[_a].passwordHint = _passwordHint;
write();
}
void KeyManager::importExisting(h128 const& _uuid, string const& _info, string const& _pass, string const& _passwordHint) void KeyManager::importExisting(h128 const& _uuid, string const& _info, string const& _pass, string const& _passwordHint)
{ {
bytesSec key = m_store.secret(_uuid, [&](){ return _pass; }); bytesSec key = m_store.secret(_uuid, [&](){ return _pass; });

6
libethcore/KeyManager.h

@ -108,6 +108,7 @@ public:
h128 import(Secret const& _s, std::string const& _accountName, std::string const& _pass, std::string const& _passwordHint); h128 import(Secret const& _s, std::string const& _accountName, std::string const& _pass, std::string const& _passwordHint);
h128 import(Secret const& _s, std::string const& _accountName) { return import(_s, _accountName, defaultPassword(), std::string()); } h128 import(Secret const& _s, std::string const& _accountName) { return import(_s, _accountName, defaultPassword(), std::string()); }
Address importBrain(std::string const& _seed, std::string const& _accountName, std::string const& _seedHint); Address importBrain(std::string const& _seed, std::string const& _accountName, std::string const& _seedHint);
void importExistingBrain(Address const& _a, std::string const& _accountName, std::string const& _seedHint);
SecretStore& store() { return m_store; } SecretStore& store() { return m_store; }
void importExisting(h128 const& _uuid, std::string const& _accountName, std::string const& _pass, std::string const& _passwordHint); void importExisting(h128 const& _uuid, std::string const& _accountName, std::string const& _pass, std::string const& _passwordHint);
@ -130,11 +131,14 @@ public:
static std::string defaultPath() { return getDataDir("ethereum") + "/keys.info"; } static std::string defaultPath() { return getDataDir("ethereum") + "/keys.info"; }
/// Extracts the secret key from the presale wallet. /// Extracts the secret key from the presale wallet.
KeyPair presaleSecret(std::string const& _json, std::function<std::string(bool)> const& _password); static KeyPair presaleSecret(std::string const& _json, std::function<std::string(bool)> const& _password);
/// @returns the brainwallet secret for the given seed. /// @returns the brainwallet secret for the given seed.
static Secret brain(std::string const& _seed); static Secret brain(std::string const& _seed);
/// @returns the HD subkey for a given key.
static Secret subkey(Secret const& _s, unsigned _index);
private: private:
std::string getPassword(h128 const& _uuid, std::function<std::string()> const& _pass = DontKnowThrow) const; std::string getPassword(h128 const& _uuid, std::function<std::string()> const& _pass = DontKnowThrow) const;
std::string getPassword(h256 const& _passHash, std::function<std::string()> const& _pass = DontKnowThrow) const; std::string getPassword(h256 const& _passHash, std::function<std::string()> const& _pass = DontKnowThrow) const;

24
libjsqrc/ethereumjs/dist/web3-light.js

@ -4577,12 +4577,34 @@ var addToGroup = new Method({
params: 0 params: 0
}); });
var newFilter = new Method({
name: 'newFilter',
call: 'shh_newFilter',
params: 1
});
var getFilterChanges = new Method({
name: 'getFilterChanges',
call: 'shh_getFilterChanges',
params: 1
});
var getMessages = new Method({
name: 'getMessages',
call: 'shh_getMessages',
params: 1
})
var methods = [ var methods = [
post, post,
newIdentity, newIdentity,
hasIdentity, hasIdentity,
newGroup, newGroup,
addToGroup addToGroup,
newFilter,
getFilterChanges,
getMessages
]; ];
module.exports = { module.exports = {

4
libjsqrc/ethereumjs/dist/web3-light.min.js

File diff suppressed because one or more lines are too long

24
libjsqrc/ethereumjs/dist/web3.js

@ -4577,12 +4577,34 @@ var addToGroup = new Method({
params: 0 params: 0
}); });
var newFilter = new Method({
name: 'newFilter',
call: 'shh_newFilter',
params: 1
});
var getFilterChanges = new Method({
name: 'getFilterChanges',
call: 'shh_getFilterChanges',
params: 1
});
var getMessages = new Method({
name: 'getMessages',
call: 'shh_getMessages',
params: 1
})
var methods = [ var methods = [
post, post,
newIdentity, newIdentity,
hasIdentity, hasIdentity,
newGroup, newGroup,
addToGroup addToGroup,
newFilter,
getFilterChanges,
getMessages
]; ];
module.exports = { module.exports = {

4
libjsqrc/ethereumjs/dist/web3.js.map

File diff suppressed because one or more lines are too long

4
libjsqrc/ethereumjs/dist/web3.min.js

File diff suppressed because one or more lines are too long

24
libjsqrc/ethereumjs/lib/web3/shh.js

@ -54,12 +54,34 @@ var addToGroup = new Method({
params: 0 params: 0
}); });
var newFilter = new Method({
name: 'newFilter',
call: 'shh_newFilter',
params: 1
});
var getFilterChanges = new Method({
name: 'getFilterChanges',
call: 'shh_getFilterChanges',
params: 1
});
var getMessages = new Method({
name: 'getMessages',
call: 'shh_getMessages',
params: 1
})
var methods = [ var methods = [
post, post,
newIdentity, newIdentity,
hasIdentity, hasIdentity,
newGroup, newGroup,
addToGroup addToGroup,
newFilter,
getFilterChanges,
getMessages
]; ];
module.exports = { module.exports = {

26
mix/qml/Block.qml

@ -23,6 +23,11 @@ ColumnLayout
property int blockIndex property int blockIndex
property variant scenario property variant scenario
property string labelColor: "#414141" property string labelColor: "#414141"
property string selectedBlockColor: "#accbf2"
property string selectedBlockForeground: "#445e7f"
property int scenarioIndex property int scenarioIndex
signal txSelected(var txIndex) signal txSelected(var txIndex)
@ -105,14 +110,15 @@ ColumnLayout
} }
} }
Label Image {
{
text: qsTr("EDIT")
color: "#1397da"
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 14 anchors.rightMargin: 14
visible: number === -2 visible: number === -2
source: "qrc:/qml/img/edit_combox.png"
height: 15
fillMode: Image.PreserveAspectFit
MouseArea MouseArea
{ {
anchors.fill: parent anchors.fill: parent
@ -122,6 +128,7 @@ ColumnLayout
projectModel.stateListModel.editState(scenarioIndex) projectModel.stateListModel.editState(scenarioIndex)
} }
} }
} }
} }
} }
@ -237,11 +244,12 @@ ColumnLayout
function select() function select()
{ {
rowContentTr.selected = true rowContentTr.selected = true
rowContentTr.color = "#4F4F4F" rowContentTr.color = selectedBlockColor
hash.color = "#EAB920" hash.color = selectedBlockForeground
func.color = "#EAB920" func.color = selectedBlockForeground
txSelected(index) txSelected(index)
} }
function deselect() function deselect()
@ -345,7 +353,7 @@ ColumnLayout
Image { Image {
id: debugImg id: debugImg
source: "qrc:/qml/img/rightarrow@2x.png" source: "qrc:/qml/img/rightarrowcircle.png"
width: debugActionWidth width: debugActionWidth
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter

21
mix/qml/Watchers.qml

@ -12,13 +12,16 @@ import "js/QEtherHelper.js" as QEtherHelper
import "." import "."
Rectangle { Rectangle {
color: "#4F4F4F" color: selectedBlockColor
property variant tx property variant tx
property variant currentState property variant currentState
property variant bc property variant bc
property var blockIndex property var blockIndex
property var txIndex property var txIndex
property string selectedBlockColor: "#accbf2"
property string selectedBlockForeground: "#445e7f"
function clear() function clear()
{ {
from.text = "" from.text = ""
@ -83,11 +86,11 @@ Rectangle {
id: fromLabel id: fromLabel
text: qsTr("from") text: qsTr("from")
visible: false visible: false
color: "#EAB920" color: selectedBlockForeground
} }
Label { Label {
id: from id: from
color: "#EAB920" color: selectedBlockForeground
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
clip: true clip: true
@ -97,11 +100,11 @@ Rectangle {
id: toLabel id: toLabel
text: qsTr("to") text: qsTr("to")
visible: false visible: false
color: "#EAB920" color: selectedBlockForeground
} }
Label { Label {
id: to id: to
color: "#EAB920" color: selectedBlockForeground
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 1 maximumLineCount: 1
clip: true clip: true
@ -109,7 +112,7 @@ Rectangle {
} }
Label { Label {
id: value id: value
color: "#EAB920" color: selectedBlockForeground
font.italic: true font.italic: true
clip: true clip: true
} }
@ -118,9 +121,9 @@ Rectangle {
Image { Image {
anchors.right: rowHeader.parent.right anchors.right: rowHeader.parent.right
anchors.top: rowHeader.parent.top anchors.top: rowHeader.parent.top
anchors.topMargin: -3 anchors.topMargin: 5
source: "qrc:/qml/img/edittransaction2.png" source: "qrc:/qml/img/edit_combox.png"
height: 30 height: 15
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
visible: from.text !== "" visible: from.text !== ""
MouseArea MouseArea

BIN
mix/qml/img/rightarrowcircle.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

1
mix/res.qrc

@ -86,6 +86,7 @@
<file>qml/img/restoreicon@2x.png</file> <file>qml/img/restoreicon@2x.png</file>
<file>qml/img/rightarrow.png</file> <file>qml/img/rightarrow.png</file>
<file>qml/img/rightarrow@2x.png</file> <file>qml/img/rightarrow@2x.png</file>
<file>qml/img/rightarrowcircle.png</file>
<file>qml/img/saveicon.png</file> <file>qml/img/saveicon.png</file>
<file>qml/img/saveicon@2x.png</file> <file>qml/img/saveicon@2x.png</file>
<file>qml/img/sendtransactionicon.png</file> <file>qml/img/sendtransactionicon.png</file>

4
templates/dockplugin.cpp

@ -14,11 +14,13 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file $NAME.h /** @file $NAME.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2015 * @date 2015
*/ */
DEV_AZ_NOTE_PLUGIN($NAME);
#include "$NAME.h" #include "$NAME.h"
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>

4
templates/plugin.cpp

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file $NAME.h /** @file $NAME.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2015 * @date 2015
*/ */
@ -27,6 +27,8 @@ using namespace dev;
using namespace az; using namespace az;
using namespace eth; using namespace eth;
DEV_AZ_NOTE_PLUGIN($NAME);
$NAME::$NAME(MainFace* _m): $NAME::$NAME(MainFace* _m):
Plugin(_m, "$NAME") Plugin(_m, "$NAME")
{ {

Loading…
Cancel
Save