Browse Source

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

cl-refactor
Paweł Bylica 10 years ago
parent
commit
8b55eff4d7
  1. 9
      README.md
  2. 2
      alethzero/CMakeLists.txt
  3. 7
      alethzero/GraphParameters.h
  4. 16
      alethzero/Grapher.h
  5. 12
      alethzero/Main.ui
  6. 10
      alethzero/MainWin.cpp
  7. 1
      alethzero/MainWin.h
  8. 5
      alethzero/MiningView.cpp
  9. 1
      alethzero/NatspecHandler.cpp
  10. 2
      alethzero/NatspecHandler.h
  11. 78
      alethzero/OurWebThreeStubServer.cpp
  12. 20
      alethzero/OurWebThreeStubServer.h
  13. 4
      alethzero/Transact.cpp
  14. 5
      cmake/EthDependencies.cmake
  15. 58
      cmake/EthExecutableHelper.cmake
  16. 10
      cmake/FindMHD.cmake
  17. 4
      eth/CMakeLists.txt
  18. 6
      eth/main.cpp
  19. 2
      evmjit/libevmjit-cpp/Env.cpp
  20. 6
      exp/main.cpp
  21. 2
      extdep/CMakeLists.txt
  22. 2
      libdevcore/Common.cpp
  23. 4
      libdevcore/RLP.h
  24. 2
      libdevcore/Worker.h
  25. 7
      libdevcore/vector_ref.h
  26. 2
      libdevcrypto/Common.cpp
  27. 3
      libdevcrypto/Common.h
  28. 6
      libdevcrypto/TrieDB.h
  29. 2
      libethcore/CommonEth.cpp
  30. 3
      libethereum/BlockChain.cpp
  31. 3
      libethereum/BlockQueue.cpp
  32. 32
      libethereum/CanonBlockChain.cpp
  33. 2
      libethereum/Client.h
  34. 40
      libethereum/GenesisInfo.cpp
  35. 32
      libethereum/GenesisInfo.h
  36. 6
      libethereum/State.cpp
  37. 2
      libethereum/Transaction.cpp
  38. 12
      libevm/VM.cpp
  39. 2
      libevm/VMFace.h
  40. 2
      libevm/VMFactory.cpp
  41. 6
      libevmcore/Assembly.cpp
  42. 2
      libevmcore/Assembly.h
  43. 1
      libjsqrc/ethereumjs/.gitignore
  44. 2
      libjsqrc/ethereumjs/.travis.yml
  45. 8
      libjsqrc/ethereumjs/README.md
  46. 2
      libjsqrc/ethereumjs/bower.json
  47. 701
      libjsqrc/ethereumjs/dist/ethereum.js
  48. 28
      libjsqrc/ethereumjs/dist/ethereum.js.map
  49. 2
      libjsqrc/ethereumjs/dist/ethereum.min.js
  50. 97
      libjsqrc/ethereumjs/gulpfile.js
  51. 4
      libjsqrc/ethereumjs/index.js
  52. 3
      libjsqrc/ethereumjs/lib/const.js
  53. 5
      libjsqrc/ethereumjs/lib/contract.js
  54. 35
      libjsqrc/ethereumjs/lib/db.js
  55. 85
      libjsqrc/ethereumjs/lib/eth.js
  56. 1
      libjsqrc/ethereumjs/lib/event.js
  57. 140
      libjsqrc/ethereumjs/lib/filter.js
  58. 6
      libjsqrc/ethereumjs/lib/httpsync.js
  59. 102
      libjsqrc/ethereumjs/lib/providermanager.js
  60. 103
      libjsqrc/ethereumjs/lib/requestmanager.js
  61. 37
      libjsqrc/ethereumjs/lib/shh.js
  62. 49
      libjsqrc/ethereumjs/lib/watches.js
  63. 177
      libjsqrc/ethereumjs/lib/web3.js
  64. 18
      libjsqrc/ethereumjs/package.json
  65. 2
      libjsqrc/ethereumjs/test/eth.methods.js
  66. 27
      libjsqrc/ethereumjs/test/filter.methods.js
  67. 11
      libjsqrc/ethereumjs/test/web3.methods.js
  68. 26
      libp2p/Host.cpp
  69. 6
      libp2p/UDP.cpp
  70. 41
      libsolidity/AST.cpp
  71. 33
      libsolidity/AST.h
  72. 2
      libsolidity/ASTForward.h
  73. 4
      libsolidity/ASTJsonConverter.cpp
  74. 4
      libsolidity/ASTJsonConverter.h
  75. 6
      libsolidity/ASTPrinter.cpp
  76. 4
      libsolidity/ASTPrinter.h
  77. 8
      libsolidity/ASTVisitor.h
  78. 20
      libsolidity/AST_accept.h
  79. 51
      libsolidity/Compiler.cpp
  80. 3
      libsolidity/Compiler.h
  81. 1
      libsolidity/CompilerContext.h
  82. 63
      libsolidity/CompilerStack.cpp
  83. 11
      libsolidity/CompilerStack.h
  84. 58
      libsolidity/ExpressionCompiler.cpp
  85. 13
      libsolidity/ExpressionCompiler.h
  86. 14
      libsolidity/NameAndTypeResolver.cpp
  87. 2
      libsolidity/NameAndTypeResolver.h
  88. 51
      libsolidity/Parser.cpp
  89. 9
      libsolidity/Parser.h
  90. 6
      libsolidity/Token.h
  91. 43
      libsolidity/Types.cpp
  92. 31
      libsolidity/Types.h
  93. 4
      libsolidity/grammar.txt
  94. 108
      libweb3jsonrpc/AccountHolder.cpp
  95. 74
      libweb3jsonrpc/AccountHolder.h
  96. 108
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  97. 12
      libweb3jsonrpc/WebThreeStubServerBase.h
  98. 18
      libweb3jsonrpc/abstractwebthreestubserver.h
  99. 4
      libweb3jsonrpc/spec.json
  100. 14
      mix/qml/Debugger.qml

9
README.md

@ -1,12 +1,12 @@
## Ethereum C++ Client.
By Gav Wood, 2014.
By Gav Wood et al, 2013, 2014, 2015.
| Linux | OSX | Windows
----------|---------|-----|--------
develop | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/OSX%20C%2B%2B%20develop%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Windows%20C%2B%2B%20develop%20branch)](http://build.ethdev.com/builders/Windows%20C%2B%2B%20develop%20branch/builds/-1)
master | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/OSX%20C%2B%2B%20master%20branch/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Windows%20C%2B%2B%20master%20branch)](http://build.ethdev.com/builders/Windows%20C%2B%2B%20master%20branch/builds/-1)
evmjit | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20evmjit)](http://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20evmjit/builds/-1) | [![Build+Status](http://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20develop%20evmjit)](http://build.ethdev.com/builders/OSX%20C%2B%2B%20develop%20evmjit/builds/-1) | N/A
develop | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20branch)](https://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20develop%20branch)](https://build.ethdev.com/builders/OSX%20C%2B%2B%20develop%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Windows%20C%2B%2B%20develop%20branch)](https://build.ethdev.com/builders/Windows%20C%2B%2B%20develop%20branch/builds/-1)
master | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20master%20branch)](https://build.ethdev.com/builders/Linux%20C%2B%2B%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20master%20branch)](https://build.ethdev.com/builders/OSX%20C%2B%2B%20master%20branch/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Windows%20C%2B%2B%20master%20branch)](https://build.ethdev.com/builders/Windows%20C%2B%2B%20master%20branch/builds/-1)
evmjit | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=Linux%20C%2B%2B%20develop%20evmjit)](https://build.ethdev.com/builders/Linux%20C%2B%2B%20develop%20evmjit/builds/-1) | [![Build+Status](https://build.ethdev.com/buildstatusimage?builder=OSX%20C%2B%2B%20develop%20evmjit)](https://build.ethdev.com/builders/OSX%20C%2B%2B%20develop%20evmjit/builds/-1) | N/A
[![Stories in Ready](https://badge.waffle.io/ethereum/cpp-ethereum.png?label=ready&title=Ready)](http://waffle.io/ethereum/cpp-ethereum)
@ -24,7 +24,6 @@ To run the tests, make sure you clone the tests repository from github.com/ether
See [TODO](https://github.com/ethereum/cpp-ethereum/wiki/TODO)
### License
See [LICENSE](LICENSE)

2
alethzero/CMakeLists.txt

@ -58,5 +58,5 @@ if (NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC"))
endif()
# eth_install_executable is defined in cmake/EthExecutableHelper.cmake
eth_install_executable(${EXECUTABLE})
eth_install_executable(${EXECUTABLE} DLLS ${MHD_DLL_RELEASE})

7
alethzero/GraphParameters.h

@ -37,8 +37,11 @@ static T graphParameters(T _min, T _max, unsigned _divisions, T* o_from = 0, T*
T uMax = _max / _divisor;
if (uMax == uMin || !_divisions)
{
*o_from = 0;
*o_delta = 1;
if (o_delta && o_from)
{
*o_from = 0;
*o_delta = 1;
}
return 1;
}
long double l10 = std::log10((uMax - uMin) / T(_divisions) * 5.5f);

16
alethzero/Grapher.h

@ -76,24 +76,24 @@ public:
void labelYOrderedPoints(std::map<float, float> const& _translatedData, int _maxCount = 20, float _minFactor = .01f) const;
protected:
QPainter* p;
QPainter* p = nullptr;
QRect active;
std::pair<float, float> xRange;
std::pair<float, float> yRange;
float xM;
float xC;
float yM;
float yC;
float xM = 0;
float xC = 0;
float yM = 0;
float yC = 0;
float dx;
float dy;
float dx = 0;
float dy = 0;
std::function<std::string(float _f)> xLabel;
std::function<std::string(float _f)> yLabel;
std::function<std::string(float _x, float _y)> pLabel;
float fontPixelSize;
float fontPixelSize = 0;
// Translate from raw indexed data into x/y graph units. Only relevant for indexed data.
float xT(float _dataIndex) const { return _dataIndex * xM + xC; }

12
alethzero/Main.ui

@ -163,6 +163,7 @@
<property name="title">
<string>&amp;Special</string>
</property>
<addaction name="natSpec"/>
<addaction name="paranoia"/>
<addaction name="clearPending"/>
<addaction name="killBlockchain"/>
@ -1652,6 +1653,17 @@ font-size: 14pt</string>
<string>New &amp;Transaction...</string>
</property>
</action>
<action name="natSpec">
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>true</bool>
</property>
<property name="text">
<string>&amp;NatSpec Enabled</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

10
alethzero/MainWin.cpp

@ -201,6 +201,11 @@ Main::~Main()
g_logPost = simpleDebugOut;
}
bool Main::confirm() const
{
return ui->natSpec->isChecked();
}
void Main::on_newIdentity_triggered()
{
KeyPair kp = KeyPair::create();
@ -651,6 +656,7 @@ void Main::writeSettings()
s.setValue("localNetworking", ui->localNetworking->isChecked());
s.setValue("forceMining", ui->forceMining->isChecked());
s.setValue("paranoia", ui->paranoia->isChecked());
s.setValue("natSpec", ui->natSpec->isChecked());
s.setValue("showAll", ui->showAll->isChecked());
s.setValue("showAllAccounts", ui->showAllAccounts->isChecked());
s.setValue("clientName", ui->clientName->text());
@ -662,7 +668,7 @@ void Main::writeSettings()
s.setValue("jitvm", ui->jitvm->isChecked());
bytes d = m_webThree->saveNetwork();
if (d.size())
if (!d.empty())
m_networkConfig = QByteArray((char*)d.data(), (int)d.size());
s.setValue("peers", m_networkConfig);
s.setValue("nameReg", ui->nameReg->text());
@ -720,6 +726,7 @@ void Main::readSettings(bool _skipGeometry)
ui->forceMining->setChecked(s.value("forceMining", false).toBool());
on_forceMining_triggered();
ui->paranoia->setChecked(s.value("paranoia", false).toBool());
ui->natSpec->setChecked(s.value("natSpec", true).toBool());
ui->showAll->setChecked(s.value("showAll", false).toBool());
ui->showAllAccounts->setChecked(s.value("showAllAccounts", false).toBool());
ui->clientName->setText(s.value("clientName", "").toString());
@ -1160,6 +1167,7 @@ void Main::timerEvent(QTimerEvent*)
interval = 0;
refreshNetwork();
refreshWhispers();
poll();
}
else
interval += 100;

1
alethzero/MainWin.h

@ -72,6 +72,7 @@ public:
dev::eth::Client* ethereum() const { return m_webThree->ethereum(); }
std::shared_ptr<dev::shh::WhisperHost> whisper() const { return m_webThree->whisper(); }
bool confirm() const;
NatSpecFace* natSpec() { return &m_natSpecDB; }
QVariant evalRaw(QString const& _js);

5
alethzero/MiningView.cpp

@ -48,7 +48,6 @@ string sL(float _x, float _y) { return toString(round(_x * 1000)) + "s (" + toSt
MiningView::MiningView(QWidget* _p): QWidget(_p)
{
}
void MiningView::appendStats(list<MineInfo> const& _i, MineProgress const& _p)
@ -86,10 +85,10 @@ void MiningView::appendStats(list<MineInfo> const& _i, MineProgress const& _p)
for (auto& i: m_resets)
i -= o;
remove_if(m_resets.begin(), m_resets.end(), [](int i){return i < 0;});
m_resets.erase(remove_if(m_resets.begin(), m_resets.end(), [](int i){return i < 0;}), m_resets.end());
for (auto& i: m_completes)
i -= o;
remove_if(m_completes.begin(), m_completes.end(), [](int i){return i < 0;});
m_completes.erase(remove_if(m_completes.begin(), m_completes.end(), [](int i){return i < 0;}), m_completes.end());
m_progress = _p;
update();

1
alethzero/NatspecHandler.cpp

@ -66,7 +66,6 @@ string NatspecHandler::getUserNotice(string const& json, dev::bytes const& _tran
{
Json::Value natspec;
Json::Value userNotice;
string retStr;
m_reader.parse(json, natspec);
FixedHash<4> transactionFunctionHash((bytesConstRef(&_transactionData).cropped(0, 4).toBytes()));

2
alethzero/NatspecHandler.h

@ -54,6 +54,6 @@ class NatspecHandler: public NatSpecFace
private:
ldb::ReadOptions m_readOptions;
ldb::WriteOptions m_writeOptions;
ldb::DB* m_db;
ldb::DB* m_db = nullptr;
Json::Reader m_reader;
};

78
alethzero/OurWebThreeStubServer.cpp

@ -33,9 +33,11 @@ using namespace dev;
using namespace dev::eth;
OurWebThreeStubServer::OurWebThreeStubServer(jsonrpc::AbstractServerConnector& _conn, WebThreeDirect& _web3,
vector<KeyPair> const& _accounts, Main* main):
WebThreeStubServer(_conn, _web3, _accounts), m_web3(&_web3), m_main(main)
{}
vector<KeyPair> const& _accounts, Main* _main):
WebThreeStubServer(_conn, _web3, _accounts), m_web3(&_web3), m_main(_main)
{
connect(_main, SIGNAL(poll()), this, SLOT(doValidations()));
}
string OurWebThreeStubServer::shh_newIdentity()
{
@ -44,29 +46,44 @@ string OurWebThreeStubServer::shh_newIdentity()
return toJS(kp.pub());
}
bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string const& _text) const
bool OurWebThreeStubServer::showAuthenticationPopup(string const& _title, string const& _text)
{
int button;
QMetaObject::invokeMethod(m_main, "authenticate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, button), Q_ARG(QString, QString::fromStdString(_title)), Q_ARG(QString, QString::fromStdString(_text)));
return button == QMessageBox::Ok;
if (!m_main->confirm())
{
cnote << "Skipping confirmation step for: " << _title << "\n" << _text;
return true;
}
QMessageBox userInput;
userInput.setText(QString::fromStdString(_title));
userInput.setInformativeText(QString::fromStdString(_text));
userInput.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
userInput.button(QMessageBox::Ok)->setText("Allow");
userInput.button(QMessageBox::Cancel)->setText("Reject");
userInput.setDefaultButton(QMessageBox::Cancel);
return userInput.exec() == QMessageBox::Ok;
//QMetaObject::invokeMethod(m_main, "authenticate", Qt::BlockingQueuedConnection, Q_RETURN_ARG(int, button), Q_ARG(QString, QString::fromStdString(_title)), Q_ARG(QString, QString::fromStdString(_text)));
//return button == QMessageBox::Ok;
}
bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t) const
bool OurWebThreeStubServer::showCreationNotice(TransactionSkeleton const& _t, bool _toProxy)
{
return showAuthenticationPopup("Contract Creation Transaction", "ÐApp is attemping to create a contract; to be endowed with " + formatBalance(_t.value) + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is <b>" + formatBalance(_t.value + _t.gas * _t.gasPrice) + "</b>.");
return showAuthenticationPopup("Contract Creation Transaction", string("ÐApp is attemping to create a contract; ") + (_toProxy ? "(this transaction is not executed directly, but forwarded to another ÐApp) " : "") + "to be endowed with " + formatBalance(_t.value) + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + ".");
}
bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t) const
bool OurWebThreeStubServer::showSendNotice(TransactionSkeleton const& _t, bool _toProxy)
{
return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to).toStdString() + ", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is <b>" + formatBalance(_t.value + _t.gas * _t.gasPrice) + "</b>.");
return showAuthenticationPopup("Fund Transfer Transaction", "ÐApp is attempting to send " + formatBalance(_t.value) + " to a recipient " + m_main->pretty(_t.to).toStdString() + (_toProxy ? " (this transaction is not executed directly, but forwarded to another ÐApp)" : "") +
", with additional network fees of up to " + formatBalance(_t.gas * _t.gasPrice) + ".\n\nMaximum total cost is " + formatBalance(_t.value + _t.gas * _t.gasPrice) + ".");
}
bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t) const
bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t, bool _toProxy)
{
return showAuthenticationPopup("DANGEROUS! Unknown Contract Transaction!",
"ÐApp is attempting to call into an unknown contract at address " +
m_main->pretty(_t.to).toStdString() +
".\n\nCall involves sending " +
m_main->pretty(_t.to).toStdString() + ".\n\n" +
(_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") +
"Call involves sending " +
formatBalance(_t.value) + " to the recipient, with additional network fees of up to " +
formatBalance(_t.gas * _t.gasPrice) +
"However, this also does other stuff which we don't understand, and does so in your name.\n\n" +
@ -76,25 +93,43 @@ bool OurWebThreeStubServer::showUnknownCallNotice(TransactionSkeleton const& _t)
"REJECT UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!");
}
bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t)
void OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t, bool _toProxy)
{
Guard l(x_queued);
m_queued.push(make_pair(_t, _toProxy));
}
void OurWebThreeStubServer::doValidations()
{
Guard l(x_queued);
while (!m_queued.empty())
{
auto q = m_queued.front();
m_queued.pop();
if (validateTransaction(q.first, q.second))
WebThreeStubServerBase::authenticate(q.first, q.second);
}
}
bool OurWebThreeStubServer::validateTransaction(TransactionSkeleton const& _t, bool _toProxy)
{
if (_t.creation)
{
// recipient has no code - nothing special about this transaction, show basic value transfer info
return showCreationNotice(_t);
// show notice concerning the creation code. TODO: this needs entering into natspec.
return showCreationNotice(_t, _toProxy);
}
h256 contractCodeHash = m_web3->ethereum()->postState().codeHash(_t.to);
if (contractCodeHash == EmptySHA3)
{
// recipient has no code - nothing special about this transaction, show basic value transfer info
return showSendNotice(_t);
return showSendNotice(_t, _toProxy);
}
string userNotice = m_main->natSpec()->getUserNotice(contractCodeHash, _t.data);
if (userNotice.empty())
return showUnknownCallNotice(_t);
return showUnknownCallNotice(_t, _toProxy);
NatspecExpressionEvaluator evaluator;
userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString();
@ -104,11 +139,12 @@ bool OurWebThreeStubServer::authenticate(TransactionSkeleton const& _t)
"ÐApp attempting to conduct contract interaction with " +
m_main->pretty(_t.to).toStdString() +
": <b>" + userNotice + "</b>.\n\n" +
(_toProxy ? "This transaction is not executed directly, but forwarded to another ÐApp.\n\n" : "") +
(_t.value > 0 ?
"In addition, ÐApp is attempting to send " +
formatBalance(_t.value) + " to said recipient, with additional network fees of up to " +
formatBalance(_t.gas * _t.gasPrice) + " = <b>" +
formatBalance(_t.value + _t.gas * _t.gasPrice) + "</b>."
formatBalance(_t.gas * _t.gasPrice) + " = " +
formatBalance(_t.value + _t.gas * _t.gasPrice) + "."
:
"Additional network fees are at most" +
formatBalance(_t.gas * _t.gasPrice) + ".")

20
alethzero/OurWebThreeStubServer.h

@ -19,7 +19,9 @@
* @date 2014
*/
#include <queue>
#include <QtCore/QObject>
#include <libdevcore/Guards.h>
#include <libethcore/CommonJS.h>
#include <libdevcrypto/Common.h>
#include <libweb3jsonrpc/WebThreeStubServer.h>
@ -35,16 +37,24 @@ public:
std::vector<dev::KeyPair> const& _accounts, Main* main);
virtual std::string shh_newIdentity() override;
virtual bool authenticate(dev::eth::TransactionSkeleton const& _t);
virtual void authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy);
signals:
void onNewId(QString _s);
public slots:
void doValidations();
private:
bool showAuthenticationPopup(std::string const& _title, std::string const& _text) const;
bool showCreationNotice(dev::eth::TransactionSkeleton const& _t) const;
bool showSendNotice(dev::eth::TransactionSkeleton const& _t) const;
bool showUnknownCallNotice(dev::eth::TransactionSkeleton const& _t) const;
bool showAuthenticationPopup(std::string const& _title, std::string const& _text);
bool showCreationNotice(dev::eth::TransactionSkeleton const& _t, bool _toProxy);
bool showSendNotice(dev::eth::TransactionSkeleton const& _t, bool _toProxy);
bool showUnknownCallNotice(dev::eth::TransactionSkeleton const& _t, bool _toProxy);
bool validateTransaction(dev::eth::TransactionSkeleton const& _t, bool _toProxy);
std::queue<std::pair<dev::eth::TransactionSkeleton, bool>> m_queued;
dev::Mutex x_queued;
dev::WebThreeDirect* m_web3;
Main* m_main;

4
alethzero/Transact.cpp

@ -169,9 +169,7 @@ void Transact::rejigData()
QString lll;
QString solidity;
if (src.find_first_not_of("1234567890abcdefABCDEF") == string::npos && src.size() % 2 == 0)
{
m_data = fromHex(src);
}
else if (sourceIsSolidity(src))
{
dev::solidity::CompilerStack compiler;
@ -204,7 +202,7 @@ void Transact::rejigData()
for (auto& i: errors)
i = "(LLL " + i + ")";
}
catch (string err)
catch (string const& err)
{
errors.push_back("Serpent " + err);
}

5
cmake/EthDependencies.cmake

@ -128,6 +128,11 @@ if (NOT HEADLESS)
set (MACDEPLOYQT_APP ${Qt5Core_DIR}/../../../bin/macdeployqt)
message(" - macdeployqt path: ${MACDEPLOYQT_APP}")
endif()
# we need to find path to windeployqt on windows
if (WIN32)
set (WINDEPLOYQT_APP ${Qt5Core_DIR}/../../../bin/windeployqt)
message(" - windeployqt path: ${WINDEPLOYQT_APP}")
endif()
# TODO check node && npm version
find_program(ETH_NODE node)

58
cmake/EthExecutableHelper.cmake

@ -56,14 +56,14 @@ macro(eth_install_executable EXECUTABLE)
set (extra_macro_args ${ARGN})
set (options)
set (one_value_args QMLDIR)
set (multi_value_args)
set (multi_value_args DLLS)
cmake_parse_arguments (ETH_INSTALL_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}")
if (ETH_INSTALL_EXECUTABLE_QMLDIR)
if (APPLE)
set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}")
elseif (WIN32)
set(eth_qml_dir --qmldir ${ETH_INSTALL_EXECUTABLE_QMLDIR})
set(eth_qml_dir "--qmldir ${ETH_INSTALL_EXECUTABLE_QMLDIR}")
endif()
message(STATUS "${EXECUTABLE} qmldir: ${eth_qml_dir}")
endif()
@ -88,48 +88,30 @@ macro(eth_install_executable EXECUTABLE)
set(BU_CHMOD_BUNDLE_ITEMS 1)
verify_app(\"${APP_BUNDLE_PATH}\")
" COMPONENT RUNTIME )
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
# copy all dlls to executable directory
# TODO improve that by copying only required dlls
file (GLOB DLLS ${ETH_DEPENDENCY_INSTALL_DIR}/bin/*.dll)
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
foreach(DLL ${DLLS})
get_target_property(TARGET_LIBS ${EXECUTABLE} INTERFACE_LINK_LIBRARIES)
string(REGEX MATCH "Qt5::Core" HAVE_QT ${TARGET_LIBS})
if ("${HAVE_QT}" STREQUAL "Qt5::Core")
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmake -E copy "${DLL}" "$<TARGET_FILE_DIR:${EXECUTABLE}>"
COMMAND cmd /C "set PATH=${Qt5Core_DIR}/../../../bin;%PATH% && ${WINDEPLOYQT_APP} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.exe ${eth_qml_dir}"
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endforeach()
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmake -E copy_directory
"${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms"
$<TARGET_FILE_DIR:${EXECUTABLE}>/platforms
)
# ugly way, improve that
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmake -E copy_directory
"${ETH_DEPENDENCY_INSTALL_DIR}/qml"
$<TARGET_FILE_DIR:${EXECUTABLE}>
)
install( FILES ${DLLS}
DESTINATION bin
COMPONENT ${EXECUTABLE}
)
#workaround for https://bugreports.qt.io/browse/QTBUG-42083
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmd /C "(echo [Paths] & echo.Prefix=.)" > "qt.conf"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} VERBATIM
)
endif()
install( DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/plugins/platforms
DESTINATION bin
COMPONENT ${EXECUTABLE}
#copy additional dlls
foreach(dll ${ETH_INSTALL_EXECUTABLE_DLLS})
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy ${dll} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
)
file (GLOB QMLS ${ETH_DEPENDENCY_INSTALL_DIR}/qml/*)
foreach(QML ${QMLS})
install( DIRECTORY ${QML}
DESTINATION bin
COMPONENT ${EXECUTABLE}
)
endforeach()
endforeach(dll)
install( TARGETS ${EXECUTABLE} RUNTIME
DESTINATION bin

10
cmake/FindMHD.cmake

@ -29,13 +29,19 @@ set(MHD_LIBRARIES ${MHD_LIBRARY})
# boost is using the same "hack" as us with "optimized" and "debug"
# official MHD project actually uses _d suffix
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
#TODO: place dlls into CMAKE_CFG_INTDIR subfolders
string(REPLACE ".lib" ".dll" MHD_DLL_RELEASE ${MHD_LIBRARY})
string(REPLACE "/lib/" "/bin/" MHD_DLL_RELEASE ${MHD_DLL_RELEASE})
find_library(
MHD_LIBRARY_DEBUG
NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d
DOC "mhd debug library"
)
set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
# always use release for now
#string(REPLACE ".lib" ".dll" MHD_DLL_DEBUG ${MHD_LIBRARY_DEBUG})
#set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
endif()

4
eth/CMakeLists.txt

@ -28,5 +28,9 @@ endif()
target_link_libraries(${EXECUTABLE} webthree)
target_link_libraries(${EXECUTABLE} secp256k1)
if (WIN32)
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy ${MHD_DLL_RELEASE} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
endif()
install( TARGETS ${EXECUTABLE} DESTINATION bin )

6
eth/main.cpp

@ -749,7 +749,7 @@ int main(int argc, char** argv)
else if (format == "standard+")
oof = [&](uint64_t, Instruction instr, bigint, bigint, dev::eth::VM* vvm, dev::eth::ExtVMFace const* vextVM)
{
dev::eth::VM* vm = (VM*)vvm;
dev::eth::VM* vm = vvm;
dev::eth::ExtVM const* ext = static_cast<ExtVM const*>(vextVM);
if (instr == Instruction::STOP || instr == Instruction::RETURN || instr == Instruction::SUICIDE)
for (auto const& i: ext->state().storage(ext->myAddress))
@ -898,7 +898,9 @@ int main(int argc, char** argv)
while (!g_exit)
this_thread::sleep_for(chrono::milliseconds(1000));
writeFile((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp", web3.saveNetwork());
auto netData = web3.saveNetwork();
if (!netData.empty())
writeFile((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp", netData);
return 0;
}

2
evmjit/libevmjit-cpp/Env.cpp

@ -70,7 +70,7 @@ extern "C"
_env->subBalance(value);
auto receiveAddress = right160(*_receiveAddress);
auto inRef = bytesConstRef{_inBeg, _inSize};
auto outRef = bytesConstRef{_outBeg, _outSize};
auto outRef = bytesRef{_outBeg, _outSize};
auto codeAddress = right160(*_codeAddress);
u256 gas = *io_gas;
auto ret = _env->call(receiveAddress, value, inRef, gas, outRef, {}, {}, codeAddress);

6
exp/main.cpp

@ -26,6 +26,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/TrieDB.h>
#include <libdevcore/CommonIO.h>
#include <libp2p/All.h>
#include <libethereum/DownloadMan.h>
@ -33,11 +34,13 @@
#include <liblll/All.h>
#include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h>
#include <test/JsonSpiritHeaders.h>
using namespace std;
using namespace dev;
using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
namespace js = json_spirit;
#if 0
int main()
@ -98,8 +101,7 @@ int main()
#else
int main()
{
cnote << KeyPair(Secret("0000000000000000000000000000000000000000000000000000000000000000")).address();
cnote << KeyPair(Secret("1111111111111111111111111111111111111111111111111111111111111111")).address();
return 0;
}
#endif

2
extdep/CMakeLists.txt

@ -7,7 +7,7 @@ include(eth_download.cmake)
# all dependencies will be installed into this directory, separated by platform
string(TOLOWER ${CMAKE_SYSTEM_NAME} _system_name)
set(ETH_DEPENDENCY_INSTALL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/install/${_system_name}")
set(ETH_DEPENDENCY_SERVER "http://build.ethdev.com/builds/${_system_name}-precompiled")
set(ETH_DEPENDENCY_SERVER "https://build.ethdev.com/builds/${_system_name}-precompiled")
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/lib)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/include)
file(MAKE_DIRECTORY ${ETH_DEPENDENCY_INSTALL_DIR}/bin)

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev
{
char const* Version = "0.8.1";
char const* Version = "0.8.2";
}

4
libdevcore/RLP.h

@ -242,7 +242,9 @@ public:
AllowNonCanon = 1,
ThrowOnFail = 4,
FailIfTooBig = 8,
FailIfTooSmall = 16,
Strict = ThrowOnFail | FailIfTooBig,
VeryStrict = ThrowOnFail | FailIfTooBig | FailIfTooSmall,
LaisezFaire = AllowNonCanon
};
@ -269,7 +271,7 @@ public:
template <class _N> _N toHash(int _flags = Strict) const
{
if (!isData() || (length() > _N::size && (_flags & FailIfTooBig)))
if (!isData() || (length() > _N::size && (_flags & FailIfTooBig)) || (length() < _N::size && (_flags & FailIfTooSmall)))
if (_flags & ThrowOnFail)
BOOST_THROW_EXCEPTION(BadCast());
else

2
libdevcore/Worker.h

@ -64,7 +64,7 @@ protected:
private:
std::string m_name;
unsigned m_idleWaitMs;
unsigned m_idleWaitMs = 0;
mutable Mutex x_work; ///< Lock for the network existance.
std::unique_ptr<std::thread> m_work; ///< The network thread.

7
libdevcore/vector_ref.h

@ -19,7 +19,7 @@ public:
vector_ref(): m_data(nullptr), m_count(0) {}
vector_ref(_T* _data, size_t _count): m_data(_data), m_count(_count) {}
vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const*, std::string*>::type _data): m_data((_T*)_data->data()), m_count(_data->size() / sizeof(_T)) {}
vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const*, std::string*>::type _data): m_data(reinterpret_cast<_T*>(_data->data())), m_count(_data->size() / sizeof(_T)) {}
vector_ref(typename std::conditional<std::is_const<_T>::value, std::vector<typename std::remove_const<_T>::type> const*, std::vector<_T>*>::type _data): m_data(_data->data()), m_count(_data->size()) {}
vector_ref(typename std::conditional<std::is_const<_T>::value, std::string const&, std::string&>::type _data): m_data((_T*)_data.data()), m_count(_data.size() / sizeof(_T)) {}
#ifdef STORAGE_LEVELDB_INCLUDE_DB_H_
@ -29,9 +29,10 @@ public:
bool contentsEqual(std::vector<mutable_value_type> const& _c) const { return _c.size() == m_count && !memcmp(_c.data(), m_data, m_count); }
std::vector<mutable_value_type> toVector() const { return std::vector<mutable_value_type>(m_data, m_data + m_count); }
std::vector<unsigned char> toBytes() const { return std::vector<unsigned char>((unsigned char const*)m_data, (unsigned char const*)m_data + m_count * sizeof(_T)); }
std::vector<unsigned char> toBytes() const { return std::vector<unsigned char>(reinterpret_cast<unsigned char const*>(m_data), reinterpret_cast<unsigned char const*>(m_data) + m_count * sizeof(_T)); }
std::string toString() const { return std::string((char const*)m_data, ((char const*)m_data) + m_count * sizeof(_T)); }
template <class _T2> operator vector_ref<_T2>() const { assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count); return vector_ref<_T2>((_T2*)m_data, m_count * sizeof(_T) / sizeof(_T2)); }
template <class _T2> explicit operator vector_ref<_T2>() const { assert(m_count * sizeof(_T) / sizeof(_T2) * sizeof(_T2) / sizeof(_T) == m_count); return vector_ref<_T2>(reinterpret_cast<_T2*>(m_data), m_count * sizeof(_T) / sizeof(_T2)); }
operator vector_ref<_T const>() const { return vector_ref<_T const>(m_data, m_count); }
_T* data() const { return m_data; }
size_t count() const { return m_count; }

2
libdevcrypto/Common.cpp

@ -44,6 +44,8 @@ bool dev::SignatureStruct::isValid() const
return true;
}
Address dev::ZeroAddress = Address();
Public dev::toPublic(Secret const& _secret)
{
Public p;

3
libdevcrypto/Common.h

@ -62,6 +62,9 @@ struct SignatureStruct
/// @NOTE This is not endian-specific; it's just a bunch of bytes.
using Address = h160;
/// The zero address.
extern Address ZeroAddress;
/// A vector of Ethereum addresses.
using Addresses = h160s;

6
libdevcrypto/TrieDB.h

@ -161,7 +161,7 @@ public:
std::string at(bytesConstRef _key) const;
void insert(bytesConstRef _key, bytesConstRef _value);
void remove(bytesConstRef _key);
void contains(bytesConstRef _key) { return !at(_key).empty(); }
bool contains(bytesConstRef _key) { return !at(_key).empty(); }
class iterator
{
@ -809,7 +809,10 @@ template <class DB> bytes GenericTrieDB<DB>::deleteAt(RLP const& _orig, NibbleSl
// exactly our node - return null.
if (k == _k && isLeaf(_orig))
{
killNode(_orig);
return RLPNull;
}
// partial key is our key - move down.
if (_k.contains(k))
@ -917,7 +920,6 @@ template <class DB> bytes GenericTrieDB<DB>::place(RLP const& _orig, NibbleSlice
tdebug << "place " << _orig << _k;
#endif
killNode(_orig);
if (_orig.isEmpty())
return (RLPStream(2) << hexPrefixEncode(_k, true) << _s).out();

2
libethcore/CommonEth.cpp

@ -32,7 +32,7 @@ namespace dev
namespace eth
{
const unsigned c_protocolVersion = 53;
const unsigned c_protocolVersion = 54;
const unsigned c_databaseVersion = 5;
vector<pair<u256, string>> const& units()

3
libethereum/BlockChain.cpp

@ -22,6 +22,7 @@
#include "BlockChain.h"
#include <boost/filesystem.hpp>
#include <test/JsonSpiritHeaders.h>
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/FileSystem.h>
@ -29,11 +30,13 @@
#include <libethcore/ProofOfWork.h>
#include <libethcore/BlockInfo.h>
#include <liblll/Compiler.h>
#include "GenesisInfo.h"
#include "State.h"
#include "Defaults.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
namespace js = json_spirit;
#define ETH_CATCH 1

3
libethereum/BlockQueue.cpp

@ -59,7 +59,6 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc)
catch (Exception const& _e)
{
cwarn << "Ignoring malformed block: " << diagnostic_information(_e);
return false;
return ImportResult::Malformed;
}
#endif
@ -128,7 +127,7 @@ void BlockQueue::drain(std::vector<bytes>& o_out)
void BlockQueue::noteReadyWithoutWriteGuard(h256 _good)
{
list<h256> goodQueue(1, _good);
while (goodQueue.size())
while (!goodQueue.empty())
{
auto r = m_unknown.equal_range(goodQueue.front());
goodQueue.pop_front();

32
libethereum/CanonBlockChain.cpp

@ -21,6 +21,7 @@
#include "CanonBlockChain.h"
#include <test/JsonSpiritHeaders.h>
#include <boost/filesystem.hpp>
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
@ -29,11 +30,13 @@
#include <libethcore/ProofOfWork.h>
#include <libethcore/BlockInfo.h>
#include <liblll/Compiler.h>
#include "GenesisInfo.h"
#include "State.h"
#include "Defaults.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
namespace js = json_spirit;
#define ETH_CATCH 1
@ -42,18 +45,23 @@ std::map<Address, Account> const& dev::eth::genesisState()
static std::map<Address, Account> s_ret;
if (s_ret.empty())
{
// Initialise.
for (auto i: vector<string>({
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6",
"e6716f9544a56c530d868e4bfbacb172315bdead",
"b9c015918bdaba24b4ff057a92a3873d6eb201be",
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4",
"2ef47100e0787b915105fd5e3f4ff6752079d5cb",
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826",
"6c386a4b26f73c802f34673f7248bb118f97424a",
"e4157b34ea9615cfbde6b4fda419828124b70c78"
}))
s_ret[Address(fromHex(i))] = Account(u256(1) << 200, Account::NormalCreation);
js::mValue val;
json_spirit::read_string(c_genesisInfo, val);
for (auto account: val.get_obj())
{
u256 balance;
if (account.second.get_obj().count("wei"))
balance = u256(account.second.get_obj()["wei"].get_str());
else
balance = u256(account.second.get_obj()["finney"].get_str()) * finney;
if (account.second.get_obj().count("code"))
{
s_ret[Address(fromHex(account.first))] = Account(balance, Account::ContractConception);
s_ret[Address(fromHex(account.first))].setCode(fromHex(account.second.get_obj()["code"].get_str()));
}
else
s_ret[Address(fromHex(account.first))] = Account(balance, Account::NormalCreation);
}
}
return s_ret;
}

2
libethereum/Client.h

@ -127,7 +127,7 @@ template <class T> struct ABIDeserialiser {};
template <unsigned N> struct ABIDeserialiser<FixedHash<N>> { static FixedHash<N> deserialise(bytesConstRef& io_t) { static_assert(N <= 32, "Parameter sizes must be at most 32 bytes."); FixedHash<N> ret; io_t.cropped(32 - N, N).populate(ret.ref()); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser<u256> { static u256 deserialise(bytesConstRef& io_t) { u256 ret = fromBigEndian<u256>(io_t.cropped(0, 32)); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser<u160> { static u160 deserialise(bytesConstRef& io_t) { u160 ret = fromBigEndian<u160>(io_t.cropped(12, 20)); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser<string32> { static string32 deserialise(bytesConstRef& io_t) { string32 ret; io_t.cropped(0, 32).populate(vector_ref<char>(ret.data(), 32)); io_t = io_t.cropped(32); return ret; } };
template <> struct ABIDeserialiser<string32> { static string32 deserialise(bytesConstRef& io_t) { string32 ret; io_t.cropped(0, 32).populate(bytesRef((byte*)ret.data(), 32)); io_t = io_t.cropped(32); return ret; } };
template <class T> T abiOut(bytes const& _data)
{

40
libethereum/GenesisInfo.cpp

@ -0,0 +1,40 @@
/*
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 GenesisInfo.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "GenesisInfo.h"
std::string const dev::eth::c_genesisInfo =
R"ETHEREUM(
{
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"e6716f9544a56c530d868e4bfbacb172315bdead": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"b9c015918bdaba24b4ff057a92a3873d6eb201be": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"1a26338f0d905e295fccb71fa9ea849ffa12aaf4": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"2ef47100e0787b915105fd5e3f4ff6752079d5cb": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"cd2a3d9f938e13cd947ec05abc7fe734df8dd826": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"6c386a4b26f73c802f34673f7248bb118f97424a": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"e4157b34ea9615cfbde6b4fda419828124b70c78": { "wei": "1606938044258990275541962092341162602522202993782792835301376" },
"b0afc46d9ce366d06ab4952ca27db1d9557ae9fd": { "finney": "154162184" },
"f6b1e9dc460d4d62cc22ec5f987d726929c0f9f0": { "finney": "102774789" },
"cc45122d8b7fa0b1eaa6b29e0fb561422a9239d0": { "finney": "51387394" },
"b7576e9d314df41ec5506494293afb1bd5d3f65d": { "finney": "69423399" },
}
)ETHEREUM";

32
libethereum/GenesisInfo.h

@ -0,0 +1,32 @@
/*
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 GenesisInfo.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <string>
namespace dev {
namespace eth {
extern std::string const c_genesisInfo;
}
}

6
libethereum/State.cpp

@ -537,7 +537,7 @@ u256 State::enact(bytesConstRef _block, BlockChain const& _bc, bool _checkNonce)
cwarn << "Hex: " << toHex(b);
cwarn << TransactionReceipt(&b);
}
cwarn << "Recorded: " << m_currentBlock.receiptsRoot;
cwarn << "Recorded: " << m_currentBlock.receiptsRoot;
auto rs = _bc.receipts(m_currentBlock.hash);
for (unsigned j = 0; j < rs.receipts.size(); ++j)
{
@ -1199,11 +1199,11 @@ std::ostream& dev::eth::operator<<(std::ostream& _out, State const& _s)
else if (j.second)
cached.insert(j.first);
}
if (delta.size())
if (!delta.empty())
lead = (lead == " . ") ? "*.* " : "*** ";
contout << " @:";
if (delta.size())
if (!delta.empty())
contout << "???";
else
contout << r[2].toHash<h256>();

2
libethereum/Transaction.cpp

@ -40,7 +40,7 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig)
m_gasPrice = rlp[field = 1].toInt<u256>();
m_gas = rlp[field = 2].toInt<u256>();
m_type = rlp[field = 3].isEmpty() ? ContractCreation : MessageCall;
m_receiveAddress = rlp[field = 3].toHash<Address>();
m_receiveAddress = rlp[field = 3].isEmpty() ? Address() : rlp[field = 3].toHash<Address>(RLP::VeryStrict);
m_value = rlp[field = 4].toInt<u256>();
m_data = rlp[field = 5].toBytes();
byte v = rlp[field = 6].toInt<byte>() - 27;

12
libevm/VM.cpp

@ -34,7 +34,13 @@ void VM::reset(u256 _gas) noexcept
bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
{
auto memNeed = [](dev::u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; };
auto memNeed = [](u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; };
auto gasForMem = [](bigint _size) -> bigint
{
bigint s = _size / 32;
// return (bigint)c_memoryGas * (s + s * s / 1024);
return (bigint)c_memoryGas * s;
};
if (m_jumpDests.empty())
for (unsigned i = 0; i < _ext.code.size(); ++i)
@ -297,7 +303,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
newTempSize = (newTempSize + 31) / 32 * 32;
if (newTempSize > m_temp.size())
runGas += c_memoryGas * (newTempSize - m_temp.size()) / 32;
runGas += gasForMem(newTempSize) - gasForMem(m_temp.size());
runGas += c_copyGas * (copySize + 31) / 32;
onOperation();
@ -529,7 +535,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
m_stack.push_back(_ext.currentBlock.difficulty);
break;
case Instruction::GASLIMIT:
m_stack.push_back(1000000);
m_stack.push_back(_ext.currentBlock.gasLimit);
break;
case Instruction::PUSH1:
case Instruction::PUSH2:

2
libevm/VMFace.h

@ -40,7 +40,7 @@ public:
explicit VMFace(u256 _gas): m_gas(_gas) {}
virtual ~VMFace() = default;
VMFace(VMFace const&) = delete;
void operator=(VMFace const&) = delete;
VMFace& operator=(VMFace const&) = delete;
virtual void reset(u256 _gas = 0) noexcept { m_gas = _gas; }
u256 gas() const noexcept { return m_gas; }

2
libevm/VMFactory.cpp

@ -39,7 +39,7 @@ void VMFactory::setKind(VMKind _kind)
std::unique_ptr<VMFace> VMFactory::create(u256 _gas)
{
#if ETH_EVMJIT
return std::unique_ptr<VMFace>(g_kind == VMKind::JIT ? (VMFace*)new JitVM(_gas) : new VM(_gas));
return std::unique_ptr<VMFace>(g_kind == VMKind::JIT ? static_cast<VMFace*>(new JitVM(_gas)) : static_cast<VMFace*>(new VM(_gas)));
#else
asserts(g_kind == VMKind::Interpreter && "JIT disabled in build configuration");
return std::unique_ptr<VMFace>(new VM(_gas));

6
libevmcore/Assembly.cpp

@ -214,7 +214,7 @@ ostream& Assembly::streamRLP(ostream& _out, string const& _prefix) const
BOOST_THROW_EXCEPTION(InvalidOpcode());
}
if (m_data.size() || m_subs.size())
if (!m_data.empty() || !m_subs.empty())
{
_out << _prefix << ".data:" << endl;
for (auto const& i: m_data)
@ -441,7 +441,7 @@ Assembly& Assembly::optimise(bool _enable)
if (i.type() == PushTag)
tags.erase(i.data());
if (tags.size())
if (!tags.empty())
{
auto t = *tags.begin();
unsigned i = t.second;
@ -567,7 +567,7 @@ bytes Assembly::assemble() const
toBigEndian(tagPos[i.second], r);
}
if (m_data.size())
if (!m_data.empty())
{
ret.push_back(0);
for (auto const& i: m_data)

2
libevmcore/Assembly.h

@ -72,6 +72,8 @@ inline std::ostream& operator<<(std::ostream& _out, AssemblyItems const& _i) { r
class Assembly
{
public:
Assembly() {}
AssemblyItem newTag() { return AssemblyItem(Tag, m_usedTags++); }
AssemblyItem newPushTag() { return AssemblyItem(PushTag, m_usedTags++); }
AssemblyItem newData(bytes const& _data) { h256 h = (u256)std::hash<std::string>()(asString(_data)); m_data[h] = _data; return AssemblyItem(PushData, h); }

1
libjsqrc/ethereumjs/.gitignore

@ -5,6 +5,7 @@
# git config --global core.excludesfile ~/.gitignore_global
*.swp
/coverage
/tmp
*/**/*un~
*un~

2
libjsqrc/ethereumjs/.travis.yml

@ -9,5 +9,5 @@ script:
- "jshint *.js lib"
after_script:
- npm run-script build
- npm test
- npm run-script test-coveralls

8
libjsqrc/ethereumjs/README.md

@ -3,7 +3,7 @@
This is the Ethereum compatible [JavaScript API](https://github.com/ethereum/wiki/wiki/JavaScript-API)
which implements the [Generic JSON RPC](https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC) spec. It's available on npm as a node module and also for bower and component as an embeddable js
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![dependency status][dep-image]][dep-url] [![dev dependency status][dep-dev-image]][dep-dev-url]
[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![dependency status][dep-image]][dep-url] [![dev dependency status][dep-dev-image]][dep-dev-url][![Coverage Status][coveralls-image]][coveralls-url]
<!-- [![browser support](https://ci.testling.com/ethereum/ethereum.js.png)](https://ci.testling.com/ethereum/ethereum.js) -->
@ -30,9 +30,9 @@ Require the library:
var web3 = require('web3');
Set a provider (QtProvider, WebSocketProvider, HttpRpcProvider)
Set a provider (QtSyncProvider, HttpSyncProvider)
var web3.setProvider(new web3.providers.WebSocketProvider('ws://localhost:40404/eth'));
web3.setProvider(new web3.providers.HttpSyncProvider());
There you go, now you can use it:
@ -93,4 +93,6 @@ ethereum -ws -loglevel=4
[dep-url]: https://david-dm.org/ethereum/ethereum.js
[dep-dev-image]: https://david-dm.org/ethereum/ethereum.js/dev-status.svg
[dep-dev-url]: https://david-dm.org/ethereum/ethereum.js#info=devDependencies
[coveralls-image]: https://coveralls.io/repos/ethereum/ethereum.js/badge.svg?branch=master
[coveralls-url]: https://coveralls.io/r/ethereum/ethereum.js?branch=master

2
libjsqrc/ethereumjs/bower.json

@ -1,7 +1,7 @@
{
"name": "ethereum.js",
"namespace": "ethereum",
"version": "0.0.13",
"version": "0.0.15",
"description": "Ethereum Compatible JavaScript API",
"main": ["./dist/ethereum.js", "./dist/ethereum.min.js"],
"dependencies": {

701
libjsqrc/ethereumjs/dist/ethereum.js

@ -210,7 +210,7 @@ module.exports = {
};
},{"./const":2,"./formatters":6,"./types":11,"./utils":12,"./web3":13}],2:[function(require,module,exports){
},{"./const":2,"./formatters":8,"./types":14,"./utils":15,"./web3":17}],2:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -264,7 +264,8 @@ module.exports = {
ETH_PADDING: 32,
ETH_SIGNATURE_LENGTH: 4,
ETH_UNITS: ETH_UNITS,
ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN }
ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN },
ETH_POLLING_TIMEOUT: 1000
};
@ -295,6 +296,7 @@ var web3 = require('./web3');
var abi = require('./abi');
var utils = require('./utils');
var eventImpl = require('./event');
var filter = require('./filter');
var exportNatspecGlobals = function (vars) {
// it's used byt natspec.js
@ -416,11 +418,11 @@ var addEventsToContract = function (contract, desc, address) {
var signature = abi.eventSignatureFromAscii(e.name);
var event = eventImpl.inputParser(address, signature, e);
var o = event.apply(null, params);
o._onWatchEventResult = function (data) {
var outputFormatter = function (data) {
var parser = eventImpl.outputParser(e);
return parser(data);
};
return web3.eth.watch(o);
return web3.eth.watch(o, undefined, undefined, outputFormatter);
};
// this property should be used by eth.filter to check if object is an event
@ -487,7 +489,131 @@ var contract = function (address, desc) {
module.exports = contract;
},{"./abi":1,"./event":4,"./utils":12,"./web3":13}],4:[function(require,module,exports){
},{"./abi":1,"./event":6,"./filter":7,"./utils":15,"./web3":17}],4:[function(require,module,exports){
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file db.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
/// @returns an array of objects describing web3.db api methods
var methods = function () {
return [
{ name: 'put', call: 'db_put' },
{ name: 'get', call: 'db_get' },
{ name: 'putString', call: 'db_putString' },
{ name: 'getString', call: 'db_getString' }
];
};
module.exports = {
methods: methods
};
},{}],5:[function(require,module,exports){
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file eth.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
/// @returns an array of objects describing web3.eth api methods
var methods = function () {
var blockCall = function (args) {
return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
};
var transactionCall = function (args) {
return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';
};
var uncleCall = function (args) {
return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';
};
var transactionCountCall = function (args) {
return typeof args[0] === "string" ? 'eth_transactionCountByHash' : 'eth_transactionCountByNumber';
};
var uncleCountCall = function (args) {
return typeof args[0] === "string" ? 'eth_uncleCountByHash' : 'eth_uncleCountByNumber';
};
return [
{ name: 'balanceAt', call: 'eth_balanceAt' },
{ name: 'stateAt', call: 'eth_stateAt' },
{ name: 'storageAt', call: 'eth_storageAt' },
{ name: 'countAt', call: 'eth_countAt'},
{ name: 'codeAt', call: 'eth_codeAt' },
{ name: 'transact', call: 'eth_transact' },
{ name: 'call', call: 'eth_call' },
{ name: 'block', call: blockCall },
{ name: 'transaction', call: transactionCall },
{ name: 'uncle', call: uncleCall },
{ name: 'compilers', call: 'eth_compilers' },
{ name: 'flush', call: 'eth_flush' },
{ name: 'lll', call: 'eth_lll' },
{ name: 'solidity', call: 'eth_solidity' },
{ name: 'serpent', call: 'eth_serpent' },
{ name: 'logs', call: 'eth_logs' },
{ name: 'transactionCount', call: transactionCountCall },
{ name: 'uncleCount', call: uncleCountCall }
];
};
/// @returns an array of objects describing web3.eth api properties
var properties = function () {
return [
{ name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
{ name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
{ name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
{ name: 'gasPrice', getter: 'eth_gasPrice' },
{ name: 'accounts', getter: 'eth_accounts' },
{ name: 'peerCount', getter: 'eth_peerCount' },
{ name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
{ name: 'number', getter: 'eth_number'}
];
};
module.exports = {
methods: methods,
properties: properties
};
},{}],6:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -589,6 +715,7 @@ var outputParser = function (event) {
args: {}
};
output.topics = output.topic; // fallback for go-ethereum
if (!output.topic) {
return result;
}
@ -624,7 +751,7 @@ module.exports = {
};
},{"./abi":1,"./utils":12}],5:[function(require,module,exports){
},{"./abi":1,"./utils":15}],7:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -650,84 +777,96 @@ module.exports = {
* @date 2014
*/
var web3 = require('./web3'); // jshint ignore:line
/// should be used when we want to watch something
/// it's using inner polling mechanism and is notified about changes
/// TODO: change 'options' name cause it may be not the best matching one, since we have events
var Filter = function(options, impl) {
/// Should be called to check if filter implementation is valid
/// @returns true if it is, otherwise false
var implementationIsValid = function (i) {
return !!i &&
typeof i.newFilter === 'function' &&
typeof i.getMessages === 'function' &&
typeof i.uninstallFilter === 'function' &&
typeof i.startPolling === 'function' &&
typeof i.stopPolling === 'function';
};
/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones
/// @param should be string or object
/// @returns options string or object
var getOptions = function (options) {
if (typeof options === 'string') {
return options;
}
if (typeof options !== "string") {
options = options || {};
// topics property is deprecated, warn about it!
if (options.topics) {
console.warn('"topics" is deprecated, use "topic" instead');
}
if (options.topics) {
console.warn('"topics" is deprecated, is "topic" instead');
}
this._onWatchResult = options._onWatchEventResult;
// evaluate lazy properties
options = {
to: options.to,
topic: options.topic,
earliest: options.earliest,
latest: options.latest,
max: options.max,
skip: options.skip,
address: options.address
};
// evaluate lazy properties
return {
to: options.to,
topic: options.topic,
earliest: options.earliest,
latest: options.latest,
max: options.max,
skip: options.skip,
address: options.address
};
};
/// Should be used when we want to watch something
/// it's using inner polling mechanism and is notified about changes
/// @param options are filter options
/// @param implementation, an abstract polling implementation
/// @param formatter (optional), callback function which formats output before 'real' callback
var filter = function(options, implementation, formatter) {
if (!implementationIsValid(implementation)) {
console.error('filter implemenation is invalid');
return;
}
this.impl = impl;
this.callbacks = [];
this.id = impl.newFilter(options);
web3.provider.startPolling({method: impl.changed, params: [this.id]}, this.id, this.trigger.bind(this));
};
options = getOptions(options);
var callbacks = [];
var filterId = implementation.newFilter(options);
var onMessages = function (messages) {
messages.forEach(function (message) {
message = formatter ? formatter(message) : message;
callbacks.forEach(function (callback) {
callback(message);
});
});
};
/// alias for changed*
Filter.prototype.arrived = function(callback) {
this.changed(callback);
};
Filter.prototype.happened = function(callback) {
this.changed(callback);
};
implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);
/// gets called when there is new eth/shh message
Filter.prototype.changed = function(callback) {
this.callbacks.push(callback);
};
var changed = function (callback) {
callbacks.push(callback);
};
/// trigger calling new message from people
Filter.prototype.trigger = function(messages) {
for (var i = 0; i < this.callbacks.length; i++) {
for (var j = 0; j < messages.length; j++) {
var message = this._onWatchResult ? this._onWatchResult(messages[j]) : messages[j];
this.callbacks[i].call(this, message);
}
}
};
var messages = function () {
return implementation.getMessages(filterId);
};
/// should be called to uninstall current filter
Filter.prototype.uninstall = function() {
this.impl.uninstallFilter(this.id);
web3.provider.stopPolling(this.id);
};
var uninstall = function (callback) {
implementation.stopPolling(filterId);
implementation.uninstallFilter(filterId);
callbacks = [];
};
/// should be called to manually trigger getting latest messages from the client
Filter.prototype.messages = function() {
return this.impl.getMessages(this.id);
return {
changed: changed,
arrived: changed,
happened: changed,
messages: messages,
logs: messages,
uninstall: uninstall
};
};
/// alias for messages
Filter.prototype.logs = function () {
return this.messages();
};
module.exports = filter;
module.exports = Filter;
},{"./web3":13}],6:[function(require,module,exports){
},{}],8:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -883,7 +1022,7 @@ module.exports = {
};
},{"./const":2,"./utils":12}],7:[function(require,module,exports){
},{"./const":2,"./utils":15}],9:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -913,7 +1052,7 @@ if ("build" !== 'build') {/*
var HttpSyncProvider = function (host) {
this.handlers = [];
this.host = host || 'http://localhost:8080';
this.host = host || 'http://127.0.0.1:8080';
};
HttpSyncProvider.prototype.send = function (payload) {
@ -923,15 +1062,17 @@ HttpSyncProvider.prototype.send = function (payload) {
request.open('POST', this.host, false);
request.send(JSON.stringify(payload));
// check request.status
var result = request.responseText;
// check request.status
if(request.status !== 200)
return;
return JSON.parse(result);
};
module.exports = HttpSyncProvider;
},{}],8:[function(require,module,exports){
},{}],10:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -998,7 +1139,42 @@ module.exports = {
},{}],9:[function(require,module,exports){
},{}],11:[function(require,module,exports){
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file qtsync.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* @date 2014
*/
var QtSyncProvider = function () {
};
QtSyncProvider.prototype.send = function (payload) {
var result = navigator.qt.callMethod(JSON.stringify(payload));
return JSON.parse(result);
};
module.exports = QtSyncProvider;
},{}],12:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -1015,7 +1191,7 @@ module.exports = {
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file providermanager.js
/** @file requestmanager.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
@ -1024,85 +1200,86 @@ module.exports = {
* @date 2014
*/
var web3 = require('./web3');
var jsonrpc = require('./jsonrpc');
var c = require('./const');
/**
* Provider manager object prototype
* It's responsible for passing messages to providers
* If no provider is set it's responsible for queuing requests
* It's also responsible for polling the ethereum node for incoming messages
* Default poll timeout is 12 seconds
* If we are running ethereum.js inside ethereum browser, there are backend based tools responsible for polling,
* and provider manager polling mechanism is not used
* Default poll timeout is 1 second
*/
var ProviderManager = function() {
this.polls = [];
this.provider = undefined;
var requestManager = function() {
var polls = [];
var provider;
var self = this;
var poll = function () {
self.polls.forEach(function (data) {
var result = self.send(data.data);
var send = function (data) {
var payload = jsonrpc.toPayload(data.method, data.params);
if (!(result instanceof Array) || result.length === 0) {
return;
}
if (!provider) {
console.error('provider is not set');
return null;
}
data.callback(result);
});
var result = provider.send(payload);
setTimeout(poll, 1000);
};
poll();
};
if (!jsonrpc.isValidResponse(result)) {
console.log(result);
return null;
}
/// sends outgoing requests
/// @params data - an object with at least 'method' property
ProviderManager.prototype.send = function(data) {
var payload = jsonrpc.toPayload(data.method, data.params);
return result.result;
};
if (this.provider === undefined) {
console.error('provider is not set');
return null;
}
var setProvider = function (p) {
provider = p;
};
var result = this.provider.send(payload);
var startPolling = function (data, pollId, callback, uninstall) {
polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});
};
if (!jsonrpc.isValidResponse(result)) {
console.log(result);
return null;
}
var stopPolling = function (pollId) {
for (var i = polls.length; i--;) {
var poll = polls[i];
if (poll.id === pollId) {
polls.splice(i, 1);
}
}
};
return result.result;
};
var reset = function () {
polls.forEach(function (poll) {
poll.uninstall(poll.id);
});
polls = [];
};
/// setups provider, which will be used for sending messages
ProviderManager.prototype.set = function(provider) {
this.provider = provider;
};
var poll = function () {
polls.forEach(function (data) {
var result = send(data.data);
if (!(result instanceof Array) || result.length === 0) {
return;
}
data.callback(result);
});
setTimeout(poll, c.ETH_POLLING_TIMEOUT);
};
/// this method is only used, when we do not have native qt bindings and have to do polling on our own
/// should be callled, on start watching for eth/shh changes
ProviderManager.prototype.startPolling = function (data, pollId, callback) {
this.polls.push({data: data, id: pollId, callback: callback});
};
poll();
/// should be called to stop polling for certain watch changes
ProviderManager.prototype.stopPolling = function (pollId) {
for (var i = this.polls.length; i--;) {
var poll = this.polls[i];
if (poll.id === pollId) {
this.polls.splice(i, 1);
}
}
return {
send: send,
setProvider: setProvider,
startPolling: startPolling,
stopPolling: stopPolling,
reset: reset
};
};
module.exports = ProviderManager;
module.exports = requestManager;
},{"./jsonrpc":8,"./web3":13}],10:[function(require,module,exports){
},{"./const":2,"./jsonrpc":10}],13:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -1119,25 +1296,29 @@ module.exports = ProviderManager;
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file qtsync.js
/** @file shh.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* @date 2014
* @date 2015
*/
var QtSyncProvider = function () {
/// @returns an array of objects describing web3.shh api methods
var methods = function () {
return [
{ name: 'post', call: 'shh_post' },
{ name: 'newIdentity', call: 'shh_newIdentity' },
{ name: 'haveIdentity', call: 'shh_haveIdentity' },
{ name: 'newGroup', call: 'shh_newGroup' },
{ name: 'addToGroup', call: 'shh_addToGroup' }
];
};
QtSyncProvider.prototype.send = function (payload) {
var result = navigator.qt.callMethod(JSON.stringify(payload));
return JSON.parse(result);
module.exports = {
methods: methods
};
module.exports = QtSyncProvider;
},{}],11:[function(require,module,exports){
},{}],14:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -1218,7 +1399,7 @@ module.exports = {
};
},{"./formatters":6}],12:[function(require,module,exports){
},{"./formatters":8}],15:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -1362,7 +1543,7 @@ module.exports = {
};
},{"./const":2}],13:[function(require,module,exports){
},{"./const":2}],16:[function(require,module,exports){
/*
This file is part of ethereum.js.
@ -1379,100 +1560,14 @@ module.exports = {
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file web3.js
/** @file watches.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
* @date 2015
*/
if ("build" !== 'build') {/*
var BigNumber = require('bignumber.js');
*/}
var utils = require('./utils');
/// @returns an array of objects describing web3 api methods
var web3Methods = function () {
return [
{ name: 'sha3', call: 'web3_sha3' }
];
};
/// @returns an array of objects describing web3.eth api methods
var ethMethods = function () {
var blockCall = function (args) {
return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
};
var transactionCall = function (args) {
return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';
};
var uncleCall = function (args) {
return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';
};
var methods = [
{ name: 'balanceAt', call: 'eth_balanceAt' },
{ name: 'stateAt', call: 'eth_stateAt' },
{ name: 'storageAt', call: 'eth_storageAt' },
{ name: 'countAt', call: 'eth_countAt'},
{ name: 'codeAt', call: 'eth_codeAt' },
{ name: 'transact', call: 'eth_transact' },
{ name: 'call', call: 'eth_call' },
{ name: 'block', call: blockCall },
{ name: 'transaction', call: transactionCall },
{ name: 'uncle', call: uncleCall },
{ name: 'compilers', call: 'eth_compilers' },
{ name: 'flush', call: 'eth_flush' },
{ name: 'lll', call: 'eth_lll' },
{ name: 'solidity', call: 'eth_solidity' },
{ name: 'serpent', call: 'eth_serpent' },
{ name: 'logs', call: 'eth_logs' }
];
return methods;
};
/// @returns an array of objects describing web3.eth api properties
var ethProperties = function () {
return [
{ name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
{ name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
{ name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
{ name: 'gasPrice', getter: 'eth_gasPrice' },
{ name: 'accounts', getter: 'eth_accounts' },
{ name: 'peerCount', getter: 'eth_peerCount' },
{ name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
{ name: 'number', getter: 'eth_number'}
];
};
/// @returns an array of objects describing web3.db api methods
var dbMethods = function () {
return [
{ name: 'put', call: 'db_put' },
{ name: 'get', call: 'db_get' },
{ name: 'putString', call: 'db_putString' },
{ name: 'getString', call: 'db_getString' }
];
};
/// @returns an array of objects describing web3.shh api methods
var shhMethods = function () {
return [
{ name: 'post', call: 'shh_post' },
{ name: 'newIdentity', call: 'shh_newIdentity' },
{ name: 'haveIdentity', call: 'shh_haveIdentity' },
{ name: 'newGroup', call: 'shh_newGroup' },
{ name: 'addToGroup', call: 'shh_addToGroup' }
];
};
/// @returns an array of objects describing web3.eth.watch api methods
var ethWatchMethods = function () {
var eth = function () {
var newFilter = function (args) {
return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';
};
@ -1485,7 +1580,7 @@ var ethWatchMethods = function () {
};
/// @returns an array of objects describing web3.shh.watch api methods
var shhWatchMethods = function () {
var shh = function () {
return [
{ name: 'newFilter', call: 'shh_newFilter' },
{ name: 'uninstallFilter', call: 'shh_uninstallFilter' },
@ -1493,6 +1588,57 @@ var shhWatchMethods = function () {
];
};
module.exports = {
eth: eth,
shh: shh
};
},{}],17:[function(require,module,exports){
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file web3.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/
if ("build" !== 'build') {/*
var BigNumber = require('bignumber.js');
*/}
var eth = require('./eth');
var db = require('./db');
var shh = require('./shh');
var watches = require('./watches');
var filter = require('./filter');
var utils = require('./utils');
var requestManager = require('./requestmanager');
/// @returns an array of objects describing web3 api methods
var web3Methods = function () {
return [
{ name: 'sha3', call: 'web3_sha3' }
];
};
/// creates methods in a given object based on method description on input
/// setups api calls for these methods
var setupMethods = function (obj, methods) {
@ -1500,7 +1646,7 @@ var setupMethods = function (obj, methods) {
obj[method.name] = function () {
var args = Array.prototype.slice.call(arguments);
var call = typeof method.call === 'function' ? method.call(args) : method.call;
return web3.provider.send({
return web3.manager.send({
method: call,
params: args
});
@ -1514,14 +1660,14 @@ var setupProperties = function (obj, properties) {
properties.forEach(function (property) {
var proto = {};
proto.get = function () {
return web3.provider.send({
return web3.manager.send({
method: property.getter
});
};
if (property.setter) {
proto.set = function (val) {
return web3.provider.send({
return web3.manager.send({
method: property.setter,
params: [val]
});
@ -1531,10 +1677,30 @@ var setupProperties = function (obj, properties) {
});
};
var startPolling = function (method, id, callback, uninstall) {
web3.manager.startPolling({
method: method,
params: [id]
}, id, callback, uninstall);
};
var stopPolling = function (id) {
web3.manager.stopPolling(id);
};
var ethWatch = {
startPolling: startPolling.bind(null, 'eth_changed'),
stopPolling: stopPolling
};
var shhWatch = {
startPolling: startPolling.bind(null, 'shh_changed'),
stopPolling: stopPolling
};
/// setups web3 object, and it's in-browser executed methods
var web3 = {
_callbacks: {},
_events: {},
manager: requestManager(),
providers: {},
/// @returns ascii string representation of hex value prefixed with 0x
@ -1573,11 +1739,12 @@ var web3 = {
/// @param filter may be a string, object or event
/// @param indexed is optional, this is an object with optional event indexed params
/// @param options is optional, this is an object with optional event options ('max'...)
watch: function (filter, indexed, options) {
if (filter._isEvent) {
return filter(indexed, options);
/// TODO: fix it, 4 params? no way
watch: function (fil, indexed, options, formatter) {
if (fil._isEvent) {
return fil(indexed, options);
}
return new web3.filter(filter, ethWatch);
return filter(fil, ethWatch, formatter);
}
},
@ -1586,54 +1753,44 @@ var web3 = {
/// shh object prototype
shh: {
/// @param filter may be a string, object or event
watch: function (filter, indexed) {
return new web3.filter(filter, shhWatch);
watch: function (fil) {
return filter(fil, shhWatch);
}
},
setProvider: function (provider) {
web3.manager.setProvider(provider);
},
/// Should be called to reset state of web3 object
/// Resets everything except manager
reset: function () {
web3.manager.reset();
}
};
/// setups all api methods
setupMethods(web3, web3Methods());
setupMethods(web3.eth, ethMethods());
setupProperties(web3.eth, ethProperties());
setupMethods(web3.db, dbMethods());
setupMethods(web3.shh, shhMethods());
var ethWatch = {
changed: 'eth_changed'
};
setupMethods(ethWatch, ethWatchMethods());
var shhWatch = {
changed: 'shh_changed'
};
setupMethods(shhWatch, shhWatchMethods());
web3.setProvider = function(provider) {
web3.provider.set(provider);
};
setupMethods(web3.eth, eth.methods());
setupProperties(web3.eth, eth.properties());
setupMethods(web3.db, db.methods());
setupMethods(web3.shh, shh.methods());
setupMethods(ethWatch, watches.eth());
setupMethods(shhWatch, watches.shh());
module.exports = web3;
},{"./utils":12}],"web3":[function(require,module,exports){
},{"./db":4,"./eth":5,"./filter":7,"./requestmanager":12,"./shh":13,"./utils":15,"./watches":16}],"web3":[function(require,module,exports){
var web3 = require('./lib/web3');
var ProviderManager = require('./lib/providermanager');
web3.provider = new ProviderManager();
web3.filter = require('./lib/filter');
web3.providers.HttpSyncProvider = require('./lib/httpsync');
web3.providers.QtSyncProvider = require('./lib/qtsync');
web3.eth.contract = require('./lib/contract');
web3.abi = require('./lib/abi');
module.exports = web3;
},{"./lib/abi":1,"./lib/contract":3,"./lib/filter":5,"./lib/httpsync":7,"./lib/providermanager":9,"./lib/qtsync":10,"./lib/web3":13}]},{},["web3"])
},{"./lib/abi":1,"./lib/contract":3,"./lib/httpsync":9,"./lib/qtsync":11,"./lib/web3":17}]},{},["web3"])
//# sourceMappingURL=ethereum.js.map

28
libjsqrc/ethereumjs/dist/ethereum.js.map

File diff suppressed because one or more lines are too long

2
libjsqrc/ethereumjs/dist/ethereum.min.js

File diff suppressed because one or more lines are too long

97
libjsqrc/ethereumjs/gulpfile.js

@ -15,90 +15,55 @@ var unreach = require('unreachable-branch-transform');
var source = require('vinyl-source-stream');
var exorcist = require('exorcist');
var bower = require('bower');
var streamify = require('gulp-streamify');
var DEST = './dist/';
var build = function(src, dst, ugly) {
var result = browserify({
debug: true,
insert_global_vars: false,
detectGlobals: false,
bundleExternal: false
})
.require('./' + src + '.js', {expose: 'web3'})
.add('./' + src + '.js')
.transform('envify', {
NODE_ENV: 'build'
})
.transform('unreachable-branch-transform');
if (ugly) {
result = result.transform('uglifyify', {
mangle: false,
compress: {
dead_code: false,
conditionals: true,
unused: false,
hoist_funs: true,
hoist_vars: true,
negate_iife: false
},
beautify: true,
warnings: true
});
}
return result.bundle()
.pipe(exorcist(path.join( DEST, dst + '.js.map')))
.pipe(source(dst + '.js'))
.pipe(gulp.dest( DEST ));
};
var uglifyFile = function(file) {
return gulp.src( DEST + file + '.js')
.pipe(uglify())
.pipe(rename(file + '.min.js'))
.pipe(gulp.dest( DEST ));
var src = 'index';
var dst = 'ethereum';
var browserifyOptions = {
debug: true,
insert_global_vars: false,
detectGlobals: false,
bundleExternal: false
};
gulp.task('bower', function(cb){
bower.commands.install().on('end', function (installed){
console.log(installed);
cb();
});
bower.commands.install().on('end', function (installed){
console.log(installed);
cb();
});
});
gulp.task('clean', ['lint'], function(cb) {
del([ DEST ], cb);
del([ DEST ], cb);
});
gulp.task('lint', function(){
return gulp.src(['./*.js', './lib/*.js'])
.pipe(jshint())
.pipe(jshint.reporter('default'));
return gulp.src(['./*.js', './lib/*.js'])
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
gulp.task('build', ['clean'], function () {
return build('index', 'ethereum', true);
});
gulp.task('buildDev', ['clean'], function () {
return build('index', 'ethereum', false);
});
gulp.task('uglify', ['build'], function(){
return uglifyFile('ethereum');
});
gulp.task('uglifyDev', ['buildDev'], function(){
return uglifyFile('ethereum');
return browserify(browserifyOptions)
.require('./' + src + '.js', {expose: 'web3'})
.add('./' + src + '.js')
.transform('envify', { NODE_ENV: 'build' })
.transform('unreachable-branch-transform')
.bundle()
.pipe(exorcist(path.join( DEST, dst + '.js.map')))
.pipe(source(dst + '.js'))
.pipe(gulp.dest( DEST ))
.pipe(streamify(uglify()))
.pipe(rename(dst + '.min.js'))
.pipe(gulp.dest( DEST ));
});
gulp.task('watch', function() {
gulp.watch(['./lib/*.js'], ['lint', 'prepare', 'build']);
gulp.watch(['./lib/*.js'], ['lint', 'build']);
});
gulp.task('release', ['bower', 'lint', 'build', 'uglify']);
gulp.task('dev', ['bower', 'lint', 'buildDev', 'uglifyDev']);
gulp.task('dev', ['bower', 'lint', 'build']);
gulp.task('default', ['dev']);

4
libjsqrc/ethereumjs/index.js

@ -1,11 +1,7 @@
var web3 = require('./lib/web3');
var ProviderManager = require('./lib/providermanager');
web3.provider = new ProviderManager();
web3.filter = require('./lib/filter');
web3.providers.HttpSyncProvider = require('./lib/httpsync');
web3.providers.QtSyncProvider = require('./lib/qtsync');
web3.eth.contract = require('./lib/contract');
web3.abi = require('./lib/abi');
module.exports = web3;

3
libjsqrc/ethereumjs/lib/const.js

@ -51,6 +51,7 @@ module.exports = {
ETH_PADDING: 32,
ETH_SIGNATURE_LENGTH: 4,
ETH_UNITS: ETH_UNITS,
ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN }
ETH_BIGNUMBER_ROUNDING_MODE: { ROUNDING_MODE: BigNumber.ROUND_DOWN },
ETH_POLLING_TIMEOUT: 1000
};

5
libjsqrc/ethereumjs/lib/contract.js

@ -24,6 +24,7 @@ var web3 = require('./web3');
var abi = require('./abi');
var utils = require('./utils');
var eventImpl = require('./event');
var filter = require('./filter');
var exportNatspecGlobals = function (vars) {
// it's used byt natspec.js
@ -145,11 +146,11 @@ var addEventsToContract = function (contract, desc, address) {
var signature = abi.eventSignatureFromAscii(e.name);
var event = eventImpl.inputParser(address, signature, e);
var o = event.apply(null, params);
o._onWatchEventResult = function (data) {
var outputFormatter = function (data) {
var parser = eventImpl.outputParser(e);
return parser(data);
};
return web3.eth.watch(o);
return web3.eth.watch(o, undefined, undefined, outputFormatter);
};
// this property should be used by eth.filter to check if object is an event

35
libjsqrc/ethereumjs/lib/db.js

@ -0,0 +1,35 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file db.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
/// @returns an array of objects describing web3.db api methods
var methods = function () {
return [
{ name: 'put', call: 'db_put' },
{ name: 'get', call: 'db_get' },
{ name: 'putString', call: 'db_putString' },
{ name: 'getString', call: 'db_getString' }
];
};
module.exports = {
methods: methods
};

85
libjsqrc/ethereumjs/lib/eth.js

@ -0,0 +1,85 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file eth.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
/// @returns an array of objects describing web3.eth api methods
var methods = function () {
var blockCall = function (args) {
return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
};
var transactionCall = function (args) {
return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';
};
var uncleCall = function (args) {
return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';
};
var transactionCountCall = function (args) {
return typeof args[0] === "string" ? 'eth_transactionCountByHash' : 'eth_transactionCountByNumber';
};
var uncleCountCall = function (args) {
return typeof args[0] === "string" ? 'eth_uncleCountByHash' : 'eth_uncleCountByNumber';
};
return [
{ name: 'balanceAt', call: 'eth_balanceAt' },
{ name: 'stateAt', call: 'eth_stateAt' },
{ name: 'storageAt', call: 'eth_storageAt' },
{ name: 'countAt', call: 'eth_countAt'},
{ name: 'codeAt', call: 'eth_codeAt' },
{ name: 'transact', call: 'eth_transact' },
{ name: 'call', call: 'eth_call' },
{ name: 'block', call: blockCall },
{ name: 'transaction', call: transactionCall },
{ name: 'uncle', call: uncleCall },
{ name: 'compilers', call: 'eth_compilers' },
{ name: 'flush', call: 'eth_flush' },
{ name: 'lll', call: 'eth_lll' },
{ name: 'solidity', call: 'eth_solidity' },
{ name: 'serpent', call: 'eth_serpent' },
{ name: 'logs', call: 'eth_logs' },
{ name: 'transactionCount', call: transactionCountCall },
{ name: 'uncleCount', call: uncleCountCall }
];
};
/// @returns an array of objects describing web3.eth api properties
var properties = function () {
return [
{ name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
{ name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
{ name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
{ name: 'gasPrice', getter: 'eth_gasPrice' },
{ name: 'accounts', getter: 'eth_accounts' },
{ name: 'peerCount', getter: 'eth_peerCount' },
{ name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
{ name: 'number', getter: 'eth_number'}
];
};
module.exports = {
methods: methods,
properties: properties
};

1
libjsqrc/ethereumjs/lib/event.js

@ -99,6 +99,7 @@ var outputParser = function (event) {
args: {}
};
output.topics = output.topic; // fallback for go-ethereum
if (!output.topic) {
return result;
}

140
libjsqrc/ethereumjs/lib/filter.js

@ -23,79 +23,91 @@
* @date 2014
*/
var web3 = require('./web3'); // jshint ignore:line
/// should be used when we want to watch something
/// it's using inner polling mechanism and is notified about changes
/// TODO: change 'options' name cause it may be not the best matching one, since we have events
var Filter = function(options, impl) {
if (typeof options !== "string") {
// topics property is deprecated, warn about it!
if (options.topics) {
console.warn('"topics" is deprecated, use "topic" instead');
}
this._onWatchResult = options._onWatchEventResult;
// evaluate lazy properties
options = {
to: options.to,
topic: options.topic,
earliest: options.earliest,
latest: options.latest,
max: options.max,
skip: options.skip,
address: options.address
};
/// Should be called to check if filter implementation is valid
/// @returns true if it is, otherwise false
var implementationIsValid = function (i) {
return !!i &&
typeof i.newFilter === 'function' &&
typeof i.getMessages === 'function' &&
typeof i.uninstallFilter === 'function' &&
typeof i.startPolling === 'function' &&
typeof i.stopPolling === 'function';
};
/// This method should be called on options object, to verify deprecated properties && lazy load dynamic ones
/// @param should be string or object
/// @returns options string or object
var getOptions = function (options) {
if (typeof options === 'string') {
return options;
}
this.impl = impl;
this.callbacks = [];
this.id = impl.newFilter(options);
web3.provider.startPolling({method: impl.changed, params: [this.id]}, this.id, this.trigger.bind(this));
};
options = options || {};
/// alias for changed*
Filter.prototype.arrived = function(callback) {
this.changed(callback);
};
Filter.prototype.happened = function(callback) {
this.changed(callback);
};
if (options.topics) {
console.warn('"topics" is deprecated, is "topic" instead');
}
/// gets called when there is new eth/shh message
Filter.prototype.changed = function(callback) {
this.callbacks.push(callback);
// evaluate lazy properties
return {
to: options.to,
topic: options.topic,
earliest: options.earliest,
latest: options.latest,
max: options.max,
skip: options.skip,
address: options.address
};
};
/// trigger calling new message from people
Filter.prototype.trigger = function(messages) {
for (var i = 0; i < this.callbacks.length; i++) {
for (var j = 0; j < messages.length; j++) {
var message = this._onWatchResult ? this._onWatchResult(messages[j]) : messages[j];
this.callbacks[i].call(this, message);
}
/// Should be used when we want to watch something
/// it's using inner polling mechanism and is notified about changes
/// @param options are filter options
/// @param implementation, an abstract polling implementation
/// @param formatter (optional), callback function which formats output before 'real' callback
var filter = function(options, implementation, formatter) {
if (!implementationIsValid(implementation)) {
console.error('filter implemenation is invalid');
return;
}
};
/// should be called to uninstall current filter
Filter.prototype.uninstall = function() {
this.impl.uninstallFilter(this.id);
web3.provider.stopPolling(this.id);
};
/// should be called to manually trigger getting latest messages from the client
Filter.prototype.messages = function() {
return this.impl.getMessages(this.id);
options = getOptions(options);
var callbacks = [];
var filterId = implementation.newFilter(options);
var onMessages = function (messages) {
messages.forEach(function (message) {
message = formatter ? formatter(message) : message;
callbacks.forEach(function (callback) {
callback(message);
});
});
};
implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);
var changed = function (callback) {
callbacks.push(callback);
};
var messages = function () {
return implementation.getMessages(filterId);
};
var uninstall = function (callback) {
implementation.stopPolling(filterId);
implementation.uninstallFilter(filterId);
callbacks = [];
};
return {
changed: changed,
arrived: changed,
happened: changed,
messages: messages,
logs: messages,
uninstall: uninstall
};
};
/// alias for messages
Filter.prototype.logs = function () {
return this.messages();
};
module.exports = filter;
module.exports = Filter;

6
libjsqrc/ethereumjs/lib/httpsync.js

@ -27,7 +27,7 @@ if (process.env.NODE_ENV !== 'build') {
var HttpSyncProvider = function (host) {
this.handlers = [];
this.host = host || 'http://localhost:8080';
this.host = host || 'http://127.0.0.1:8080';
};
HttpSyncProvider.prototype.send = function (payload) {
@ -37,8 +37,10 @@ HttpSyncProvider.prototype.send = function (payload) {
request.open('POST', this.host, false);
request.send(JSON.stringify(payload));
// check request.status
var result = request.responseText;
// check request.status
if(request.status !== 200)
return;
return JSON.parse(result);
};

102
libjsqrc/ethereumjs/lib/providermanager.js

@ -1,102 +0,0 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file providermanager.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/
var web3 = require('./web3');
var jsonrpc = require('./jsonrpc');
/**
* Provider manager object prototype
* It's responsible for passing messages to providers
* If no provider is set it's responsible for queuing requests
* It's also responsible for polling the ethereum node for incoming messages
* Default poll timeout is 12 seconds
* If we are running ethereum.js inside ethereum browser, there are backend based tools responsible for polling,
* and provider manager polling mechanism is not used
*/
var ProviderManager = function() {
this.polls = [];
this.provider = undefined;
var self = this;
var poll = function () {
self.polls.forEach(function (data) {
var result = self.send(data.data);
if (!(result instanceof Array) || result.length === 0) {
return;
}
data.callback(result);
});
setTimeout(poll, 1000);
};
poll();
};
/// sends outgoing requests
/// @params data - an object with at least 'method' property
ProviderManager.prototype.send = function(data) {
var payload = jsonrpc.toPayload(data.method, data.params);
if (this.provider === undefined) {
console.error('provider is not set');
return null;
}
var result = this.provider.send(payload);
if (!jsonrpc.isValidResponse(result)) {
console.log(result);
return null;
}
return result.result;
};
/// setups provider, which will be used for sending messages
ProviderManager.prototype.set = function(provider) {
this.provider = provider;
};
/// this method is only used, when we do not have native qt bindings and have to do polling on our own
/// should be callled, on start watching for eth/shh changes
ProviderManager.prototype.startPolling = function (data, pollId, callback) {
this.polls.push({data: data, id: pollId, callback: callback});
};
/// should be called to stop polling for certain watch changes
ProviderManager.prototype.stopPolling = function (pollId) {
for (var i = this.polls.length; i--;) {
var poll = this.polls[i];
if (poll.id === pollId) {
this.polls.splice(i, 1);
}
}
};
module.exports = ProviderManager;

103
libjsqrc/ethereumjs/lib/requestmanager.js

@ -0,0 +1,103 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file requestmanager.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* Gav Wood <g@ethdev.com>
* @date 2014
*/
var jsonrpc = require('./jsonrpc');
var c = require('./const');
/**
* It's responsible for passing messages to providers
* It's also responsible for polling the ethereum node for incoming messages
* Default poll timeout is 1 second
*/
var requestManager = function() {
var polls = [];
var provider;
var send = function (data) {
var payload = jsonrpc.toPayload(data.method, data.params);
if (!provider) {
console.error('provider is not set');
return null;
}
var result = provider.send(payload);
if (!jsonrpc.isValidResponse(result)) {
console.log(result);
return null;
}
return result.result;
};
var setProvider = function (p) {
provider = p;
};
var startPolling = function (data, pollId, callback, uninstall) {
polls.push({data: data, id: pollId, callback: callback, uninstall: uninstall});
};
var stopPolling = function (pollId) {
for (var i = polls.length; i--;) {
var poll = polls[i];
if (poll.id === pollId) {
polls.splice(i, 1);
}
}
};
var reset = function () {
polls.forEach(function (poll) {
poll.uninstall(poll.id);
});
polls = [];
};
var poll = function () {
polls.forEach(function (data) {
var result = send(data.data);
if (!(result instanceof Array) || result.length === 0) {
return;
}
data.callback(result);
});
setTimeout(poll, c.ETH_POLLING_TIMEOUT);
};
poll();
return {
send: send,
setProvider: setProvider,
startPolling: startPolling,
stopPolling: stopPolling,
reset: reset
};
};
module.exports = requestManager;

37
libjsqrc/ethereumjs/lib/shh.js

@ -0,0 +1,37 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file shh.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
/// @returns an array of objects describing web3.shh api methods
var methods = function () {
return [
{ name: 'post', call: 'shh_post' },
{ name: 'newIdentity', call: 'shh_newIdentity' },
{ name: 'haveIdentity', call: 'shh_haveIdentity' },
{ name: 'newGroup', call: 'shh_newGroup' },
{ name: 'addToGroup', call: 'shh_addToGroup' }
];
};
module.exports = {
methods: methods
};

49
libjsqrc/ethereumjs/lib/watches.js

@ -0,0 +1,49 @@
/*
This file is part of ethereum.js.
ethereum.js is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
ethereum.js 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file watches.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
/// @returns an array of objects describing web3.eth.watch api methods
var eth = function () {
var newFilter = function (args) {
return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';
};
return [
{ name: 'newFilter', call: newFilter },
{ name: 'uninstallFilter', call: 'eth_uninstallFilter' },
{ name: 'getMessages', call: 'eth_filterLogs' }
];
};
/// @returns an array of objects describing web3.shh.watch api methods
var shh = function () {
return [
{ name: 'newFilter', call: 'shh_newFilter' },
{ name: 'uninstallFilter', call: 'shh_uninstallFilter' },
{ name: 'getMessages', call: 'shh_getMessages' }
];
};
module.exports = {
eth: eth,
shh: shh
};

177
libjsqrc/ethereumjs/lib/web3.js

@ -27,7 +27,13 @@ if (process.env.NODE_ENV !== 'build') {
var BigNumber = require('bignumber.js');
}
var eth = require('./eth');
var db = require('./db');
var shh = require('./shh');
var watches = require('./watches');
var filter = require('./filter');
var utils = require('./utils');
var requestManager = require('./requestmanager');
/// @returns an array of objects describing web3 api methods
var web3Methods = function () {
@ -36,98 +42,6 @@ var web3Methods = function () {
];
};
/// @returns an array of objects describing web3.eth api methods
var ethMethods = function () {
var blockCall = function (args) {
return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
};
var transactionCall = function (args) {
return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';
};
var uncleCall = function (args) {
return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';
};
var methods = [
{ name: 'balanceAt', call: 'eth_balanceAt' },
{ name: 'stateAt', call: 'eth_stateAt' },
{ name: 'storageAt', call: 'eth_storageAt' },
{ name: 'countAt', call: 'eth_countAt'},
{ name: 'codeAt', call: 'eth_codeAt' },
{ name: 'transact', call: 'eth_transact' },
{ name: 'call', call: 'eth_call' },
{ name: 'block', call: blockCall },
{ name: 'transaction', call: transactionCall },
{ name: 'uncle', call: uncleCall },
{ name: 'compilers', call: 'eth_compilers' },
{ name: 'flush', call: 'eth_flush' },
{ name: 'lll', call: 'eth_lll' },
{ name: 'solidity', call: 'eth_solidity' },
{ name: 'serpent', call: 'eth_serpent' },
{ name: 'logs', call: 'eth_logs' }
];
return methods;
};
/// @returns an array of objects describing web3.eth api properties
var ethProperties = function () {
return [
{ name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
{ name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
{ name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
{ name: 'gasPrice', getter: 'eth_gasPrice' },
{ name: 'accounts', getter: 'eth_accounts' },
{ name: 'peerCount', getter: 'eth_peerCount' },
{ name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
{ name: 'number', getter: 'eth_number'}
];
};
/// @returns an array of objects describing web3.db api methods
var dbMethods = function () {
return [
{ name: 'put', call: 'db_put' },
{ name: 'get', call: 'db_get' },
{ name: 'putString', call: 'db_putString' },
{ name: 'getString', call: 'db_getString' }
];
};
/// @returns an array of objects describing web3.shh api methods
var shhMethods = function () {
return [
{ name: 'post', call: 'shh_post' },
{ name: 'newIdentity', call: 'shh_newIdentity' },
{ name: 'haveIdentity', call: 'shh_haveIdentity' },
{ name: 'newGroup', call: 'shh_newGroup' },
{ name: 'addToGroup', call: 'shh_addToGroup' }
];
};
/// @returns an array of objects describing web3.eth.watch api methods
var ethWatchMethods = function () {
var newFilter = function (args) {
return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';
};
return [
{ name: 'newFilter', call: newFilter },
{ name: 'uninstallFilter', call: 'eth_uninstallFilter' },
{ name: 'getMessages', call: 'eth_filterLogs' }
];
};
/// @returns an array of objects describing web3.shh.watch api methods
var shhWatchMethods = function () {
return [
{ name: 'newFilter', call: 'shh_newFilter' },
{ name: 'uninstallFilter', call: 'shh_uninstallFilter' },
{ name: 'getMessages', call: 'shh_getMessages' }
];
};
/// creates methods in a given object based on method description on input
/// setups api calls for these methods
var setupMethods = function (obj, methods) {
@ -135,7 +49,7 @@ var setupMethods = function (obj, methods) {
obj[method.name] = function () {
var args = Array.prototype.slice.call(arguments);
var call = typeof method.call === 'function' ? method.call(args) : method.call;
return web3.provider.send({
return web3.manager.send({
method: call,
params: args
});
@ -149,14 +63,14 @@ var setupProperties = function (obj, properties) {
properties.forEach(function (property) {
var proto = {};
proto.get = function () {
return web3.provider.send({
return web3.manager.send({
method: property.getter
});
};
if (property.setter) {
proto.set = function (val) {
return web3.provider.send({
return web3.manager.send({
method: property.setter,
params: [val]
});
@ -166,10 +80,30 @@ var setupProperties = function (obj, properties) {
});
};
var startPolling = function (method, id, callback, uninstall) {
web3.manager.startPolling({
method: method,
params: [id]
}, id, callback, uninstall);
};
var stopPolling = function (id) {
web3.manager.stopPolling(id);
};
var ethWatch = {
startPolling: startPolling.bind(null, 'eth_changed'),
stopPolling: stopPolling
};
var shhWatch = {
startPolling: startPolling.bind(null, 'shh_changed'),
stopPolling: stopPolling
};
/// setups web3 object, and it's in-browser executed methods
var web3 = {
_callbacks: {},
_events: {},
manager: requestManager(),
providers: {},
/// @returns ascii string representation of hex value prefixed with 0x
@ -208,11 +142,12 @@ var web3 = {
/// @param filter may be a string, object or event
/// @param indexed is optional, this is an object with optional event indexed params
/// @param options is optional, this is an object with optional event options ('max'...)
watch: function (filter, indexed, options) {
if (filter._isEvent) {
return filter(indexed, options);
/// TODO: fix it, 4 params? no way
watch: function (fil, indexed, options, formatter) {
if (fil._isEvent) {
return fil(indexed, options);
}
return new web3.filter(filter, ethWatch);
return filter(fil, ethWatch, formatter);
}
},
@ -221,36 +156,30 @@ var web3 = {
/// shh object prototype
shh: {
/// @param filter may be a string, object or event
watch: function (filter, indexed) {
return new web3.filter(filter, shhWatch);
watch: function (fil) {
return filter(fil, shhWatch);
}
},
setProvider: function (provider) {
web3.manager.setProvider(provider);
},
/// Should be called to reset state of web3 object
/// Resets everything except manager
reset: function () {
web3.manager.reset();
}
};
/// setups all api methods
setupMethods(web3, web3Methods());
setupMethods(web3.eth, ethMethods());
setupProperties(web3.eth, ethProperties());
setupMethods(web3.db, dbMethods());
setupMethods(web3.shh, shhMethods());
var ethWatch = {
changed: 'eth_changed'
};
setupMethods(ethWatch, ethWatchMethods());
var shhWatch = {
changed: 'shh_changed'
};
setupMethods(shhWatch, shhWatchMethods());
web3.setProvider = function(provider) {
web3.provider.set(provider);
};
setupMethods(web3.eth, eth.methods());
setupProperties(web3.eth, eth.properties());
setupMethods(web3.db, db.methods());
setupMethods(web3.shh, shh.methods());
setupMethods(ethWatch, watches.eth());
setupMethods(shhWatch, watches.shh());
module.exports = web3;

18
libjsqrc/ethereumjs/package.json

@ -1,38 +1,42 @@
{
"name": "ethereum.js",
"namespace": "ethereum",
"version": "0.0.13",
"version": "0.0.15",
"description": "Ethereum Compatible JavaScript API",
"main": "./index.js",
"directories": {
"lib": "./lib"
},
"dependencies": {
"bignumber.js": ">=2.0.0",
"ws": "*",
"xmlhttprequest": "*",
"bignumber.js": ">=2.0.0"
"xmlhttprequest": "*"
},
"devDependencies": {
"bower": ">=1.3.0",
"browserify": ">=6.0",
"coveralls": "^2.11.2",
"del": ">=0.1.1",
"envify": "^3.0.0",
"exorcist": "^0.1.6",
"gulp": ">=3.4.0",
"gulp-jshint": ">=1.5.0",
"gulp-rename": ">=1.2.0",
"gulp-streamify": "0.0.5",
"gulp-uglify": ">=1.0.0",
"istanbul": "^0.3.5",
"jshint": ">=2.5.0",
"uglifyify": "^2.6.0",
"mocha": ">=2.1.0",
"mocha-lcov-reporter": "0.0.1",
"unreachable-branch-transform": "^0.1.0",
"vinyl-source-stream": "^1.0.0",
"mocha": ">=2.1.0"
"vinyl-source-stream": "^1.0.0"
},
"scripts": {
"build": "gulp",
"watch": "gulp watch",
"lint": "gulp lint",
"test": "mocha"
"test": "mocha",
"test-coveralls": "istanbul cover _mocha -- -R spec && cat coverage/lcov.info | coveralls --verbose"
},
"repository": {
"type": "git",

2
libjsqrc/ethereumjs/test/eth.methods.js

@ -19,6 +19,8 @@ describe('web3', function() {
u.methodExists(web3.eth, 'solidity');
u.methodExists(web3.eth, 'serpent');
u.methodExists(web3.eth, 'logs');
u.methodExists(web3.eth, 'transactionCount');
u.methodExists(web3.eth, 'uncleCount');
u.propertyExists(web3.eth, 'coinbase');
u.propertyExists(web3.eth, 'listening');

27
libjsqrc/ethereumjs/test/filter.methods.js

@ -0,0 +1,27 @@
var assert = require('assert');
var filter = require('../lib/filter');
var u = require('./test.utils.js');
var empty = function () {};
var implementation = {
newFilter: empty,
getMessages: empty,
uninstallFilter: empty,
startPolling: empty,
stopPolling: empty,
};
describe('web3', function () {
describe('eth', function () {
describe('filter', function () {
var f = filter({}, implementation);
u.methodExists(f, 'arrived');
u.methodExists(f, 'happened');
u.methodExists(f, 'changed');
u.methodExists(f, 'messages');
u.methodExists(f, 'logs');
u.methodExists(f, 'uninstall');
});
});
});

11
libjsqrc/ethereumjs/test/web3.methods.js

@ -6,5 +6,16 @@ describe('web3', function() {
u.methodExists(web3, 'sha3');
u.methodExists(web3, 'toAscii');
u.methodExists(web3, 'fromAscii');
u.methodExists(web3, 'toDecimal');
u.methodExists(web3, 'fromDecimal');
u.methodExists(web3, 'toEth');
u.methodExists(web3, 'setProvider');
u.methodExists(web3, 'reset');
u.propertyExists(web3, 'manager');
u.propertyExists(web3, 'providers');
u.propertyExists(web3, 'eth');
u.propertyExists(web3, 'db');
u.propertyExists(web3, 'shh');
});

26
libp2p/Host.cpp

@ -630,6 +630,9 @@ void Host::disconnectLatePeers()
bytes Host::saveNetwork() const
{
if (!m_nodeTable)
return bytes();
std::list<Peer> peers;
{
RecursiveGuard l(x_sessions);
@ -665,17 +668,20 @@ bytes Host::saveNetwork() const
}
}
auto state = m_nodeTable->snapshot();
state.sort();
for (auto const& s: state)
if (!!m_nodeTable)
{
network.appendList(3);
if (s.endpoint.tcp.address().is_v4())
network << s.endpoint.tcp.address().to_v4().to_bytes();
else
network << s.endpoint.tcp.address().to_v6().to_bytes();
network << s.endpoint.tcp.port() << s.id;
count++;
auto state = m_nodeTable->snapshot();
state.sort();
for (auto const& s: state)
{
network.appendList(3);
if (s.endpoint.tcp.address().is_v4())
network << s.endpoint.tcp.address().to_v4().to_bytes();
else
network << s.endpoint.tcp.address().to_v6().to_bytes();
network << s.endpoint.tcp.port() << s.id;
count++;
}
}
RLPStream ret(3);

6
libp2p/UDP.cpp

@ -38,9 +38,9 @@ h256 RLPXDatagramFace::sign(Secret const& _k)
Signature sig = dev::sign(_k, sighash); // S(H(type||data))
data.resize(h256::size + Signature::size + rlpx.size());
bytesConstRef rlpxHash(&data[0], h256::size);
bytesConstRef rlpxSig(&data[h256::size], Signature::size);
bytesConstRef rlpxPayload(&data[h256::size + Signature::size], rlpx.size());
bytesRef rlpxHash(&data[0], h256::size);
bytesRef rlpxSig(&data[h256::size], Signature::size);
bytesRef rlpxPayload(&data[h256::size + Signature::size], rlpx.size());
sig.ref().copyTo(rlpxSig);
rlpx.copyTo(rlpxPayload);

41
libsolidity/AST.cpp

@ -77,6 +77,9 @@ void ContractDefinition::checkTypeRequirements()
for (ASTPointer<FunctionDefinition> const& function: getDefinedFunctions())
function->checkTypeRequirements();
for (ASTPointer<VariableDeclaration> const& variable: m_stateVariables)
variable->checkTypeRequirements();
// check for hash collisions in function signatures
set<FixedHash<4>> hashes;
for (auto const& it: getInterfaceFunctionList())
@ -274,15 +277,6 @@ TypePointer FunctionDefinition::getType(ContractDefinition const*) const
void FunctionDefinition::checkTypeRequirements()
{
// change all byte arrays parameters to point to calldata
if (getVisibility() == Visibility::External)
for (ASTPointer<VariableDeclaration> const& var: getParameters())
{
auto const& type = var->getType();
solAssert(!!type, "");
if (auto const* byteArrayType = dynamic_cast<ByteArrayType const*>(type.get()))
var->setType(byteArrayType->copyForLocation(ByteArrayType::Location::CallData));
}
for (ASTPointer<VariableDeclaration> const& var: getParameters() + getReturnParameters())
if (!var->getType()->canLiveOutsideStorage())
BOOST_THROW_EXCEPTION(var->createTypeError("Type is required to live outside storage."));
@ -299,16 +293,20 @@ string FunctionDefinition::getCanonicalSignature() const
bool VariableDeclaration::isLValue() const
{
if (auto const* function = dynamic_cast<FunctionDefinition const*>(getScope()))
if (function->getVisibility() == Declaration::Visibility::External && isFunctionParameter())
return false;
return true;
// External function parameters are Read-Only
return !isExternalFunctionParameter();
}
bool VariableDeclaration::isFunctionParameter() const
void VariableDeclaration::checkTypeRequirements()
{
if (m_value)
m_value->checkTypeRequirements();
}
bool VariableDeclaration::isExternalFunctionParameter() const
{
auto const* function = dynamic_cast<FunctionDefinition const*>(getScope());
if (!function)
if (!function || function->getVisibility() != Declaration::Visibility::External)
return false;
for (auto const& variable: function->getParameters())
if (variable.get() == this)
@ -401,26 +399,26 @@ void Return::checkTypeRequirements()
m_expression->expectType(*m_returnParameters->getParameters().front()->getType());
}
void VariableDefinition::checkTypeRequirements()
void VariableDeclarationStatement::checkTypeRequirements()
{
// Variables can be declared without type (with "var"), in which case the first assignment
// sets the type.
// Note that assignments before the first declaration are legal because of the special scoping
// rules inherited from JavaScript.
if (m_value)
if (m_variable->getValue())
{
if (m_variable->getType())
m_value->expectType(*m_variable->getType());
m_variable->getValue()->expectType(*m_variable->getType());
else
{
// no type declared and no previous assignment, infer the type
m_value->checkTypeRequirements();
TypePointer type = m_value->getType();
m_variable->getValue()->checkTypeRequirements();
TypePointer type = m_variable->getValue()->getType();
if (type->getCategory() == Type::Category::IntegerConstant)
{
auto intType = dynamic_pointer_cast<IntegerConstantType const>(type)->getIntegerType();
if (!intType)
BOOST_THROW_EXCEPTION(m_value->createTypeError("Invalid integer constant " + type->toString()));
BOOST_THROW_EXCEPTION(m_variable->getValue()->createTypeError("Invalid integer constant " + type->toString()));
type = intType;
}
else if (type->getCategory() == Type::Category::Void)
@ -429,7 +427,6 @@ void VariableDefinition::checkTypeRequirements()
}
}
}
void Assignment::checkTypeRequirements()
{
m_leftHandSide->checkTypeRequirements();

33
libsolidity/AST.h

@ -133,7 +133,7 @@ class Declaration: public ASTNode
{
public:
/// Visibility ordered from restricted to unrestricted.
enum class Visibility { Default, Private, Protected, Public, External };
enum class Visibility { Default, Private, Internal, Public, External };
Declaration(Location const& _location, ASTPointer<ASTString> const& _name,
Visibility _visibility = Visibility::Default):
@ -144,7 +144,7 @@ public:
Visibility getVisibility() const { return m_visibility == Visibility::Default ? getDefaultVisibility() : m_visibility; }
bool isPublic() const { return getVisibility() >= Visibility::Public; }
bool isVisibleInContract() const { return getVisibility() != Visibility::External; }
bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Protected; }
bool isVisibleInDerivedContracts() const { return isVisibleInContract() && getVisibility() >= Visibility::Internal; }
/// @returns the scope this declaration resides in. Can be nullptr if it is the global scope.
/// Available only after name and type resolution step.
@ -432,14 +432,17 @@ class VariableDeclaration: public Declaration
{
public:
VariableDeclaration(Location const& _location, ASTPointer<TypeName> const& _type,
ASTPointer<ASTString> const& _name, Visibility _visibility,
bool _isStateVar = false, bool _isIndexed = false):
Declaration(_location, _name, _visibility), m_typeName(_type),
m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed) {}
ASTPointer<ASTString> const& _name, ASTPointer<Expression> _value,
Visibility _visibility,
bool _isStateVar = false, bool _isIndexed = false):
Declaration(_location, _name, _visibility),
m_typeName(_type), m_value(_value),
m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
TypeName const* getTypeName() const { return m_typeName.get(); }
ASTPointer<Expression> const& getValue() const { return m_value; }
/// Returns the declared or inferred type. Can be an empty pointer if no type was explicitly
/// declared and there is no assignment to the variable that fixes the type.
@ -447,16 +450,20 @@ public:
void setType(std::shared_ptr<Type const> const& _type) { m_type = _type; }
virtual bool isLValue() const override;
/// Calls checkTypeRequirments for all state variables.
void checkTypeRequirements();
bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition const*>(getScope()); }
bool isFunctionParameter() const;
bool isExternalFunctionParameter() const;
bool isStateVariable() const { return m_isStateVariable; }
bool isIndexed() const { return m_isIndexed; }
protected:
Visibility getDefaultVisibility() const override { return Visibility::Protected; }
Visibility getDefaultVisibility() const override { return Visibility::Internal; }
private:
ASTPointer<TypeName> m_typeName; ///< can be empty ("var")
ASTPointer<Expression> m_value; ///< the assigned value, can be missing
bool m_isStateVariable; ///< Whether or not this is a contract state variable
bool m_isIndexed; ///< Whether this is an indexed variable (used by events).
@ -833,22 +840,20 @@ private:
* also be "var") but the actual assignment can be missing.
* Examples: var a = 2; uint256 a;
*/
class VariableDefinition: public Statement
class VariableDeclarationStatement: public Statement
{
public:
VariableDefinition(Location const& _location, ASTPointer<VariableDeclaration> _variable,
ASTPointer<Expression> _value):
Statement(_location), m_variable(_variable), m_value(_value) {}
VariableDeclarationStatement(Location const& _location, ASTPointer<VariableDeclaration> _variable):
Statement(_location), m_variable(_variable) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
virtual void checkTypeRequirements() override;
VariableDeclaration const& getDeclaration() const { return *m_variable; }
Expression const* getExpression() const { return m_value.get(); }
Expression const* getExpression() const { return m_variable->getValue().get(); }
private:
ASTPointer<VariableDeclaration> m_variable;
ASTPointer<Expression> m_value; ///< the assigned value, can be missing
};
/**

2
libsolidity/ASTForward.h

@ -63,7 +63,7 @@ class ForStatement;
class Continue;
class Break;
class Return;
class VariableDefinition;
class VariableDeclarationStatement;
class ExpressionStatement;
class Expression;
class Assignment;

4
libsolidity/ASTJsonConverter.cpp

@ -198,7 +198,7 @@ bool ASTJsonConverter::visit(Return const&)
return true;
}
bool ASTJsonConverter::visit(VariableDefinition const&)
bool ASTJsonConverter::visit(VariableDeclarationStatement const&)
{
addJsonNode("VariableDefinition", {}, true);
return true;
@ -394,7 +394,7 @@ void ASTJsonConverter::endVisit(Return const&)
goUp();
}
void ASTJsonConverter::endVisit(VariableDefinition const&)
void ASTJsonConverter::endVisit(VariableDeclarationStatement const&)
{
goUp();
}

4
libsolidity/ASTJsonConverter.h

@ -64,7 +64,7 @@ public:
bool visit(Continue const& _node) override;
bool visit(Break const& _node) override;
bool visit(Return const& _node) override;
bool visit(VariableDefinition const& _node) override;
bool visit(VariableDeclarationStatement const& _node) override;
bool visit(ExpressionStatement const& _node) override;
bool visit(Expression const& _node) override;
bool visit(Assignment const& _node) override;
@ -98,7 +98,7 @@ public:
void endVisit(Continue const&) override;
void endVisit(Break const&) override;
void endVisit(Return const&) override;
void endVisit(VariableDefinition const&) override;
void endVisit(VariableDeclarationStatement const&) override;
void endVisit(ExpressionStatement const&) override;
void endVisit(Expression const&) override;
void endVisit(Assignment const&) override;

6
libsolidity/ASTPrinter.cpp

@ -225,9 +225,9 @@ bool ASTPrinter::visit(Return const& _node)
return goDeeper();
}
bool ASTPrinter::visit(VariableDefinition const& _node)
bool ASTPrinter::visit(VariableDeclarationStatement const& _node)
{
writeLine("VariableDefinition");
writeLine("VariableDeclarationStatement");
printSourcePart(_node);
return goDeeper();
}
@ -469,7 +469,7 @@ void ASTPrinter::endVisit(Return const&)
m_indentation--;
}
void ASTPrinter::endVisit(VariableDefinition const&)
void ASTPrinter::endVisit(VariableDeclarationStatement const&)
{
m_indentation--;
}

4
libsolidity/ASTPrinter.h

@ -68,7 +68,7 @@ public:
bool visit(Continue const& _node) override;
bool visit(Break const& _node) override;
bool visit(Return const& _node) override;
bool visit(VariableDefinition const& _node) override;
bool visit(VariableDeclarationStatement const& _node) override;
bool visit(ExpressionStatement const& _node) override;
bool visit(Expression const& _node) override;
bool visit(Assignment const& _node) override;
@ -109,7 +109,7 @@ public:
void endVisit(Continue const&) override;
void endVisit(Break const&) override;
void endVisit(Return const&) override;
void endVisit(VariableDefinition const&) override;
void endVisit(VariableDeclarationStatement const&) override;
void endVisit(ExpressionStatement const&) override;
void endVisit(Expression const&) override;
void endVisit(Assignment const&) override;

8
libsolidity/ASTVisitor.h

@ -69,7 +69,7 @@ public:
virtual bool visit(Continue&) { return true; }
virtual bool visit(Break&) { return true; }
virtual bool visit(Return&) { return true; }
virtual bool visit(VariableDefinition&) { return true; }
virtual bool visit(VariableDeclarationStatement&) { return true; }
virtual bool visit(ExpressionStatement&) { return true; }
virtual bool visit(Expression&) { return true; }
virtual bool visit(Assignment&) { return true; }
@ -112,7 +112,7 @@ public:
virtual void endVisit(Continue&) { }
virtual void endVisit(Break&) { }
virtual void endVisit(Return&) { }
virtual void endVisit(VariableDefinition&) { }
virtual void endVisit(VariableDeclarationStatement&) { }
virtual void endVisit(ExpressionStatement&) { }
virtual void endVisit(Expression&) { }
virtual void endVisit(Assignment&) { }
@ -159,7 +159,7 @@ public:
virtual bool visit(Continue const&) { return true; }
virtual bool visit(Break const&) { return true; }
virtual bool visit(Return const&) { return true; }
virtual bool visit(VariableDefinition const&) { return true; }
virtual bool visit(VariableDeclarationStatement const&) { return true; }
virtual bool visit(ExpressionStatement const&) { return true; }
virtual bool visit(Expression const&) { return true; }
virtual bool visit(Assignment const&) { return true; }
@ -202,7 +202,7 @@ public:
virtual void endVisit(Continue const&) { }
virtual void endVisit(Break const&) { }
virtual void endVisit(Return const&) { }
virtual void endVisit(VariableDefinition const&) { }
virtual void endVisit(VariableDeclarationStatement const&) { }
virtual void endVisit(ExpressionStatement const&) { }
virtual void endVisit(Expression const&) { }
virtual void endVisit(Assignment const&) { }

20
libsolidity/AST_accept.h

@ -196,16 +196,24 @@ void FunctionDefinition::accept(ASTConstVisitor& _visitor) const
void VariableDeclaration::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
{
if (m_typeName)
m_typeName->accept(_visitor);
if (m_value)
m_value->accept(_visitor);
}
_visitor.endVisit(*this);
}
void VariableDeclaration::accept(ASTConstVisitor& _visitor) const
{
if (_visitor.visit(*this))
{
if (m_typeName)
m_typeName->accept(_visitor);
if (m_value)
m_value->accept(_visitor);
}
_visitor.endVisit(*this);
}
@ -475,25 +483,17 @@ void ExpressionStatement::accept(ASTConstVisitor& _visitor) const
_visitor.endVisit(*this);
}
void VariableDefinition::accept(ASTVisitor& _visitor)
void VariableDeclarationStatement::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
{
m_variable->accept(_visitor);
if (m_value)
m_value->accept(_visitor);
}
_visitor.endVisit(*this);
}
void VariableDefinition::accept(ASTConstVisitor& _visitor) const
void VariableDeclarationStatement::accept(ASTConstVisitor& _visitor) const
{
if (_visitor.visit(*this))
{
m_variable->accept(_visitor);
if (m_value)
m_value->accept(_visitor);
}
_visitor.endVisit(*this);
}

51
libsolidity/Compiler.cpp

@ -34,6 +34,20 @@ using namespace std;
namespace dev {
namespace solidity {
/**
* Simple helper class to ensure that the stack height is the same at certain places in the code.
*/
class StackHeightChecker
{
public:
StackHeightChecker(CompilerContext const& _context):
m_context(_context), stackHeight(m_context.getStackHeight()) {}
void check() { solAssert(m_context.getStackHeight() == stackHeight, "I sense a disturbance in the stack."); }
private:
CompilerContext const& m_context;
unsigned stackHeight;
};
void Compiler::compileContract(ContractDefinition const& _contract,
map<ContractDefinition const*, bytes const*> const& _contracts)
{
@ -73,7 +87,7 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp
for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts())
{
ContractDefinition const* baseContract = dynamic_cast<ContractDefinition const*>(
base->getName()->getReferencedDeclaration());
base->getName()->getReferencedDeclaration());
solAssert(baseContract, "");
if (baseArguments.count(baseContract) == 0)
baseArguments[baseContract] = &base->getArguments();
@ -85,12 +99,14 @@ void Compiler::packIntoContractCreator(ContractDefinition const& _contract, Comp
{
ContractDefinition const* base = bases[bases.size() - i];
solAssert(base, "");
initializeStateVariables(*base);
FunctionDefinition const* baseConstructor = base->getConstructor();
if (!baseConstructor)
continue;
solAssert(baseArguments[base], "");
appendBaseConstructorCall(*baseConstructor, *baseArguments[base]);
}
initializeStateVariables(_contract);
if (_contract.getConstructor())
appendConstructorCall(*_contract.getConstructor());
@ -247,6 +263,13 @@ void Compiler::registerStateVariables(ContractDefinition const& _contract)
m_context.addStateVariable(*variable);
}
void Compiler::initializeStateVariables(ContractDefinition const& _contract)
{
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
if (variable->getValue())
ExpressionCompiler::appendStateVariableInitialization(m_context, *variable);
}
bool Compiler::visit(VariableDeclaration const& _variableDeclaration)
{
solAssert(_variableDeclaration.isStateVariable(), "Compiler visit to non-state variable declaration.");
@ -331,6 +354,8 @@ bool Compiler::visit(FunctionDefinition const& _function)
bool Compiler::visit(IfStatement const& _ifStatement)
{
StackHeightChecker checker(m_context);
compileExpression(_ifStatement.getCondition());
eth::AssemblyItem trueTag = m_context.appendConditionalJump();
if (_ifStatement.getFalseStatement())
@ -339,11 +364,15 @@ bool Compiler::visit(IfStatement const& _ifStatement)
m_context << trueTag;
_ifStatement.getTrueStatement().accept(*this);
m_context << endTag;
checker.check();
return false;
}
bool Compiler::visit(WhileStatement const& _whileStatement)
{
StackHeightChecker checker(m_context);
eth::AssemblyItem loopStart = m_context.newTag();
eth::AssemblyItem loopEnd = m_context.newTag();
m_continueTags.push_back(loopStart);
@ -361,11 +390,15 @@ bool Compiler::visit(WhileStatement const& _whileStatement)
m_continueTags.pop_back();
m_breakTags.pop_back();
checker.check();
return false;
}
bool Compiler::visit(ForStatement const& _forStatement)
{
StackHeightChecker checker(m_context);
eth::AssemblyItem loopStart = m_context.newTag();
eth::AssemblyItem loopEnd = m_context.newTag();
m_continueTags.push_back(loopStart);
@ -395,6 +428,8 @@ bool Compiler::visit(ForStatement const& _forStatement)
m_continueTags.pop_back();
m_breakTags.pop_back();
checker.check();
return false;
}
@ -429,29 +464,35 @@ bool Compiler::visit(Return const& _return)
return false;
}
bool Compiler::visit(VariableDefinition const& _variableDefinition)
bool Compiler::visit(VariableDeclarationStatement const& _variableDeclarationStatement)
{
if (Expression const* expression = _variableDefinition.getExpression())
StackHeightChecker checker(m_context);
if (Expression const* expression = _variableDeclarationStatement.getExpression())
{
compileExpression(*expression, _variableDefinition.getDeclaration().getType());
CompilerUtils(m_context).moveToStackVariable(_variableDefinition.getDeclaration());
compileExpression(*expression, _variableDeclarationStatement.getDeclaration().getType());
CompilerUtils(m_context).moveToStackVariable(_variableDeclarationStatement.getDeclaration());
}
checker.check();
return false;
}
bool Compiler::visit(ExpressionStatement const& _expressionStatement)
{
StackHeightChecker checker(m_context);
Expression const& expression = _expressionStatement.getExpression();
compileExpression(expression);
CompilerUtils(m_context).popStackElement(*expression.getType());
checker.check();
return false;
}
bool Compiler::visit(PlaceholderStatement const&)
{
StackHeightChecker checker(m_context);
++m_modifierDepth;
appendModifierOrFunctionCode();
--m_modifierDepth;
checker.check();
return true;
}

3
libsolidity/Compiler.h

@ -59,6 +59,7 @@ private:
void appendReturnValuePacker(TypePointers const& _typeParameters);
void registerStateVariables(ContractDefinition const& _contract);
void initializeStateVariables(ContractDefinition const& _contract);
virtual bool visit(VariableDeclaration const& _variableDeclaration) override;
virtual bool visit(FunctionDefinition const& _function) override;
@ -68,7 +69,7 @@ private:
virtual bool visit(Continue const& _continue) override;
virtual bool visit(Break const& _break) override;
virtual bool visit(Return const& _return) override;
virtual bool visit(VariableDefinition const& _variableDefinition) override;
virtual bool visit(VariableDeclarationStatement const& _variableDeclarationStatement) override;
virtual bool visit(ExpressionStatement const& _expressionStatement) override;
virtual bool visit(PlaceholderStatement const&) override;

1
libsolidity/CompilerContext.h

@ -48,6 +48,7 @@ public:
bytes const& getCompiledContract(ContractDefinition const& _contract) const;
void adjustStackOffset(int _adjustment) { m_asm.adjustDeposit(_adjustment); }
unsigned getStackHeight() const { solAssert(m_asm.deposit() >= 0, ""); return unsigned(m_asm.deposit()); }
bool isMagicGlobal(Declaration const* _declaration) const { return m_magicGlobals.count(_declaration) != 0; }
bool isLocalVariable(Declaration const* _declaration) const;

63
libsolidity/CompilerStack.cpp

@ -58,21 +58,22 @@ CompilerStack::CompilerStack(bool _addStandardSources):
m_addStandardSources(_addStandardSources), m_parseSuccessful(false)
{
if (m_addStandardSources)
addSources(StandardSources);
addSources(StandardSources, true); // add them as libraries
}
bool CompilerStack::addSource(string const& _name, string const& _content)
bool CompilerStack::addSource(string const& _name, string const& _content, bool _isLibrary)
{
bool existed = m_sources.count(_name) != 0;
reset(true);
m_sources[_name].scanner = make_shared<Scanner>(CharStream(expanded(_content)), _name);
m_sources[_name].scanner = make_shared<Scanner>(CharStream(_content), _name);
m_sources[_name].isLibrary = _isLibrary;
return existed;
}
void CompilerStack::setSource(string const& _sourceCode)
{
reset();
addSource("", expanded(_sourceCode));
addSource("", _sourceCode);
}
void CompilerStack::parse()
@ -126,57 +127,6 @@ vector<string> CompilerStack::getContractNames() const
return contractNames;
}
////// BEGIN: TEMPORARY ONLY
///
/// NOTE: THIS INVALIDATES SOURCE POINTERS AND CAN CRASH THE COMPILER
///
/// remove once import works properly and we have genesis contracts
string CompilerStack::expanded(string const& _sourceCode)
{
const map<string, string> c_standardSources = map<string, string>{
{ "Config", "contract Config{function lookup(uint256 service)constant returns(address a){}function kill(){}function unregister(uint256 id){}function register(uint256 id,address service){}}" },
{ "Coin", "contract Coin{function isApprovedFor(address _target,address _proxy)constant returns(bool _r){}function isApproved(address _proxy)constant returns(bool _r){}function sendCoinFrom(address _from,uint256 _val,address _to){}function coinBalanceOf(address _a)constant returns(uint256 _r){}function sendCoin(uint256 _val,address _to){}function coinBalance()constant returns(uint256 _r){}function approve(address _a){}}"},
{ "CoinReg", "contract CoinReg{function count()constant returns(uint256 r){}function info(uint256 i)constant returns(address addr,string3 name,uint256 denom){}function register(string3 name,uint256 denom){}function unregister(){}}" },
{ "coin", "#require CoinReg\ncontract coin {function coin(string3 name, uint denom) {CoinReg(Config().lookup(3)).register(name, denom);}}" },
{ "service", "#require Config\ncontract service{function service(uint _n){Config().register(_n, this);}}" },
{ "owned", "contract owned{function owned(){owner = msg.sender;}modifier onlyowner(){if(msg.sender==owner)_}address owner;}" },
{ "mortal", "#require owned\ncontract mortal is owned {function kill() { if (msg.sender == owner) suicide(owner); }}" },
{ "NameReg", "contract NameReg{function register(string32 name){}function addressOf(string32 name)constant returns(address addr){}function unregister(){}function nameOf(address addr)constant returns(string32 name){}}" },
{ "named", "#require Config NameReg\ncontract named {function named(string32 name) {NameReg(Config().lookup(1)).register(name);}}" },
{ "std", "#require owned mortal Config NameReg named" },
};
string sub;
set<string> got;
function<string(string const&)> localExpanded;
localExpanded = [&](string const& s) -> string
{
string ret = s;
for (size_t p = 0; p != string::npos;)
if ((p = ret.find("#require ")) != string::npos)
{
string n = ret.substr(p + 9, ret.find_first_of('\n', p + 9) - p - 9);
ret.replace(p, n.size() + 9, "");
vector<string> rs;
boost::split(rs, n, boost::is_any_of(" \t,"), boost::token_compress_on);
for (auto const& r: rs)
if (!got.count(r))
{
if (c_standardSources.count(r))
sub.append("\n" + localExpanded(c_standardSources.at(r)) + "\n");
got.insert(r);
}
}
// TODO: remove once we have genesis contracts.
else if ((p = ret.find("Config()")) != string::npos)
ret.replace(p, 8, "Config(0xc6d9d2cd449a754c494264e1809c50e34d64562b)");
return ret;
};
return sub + localExpanded(_sourceCode);
}
////// END: TEMPORARY ONLY
void CompilerStack::compile(bool _optimize)
{
@ -328,7 +278,8 @@ void CompilerStack::resolveImports()
};
for (auto const& sourcePair: m_sources)
toposort(&sourcePair.second);
if (!sourcePair.second.isLibrary)
toposort(&sourcePair.second);
swap(m_sourceOrder, sourceOrder);
}

11
libsolidity/CompilerStack.h

@ -64,8 +64,8 @@ public:
/// Adds a source object (e.g. file) to the parser. After this, parse has to be called again.
/// @returns true if a source object by the name already existed and was replaced.
void addSources(std::map<std::string, std::string> const& _nameContents) { for (auto const& i: _nameContents) addSource(i.first, i.second); }
bool addSource(std::string const& _name, std::string const& _content);
void addSources(std::map<std::string, std::string> const& _nameContents, bool _isLibrary = false) { for (auto const& i: _nameContents) addSource(i.first, i.second, _isLibrary); }
bool addSource(std::string const& _name, std::string const& _content, bool _isLibrary = false);
void setSource(std::string const& _sourceCode);
/// Parses all source units that were added
void parse();
@ -125,7 +125,8 @@ private:
std::shared_ptr<Scanner> scanner;
std::shared_ptr<SourceUnit> ast;
std::string interface;
void reset() { scanner.reset(); ast.reset(); interface.clear(); }
bool isLibrary = false;
void reset() { scanner.reset(); ast.reset(); interface.clear(); isLibrary = false;}
};
struct Contract
@ -143,10 +144,6 @@ private:
Contract();
};
/// Expand source code with preprocessor-like includes.
/// @todo Replace with better framework.
std::string expanded(std::string const& _sourceCode);
void reset(bool _keepSources = false);
void resolveImports();

58
libsolidity/ExpressionCompiler.cpp

@ -56,6 +56,23 @@ void ExpressionCompiler::appendStateVariableAccessor(CompilerContext& _context,
compiler.appendStateVariableAccessor(_varDecl);
}
void ExpressionCompiler::appendStateVariableInitialization(CompilerContext& _context, VariableDeclaration const& _varDecl, bool _optimize)
{
compileExpression(_context, *(_varDecl.getValue()), _optimize);
if (_varDecl.getValue()->getType())
appendTypeConversion(_context, *(_varDecl.getValue())->getType(), *(_varDecl.getValue())->getType());
ExpressionCompiler compiler(_context, _optimize);
compiler.appendStateVariableInitialization(_varDecl);
}
void ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration const& _varDecl)
{
LValue var = LValue(m_context);
var.fromDeclaration(_varDecl, _varDecl.getValue()->getLocation());
var.storeValue(*_varDecl.getType(), _varDecl.getLocation());
}
bool ExpressionCompiler::visit(Assignment const& _assignment)
{
_assignment.getRightHandSide().accept(*this);
@ -77,7 +94,6 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
}
m_currentLValue.storeValue(*_assignment.getRightHandSide().getType(), _assignment.getLocation());
m_currentLValue.reset();
return false;
}
@ -572,7 +588,7 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag();
else if (dynamic_cast<VariableDeclaration const*>(declaration))
{
m_currentLValue.fromIdentifier(_identifier, *declaration);
m_currentLValue.fromDeclaration(*declaration, _identifier.getLocation());
m_currentLValue.retrieveValueIfLValueNotRequested(_identifier);
}
else if (dynamic_cast<ContractDefinition const*>(declaration))
@ -1002,12 +1018,12 @@ ExpressionCompiler::LValue::LValue(CompilerContext& _compilerContext, LValueType
m_size = unsigned(m_dataType->getSizeOnStack());
}
void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, Declaration const& _declaration)
void ExpressionCompiler::LValue::fromDeclaration(Declaration const& _declaration, Location const& _location)
{
if (m_context->isLocalVariable(&_declaration))
{
m_type = LValueType::Stack;
m_dataType = _identifier.getType();
m_dataType = _declaration.getType();
m_size = m_dataType->getSizeOnStack();
m_baseStackOffset = m_context->getBaseStackOffsetOfVariable(_declaration);
}
@ -1015,12 +1031,13 @@ void ExpressionCompiler::LValue::fromIdentifier(Identifier const& _identifier, D
{
*m_context << m_context->getStorageLocationOfVariable(_declaration);
m_type = LValueType::Storage;
m_dataType = _identifier.getType();
m_dataType = _declaration.getType();
solAssert(m_dataType->getStorageSize() <= numeric_limits<unsigned>::max(),
"The storage size of " + m_dataType->toString() + " should fit in an unsigned");
m_size = unsigned(m_dataType->getStorageSize()); }
m_size = unsigned(m_dataType->getStorageSize());
}
else
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_identifier.getLocation())
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_location)
<< errinfo_comment("Identifier type not supported or identifier not found."));
}
@ -1117,11 +1134,15 @@ void ExpressionCompiler::LValue::storeValue(Type const& _sourceType, Location co
}
else
{
solAssert(_sourceType.getCategory() == m_dataType->getCategory(), "");
solAssert(_sourceType.getCategory() == m_dataType->getCategory(), "Wrong type conversation for assignment.");
if (m_dataType->getCategory() == Type::Category::ByteArray)
{
CompilerUtils(*m_context).copyByteArrayToStorage(
dynamic_cast<ByteArrayType const&>(*m_dataType),
dynamic_cast<ByteArrayType const&>(_sourceType));
if (_move)
*m_context << eth::Instruction::POP;
}
else if (m_dataType->getCategory() == Type::Category::Struct)
{
// stack layout: source_ref target_ref
@ -1136,12 +1157,14 @@ void ExpressionCompiler::LValue::storeValue(Type const& _sourceType, Location co
*m_context << structType.getStorageOffsetOfMember(member.first)
<< eth::Instruction::DUP3 << eth::Instruction::DUP2
<< eth::Instruction::ADD;
// stack: source_ref target_ref member_offset source_member_ref
LValue rightHandSide(*m_context, LValueType::Storage, memberType);
rightHandSide.retrieveValue(_location, true);
// stack: source_ref target_ref offset source_value...
// stack: source_ref target_ref member_offset source_value...
*m_context << eth::dupInstruction(2 + memberType->getSizeOnStack())
<< eth::dupInstruction(2 + memberType->getSizeOnStack())
<< eth::Instruction::ADD;
// stack: source_ref target_ref member_offset source_value... target_member_ref
LValue memberLValue(*m_context, LValueType::Storage, memberType);
memberLValue.storeValue(*memberType, _location, true);
*m_context << eth::Instruction::POP;
@ -1189,6 +1212,23 @@ void ExpressionCompiler::LValue::setToZero(Location const& _location) const
case LValueType::Storage:
if (m_dataType->getCategory() == Type::Category::ByteArray)
CompilerUtils(*m_context).clearByteArray(dynamic_cast<ByteArrayType const&>(*m_dataType));
else if (m_dataType->getCategory() == Type::Category::Struct)
{
// stack layout: ref
auto const& structType = dynamic_cast<StructType const&>(*m_dataType);
for (auto const& member: structType.getMembers())
{
// zero each member that is not a mapping
TypePointer const& memberType = member.second;
if (memberType->getCategory() == Type::Category::Mapping)
continue;
*m_context << structType.getStorageOffsetOfMember(member.first)
<< eth::Instruction::DUP2 << eth::Instruction::ADD;
LValue memberValue(*m_context, LValueType::Storage, memberType);
memberValue.setToZero();
}
*m_context << eth::Instruction::POP;
}
else
{
if (m_size == 0)

13
libsolidity/ExpressionCompiler.h

@ -59,6 +59,9 @@ public:
/// Appends code for a State Variable accessor function
static void appendStateVariableAccessor(CompilerContext& _context, VariableDeclaration const& _varDecl, bool _optimize = false);
/// Appends code for a State Variable Initialization function
static void appendStateVariableInitialization(CompilerContext& _context, VariableDeclaration const& _varDecl, bool _optimize = false);
private:
explicit ExpressionCompiler(CompilerContext& _compilerContext, bool _optimize = false):
m_optimize(_optimize), m_context(_compilerContext), m_currentLValue(m_context) {}
@ -111,6 +114,9 @@ private:
/// Appends code for a State Variable accessor function
void appendStateVariableAccessor(VariableDeclaration const& _varDecl);
/// Appends code for a State Variable initialization
void appendStateVariableInitialization(VariableDeclaration const& _varDecl);
/**
* Helper class to store and retrieve lvalues to and from various locations.
* All types except STACK store a reference in a slot on the stack, STACK just
@ -126,8 +132,9 @@ private:
std::shared_ptr<Type const> const& _dataType, unsigned _baseStackOffset = 0);
/// Set type according to the declaration and retrieve the reference.
/// @a _expression is the current expression
void fromIdentifier(Identifier const& _identifier, Declaration const& _declaration);
/// @a _location is the current location
void fromDeclaration(Declaration const& _declaration, Location const& _location);
void reset() { m_type = LValueType::None; m_dataType.reset(); m_baseStackOffset = 0; m_size = 0; }
bool isValid() const { return m_type != LValueType::None; }
@ -144,7 +151,7 @@ private:
void retrieveValue(Location const& _location, bool _remove = false) const;
/// Moves a value from the stack to the lvalue. Removes the value if @a _move is true.
/// @a _location is the source location of the expression that caused this operation.
/// Stack pre: [lvalue_ref] value
/// Stack pre: value [lvalue_ref]
/// Stack post if !_move: value_of(lvalue_ref)
void storeValue(Type const& _sourceType, Location const& _location = Location(), bool _move = false) const;
/// Stores zero in the lvalue.

14
libsolidity/NameAndTypeResolver.cpp

@ -267,12 +267,12 @@ void DeclarationRegistrationHelper::endVisit(ModifierDefinition&)
closeCurrentScope();
}
void DeclarationRegistrationHelper::endVisit(VariableDefinition& _variableDefinition)
void DeclarationRegistrationHelper::endVisit(VariableDeclarationStatement& _variableDeclarationStatement)
{
// Register the local variables with the function
// This does not fit here perfectly, but it saves us another AST visit.
solAssert(m_currentFunction, "Variable definition without function.");
m_currentFunction->addLocalVariable(_variableDefinition.getDeclaration());
solAssert(m_currentFunction, "Variable declaration without function.");
m_currentFunction->addLocalVariable(_variableDeclarationStatement.getDeclaration());
}
bool DeclarationRegistrationHelper::visit(VariableDeclaration& _declaration)
@ -333,7 +333,13 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable)
// or mapping
if (_variable.getTypeName())
{
_variable.setType(_variable.getTypeName()->toType());
TypePointer type = _variable.getTypeName()->toType();
// All byte array parameter types should point to call data
if (_variable.isExternalFunctionParameter())
if (auto const* byteArrayType = dynamic_cast<ByteArrayType const*>(type.get()))
type = byteArrayType->copyForLocation(ByteArrayType::Location::CallData);
_variable.setType(type);
if (!_variable.getType())
BOOST_THROW_EXCEPTION(_variable.getTypeName()->createTypeError("Invalid type name"));
}

2
libsolidity/NameAndTypeResolver.h

@ -105,7 +105,7 @@ private:
void endVisit(FunctionDefinition& _function) override;
bool visit(ModifierDefinition& _modifier) override;
void endVisit(ModifierDefinition& _modifier) override;
void endVisit(VariableDefinition& _variableDefinition) override;
void endVisit(VariableDeclarationStatement& _variableDeclarationStatement) override;
bool visit(VariableDeclaration& _declaration) override;
bool visit(EventDefinition& _event) override;
void endVisit(EventDefinition& _event) override;

51
libsolidity/Parser.cpp

@ -148,6 +148,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
{
VarDeclParserOptions options;
options.isStateVariable = true;
options.allowInitialValue = true;
stateVariables.push_back(parseVariableDeclaration(options));
expectToken(Token::Semicolon);
}
@ -186,8 +187,8 @@ Declaration::Visibility Parser::parseVisibilitySpecifier(Token::Value _token)
Declaration::Visibility visibility(Declaration::Visibility::Default);
if (_token == Token::Public)
visibility = Declaration::Visibility::Public;
else if (_token == Token::Protected)
visibility = Declaration::Visibility::Protected;
else if (_token == Token::Internal)
visibility = Declaration::Visibility::Internal;
else if (_token == Token::Private)
visibility = Declaration::Visibility::Private;
else if (_token == Token::External)
@ -324,9 +325,19 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(VarDeclParserOp
}
else
identifier = expectIdentifierToken();
return nodeFactory.createNode<VariableDeclaration>(type, identifier,
visibility, _options.isStateVariable,
isIndexed);
ASTPointer<Expression> value;
if (_options.allowInitialValue)
{
if (m_scanner->getCurrentToken() == Token::Assign)
{
m_scanner->next();
value = parseExpression();
nodeFactory.setEndPositionFromNode(value);
}
}
return nodeFactory.createNode<VariableDeclaration>(type, identifier, value,
visibility, _options.isStateVariable,
isIndexed);
}
ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
@ -519,7 +530,7 @@ ASTPointer<Statement> Parser::parseStatement()
}
// fall-through
default:
statement = parseVarDefOrExprStmt();
statement = parseVarDeclOrExprStmt();
}
expectToken(Token::Semicolon);
return statement;
@ -568,7 +579,7 @@ ASTPointer<ForStatement> Parser::parseForStatement()
// LTODO: Maybe here have some predicate like peekExpression() instead of checking for semicolon and RParen?
if (m_scanner->getCurrentToken() != Token::Semicolon)
initExpression = parseVarDefOrExprStmt();
initExpression = parseVarDeclOrExprStmt();
expectToken(Token::Semicolon);
if (m_scanner->getCurrentToken() != Token::Semicolon)
@ -587,30 +598,22 @@ ASTPointer<ForStatement> Parser::parseForStatement()
body);
}
ASTPointer<Statement> Parser::parseVarDefOrExprStmt()
ASTPointer<Statement> Parser::parseVarDeclOrExprStmt()
{
if (peekVariableDefinition())
return parseVariableDefinition();
if (peekVariableDeclarationStatement())
return parseVariableDeclarationStatement();
else
return parseExpressionStatement();
}
ASTPointer<VariableDefinition> Parser::parseVariableDefinition()
ASTPointer<VariableDeclarationStatement> Parser::parseVariableDeclarationStatement()
{
ASTNodeFactory nodeFactory(*this);
VarDeclParserOptions options;
options.allowVar = true;
options.allowInitialValue = true;
ASTPointer<VariableDeclaration> variable = parseVariableDeclaration(options);
ASTPointer<Expression> value;
if (m_scanner->getCurrentToken() == Token::Assign)
{
m_scanner->next();
value = parseExpression();
nodeFactory.setEndPositionFromNode(value);
}
else
nodeFactory.setEndPositionFromNode(variable);
return nodeFactory.createNode<VariableDefinition>(variable, value);
return nodeFactory.createNode<VariableDeclarationStatement>(variable);
}
ASTPointer<ExpressionStatement> Parser::parseExpressionStatement()
@ -822,11 +825,11 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
}
bool Parser::peekVariableDefinition()
bool Parser::peekVariableDeclarationStatement()
{
// distinguish between variable definition (and potentially assignment) and expression statement
// distinguish between variable declaration (and potentially assignment) and expression statement
// (which include assignments to other expressions and pre-declared variables)
// We have a variable definition if we get a keyword that specifies a type name, or
// We have a variable declaration if we get a keyword that specifies a type name, or
// in the case of a user-defined type, we have two identifiers following each other.
return (m_scanner->getCurrentToken() == Token::Mapping ||
m_scanner->getCurrentToken() == Token::Var ||

9
libsolidity/Parser.h

@ -51,6 +51,7 @@ private:
bool isStateVariable = false;
bool allowIndexed = false;
bool allowEmptyName = false;
bool allowInitialValue = false;
};
///@{
@ -76,8 +77,8 @@ private:
ASTPointer<IfStatement> parseIfStatement();
ASTPointer<WhileStatement> parseWhileStatement();
ASTPointer<ForStatement> parseForStatement();
ASTPointer<Statement> parseVarDefOrExprStmt();
ASTPointer<VariableDefinition> parseVariableDefinition();
ASTPointer<Statement> parseVarDeclOrExprStmt();
ASTPointer<VariableDeclarationStatement> parseVariableDeclarationStatement();
ASTPointer<ExpressionStatement> parseExpressionStatement();
ASTPointer<Expression> parseExpression();
ASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4);
@ -91,8 +92,8 @@ private:
///@{
///@name Helper functions
/// Peeks ahead in the scanner to determine if a variable definition is going to follow
bool peekVariableDefinition();
/// Peeks ahead in the scanner to determine if a variable declaration statement is going to follow
bool peekVariableDeclarationStatement();
/// If current token value is not _value, throw exception otherwise advance token.
void expectToken(Token::Value _value);

6
libsolidity/Token.h

@ -162,7 +162,7 @@ namespace solidity
K(New, "new", 0) \
K(Public, "public", 0) \
K(Private, "private", 0) \
K(Protected, "protected", 0) \
K(Internal, "internal", 0) \
K(Return, "return", 0) \
K(Returns, "returns", 0) \
K(Struct, "struct", 0) \
@ -372,7 +372,7 @@ public:
static Value AssignmentToBinaryOp(Value op)
{
solAssert(isAssignmentOp(op) && op != Assign, "");
return Token::Value(op + (BitOr - AssignBitOr));
return Value(op + (BitOr - AssignBitOr));
}
static bool isBitOp(Value op) { return (BitOr <= op && op <= SHR) || op == BitNot; }
@ -380,7 +380,7 @@ public:
static bool isCountOp(Value op) { return op == Inc || op == Dec; }
static bool isShiftOp(Value op) { return (SHL <= op) && (op <= SHR); }
static bool isVisibilitySpecifier(Value op) { return isVariableVisibilitySpecifier(op) || op == External; }
static bool isVariableVisibilitySpecifier(Value op) { return op == Public || op == Private || op == Protected; }
static bool isVariableVisibilitySpecifier(Value op) { return op == Public || op == Private || op == Internal; }
static bool isEtherSubdenomination(Value op) { return op == SubWei || op == SubSzabo || op == SubFinney || op == Token::SubEther; }
// Returns a string corresponding to the JS token string

43
libsolidity/Types.cpp

@ -573,19 +573,19 @@ MemberList const& ContractType::getMembers() const
if (!m_members)
{
// All address members and all interface functions
map<string, TypePointer> members(IntegerType::AddressMemberList.begin(),
IntegerType::AddressMemberList.end());
vector<pair<string, TypePointer>> members(IntegerType::AddressMemberList.begin(),
IntegerType::AddressMemberList.end());
if (m_super)
{
for (ContractDefinition const* base: m_contract.getLinearizedBaseContracts())
for (ASTPointer<FunctionDefinition> const& function: base->getDefinedFunctions())
if (!function->isConstructor() && !function->getName().empty() &&
if (!function->isConstructor() && !function->getName().empty()&&
function->isVisibleInDerivedContracts())
members.insert(make_pair(function->getName(), make_shared<FunctionType>(*function, true)));
members.push_back(make_pair(function->getName(), make_shared<FunctionType>(*function, true)));
}
else
for (auto const& it: m_contract.getInterfaceFunctions())
members[it.second->getDeclaration().getName()] = it.second;
members.push_back(make_pair(it.second->getDeclaration().getName(), it.second));
m_members.reset(new MemberList(members));
}
return *m_members;
@ -653,9 +653,9 @@ MemberList const& StructType::getMembers() const
// We need to lazy-initialize it because of recursive references.
if (!m_members)
{
map<string, TypePointer> members;
MemberList::MemberMap members;
for (ASTPointer<VariableDeclaration> const& variable: m_struct.getMembers())
members[variable->getName()] = variable->getType();
members.push_back(make_pair(variable->getName(), variable->getType()));
m_members.reset(new MemberList(members));
}
return *m_members;
@ -833,10 +833,17 @@ string FunctionType::toString() const
unsigned FunctionType::getSizeOnStack() const
{
Location location = m_location;
if (m_location == Location::SetGas || m_location == Location::SetValue)
{
solAssert(m_returnParameterTypes.size() == 1, "");
location = dynamic_cast<FunctionType const&>(*m_returnParameterTypes.front()).m_location;
}
unsigned size = 0;
if (m_location == Location::External)
if (location == Location::External)
size = 2;
else if (m_location == Location::Internal || m_location == Location::Bare)
else if (location == Location::Internal || location == Location::Bare)
size = 1;
if (m_gasSet)
size++;
@ -857,15 +864,15 @@ MemberList const& FunctionType::getMembers() const
case Location::Bare:
if (!m_members)
{
map<string, TypePointer> members{
{"gas", make_shared<FunctionType>(parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(true, false)},
Location::SetGas, false, m_gasSet, m_valueSet)},
vector<pair<string, TypePointer>> members{
{"value", make_shared<FunctionType>(parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(false, true)},
Location::SetValue, false, m_gasSet, m_valueSet)}};
if (m_location == Location::Creation)
members.erase("gas");
if (m_location != Location::Creation)
members.push_back(make_pair("gas", make_shared<FunctionType>(
parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(true, false)},
Location::SetGas, false, m_gasSet, m_valueSet)));
m_members.reset(new MemberList(members));
}
return *m_members;
@ -959,7 +966,7 @@ MemberList const& TypeType::getMembers() const
// We need to lazy-initialize it because of recursive references.
if (!m_members)
{
map<string, TypePointer> members;
vector<pair<string, TypePointer>> members;
if (m_actualType->getCategory() == Category::Contract && m_currentContract != nullptr)
{
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*m_actualType).getContractDefinition();
@ -969,14 +976,14 @@ MemberList const& TypeType::getMembers() const
// functions. Note that this does not add inherited functions on purpose.
for (ASTPointer<FunctionDefinition> const& f: contract.getDefinedFunctions())
if (!f->isConstructor() && !f->getName().empty() && f->isVisibleInDerivedContracts())
members[f->getName()] = make_shared<FunctionType>(*f);
members.push_back(make_pair(f->getName(), make_shared<FunctionType>(*f)));
}
else if (m_actualType->getCategory() == Category::Enum)
{
EnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).getEnumDefinition();
auto enumType = make_shared<EnumType>(enumDef);
for (ASTPointer<EnumValue> const& enumValue: enumDef.getMembers())
members.insert(make_pair(enumValue->getName(), enumType));
members.push_back(make_pair(enumValue->getName(), enumType));
}
m_members.reset(new MemberList(members));
}

31
libsolidity/Types.h

@ -50,14 +50,16 @@ using TypePointers = std::vector<TypePointer>;
class MemberList
{
public:
using MemberMap = std::map<std::string, TypePointer>;
using MemberMap = std::vector<std::pair<std::string, TypePointer>>;
MemberList() {}
explicit MemberList(MemberMap const& _members): m_memberTypes(_members) {}
TypePointer getMemberType(std::string const& _name) const
{
auto it = m_memberTypes.find(_name);
return it != m_memberTypes.end() ? it->second : TypePointer();
for (auto const& it: m_memberTypes)
if (it.first == _name)
return it.second;
return TypePointer();
}
MemberMap::const_iterator begin() const { return m_memberTypes.begin(); }
@ -428,12 +430,21 @@ public:
Location _location = Location::Internal, bool _arbitraryParameters = false):
FunctionType(parseElementaryTypeVector(_parameterTypes), parseElementaryTypeVector(_returnParameterTypes),
_location, _arbitraryParameters) {}
FunctionType(TypePointers const& _parameterTypes, TypePointers const& _returnParameterTypes,
Location _location = Location::Internal,
bool _arbitraryParameters = false, bool _gasSet = false, bool _valueSet = false):
m_parameterTypes(_parameterTypes), m_returnParameterTypes(_returnParameterTypes),
m_location(_location),
m_arbitraryParameters(_arbitraryParameters), m_gasSet(_gasSet), m_valueSet(_valueSet) {}
FunctionType(
TypePointers const& _parameterTypes,
TypePointers const& _returnParameterTypes,
Location _location = Location::Internal,
bool _arbitraryParameters = false,
bool _gasSet = false,
bool _valueSet = false
):
m_parameterTypes (_parameterTypes),
m_returnParameterTypes (_returnParameterTypes),
m_location (_location),
m_arbitraryParameters (_arbitraryParameters),
m_gasSet (_gasSet),
m_valueSet (_valueSet)
{}
TypePointers const& getParameterTypes() const { return m_parameterTypes; }
std::vector<std::string> const& getParameterNames() const { return m_parameterNames; }
@ -488,7 +499,7 @@ private:
bool const m_arbitraryParameters = false;
bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack
bool const m_valueSet = false; ///< true iff the value to be sent is on the stack
bool m_isConstant;
bool m_isConstant = false;
mutable std::unique_ptr<MemberList> m_members;
Declaration const* m_declaration = nullptr;
};

4
libsolidity/grammar.txt

@ -6,10 +6,10 @@ ContractPart = StateVariableDeclaration | StructDefinition | ModifierDefinition
InheritanceSpecifier = Identifier ( '(' Expression ( ',' Expression )* ')' )?
StructDefinition = 'struct' Identifier '{'
( VariableDeclaration (';' VariableDeclaration)* )? '}
StateVariableDeclaration = TypeName ( 'public' | 'protected' | 'private' )? Identifier ';'
StateVariableDeclaration = TypeName ( 'public' | 'inheritable' | 'private' )? Identifier ';'
ModifierDefinition = 'modifier' Identifier ParameterList? Block
FunctionDefinition = 'function' Identifier ParameterList
( Identifier | 'constant' | 'public' | 'protected' | 'private' )*
( Identifier | 'constant' | 'external' | 'public' | 'inheritable' | 'private' )*
( 'returns' ParameterList )? Block
EnumValue = Identifier

108
libweb3jsonrpc/AccountHolder.cpp

@ -0,0 +1,108 @@
/*
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 AccountHolder.cpp
* @authors:
* Christian R <c@ethdev.com>
* Lefteris Karapetsas <lefteris@ethdev.com>
* @date 2015
*/
#include "AccountHolder.h"
#include <random>
#include <ctime>
#include <libdevcore/Guards.h>
#include <libethereum/Client.h>
using namespace std;
using namespace dev;
using namespace dev::eth;
vector<TransactionSkeleton> g_emptyQueue;
static std::mt19937 g_randomNumberGenerator(time(0));
static Mutex x_rngMutex;
void AccountHolder::setAccounts(vector<KeyPair> const& _accounts)
{
m_accounts.clear();
for (auto const& keyPair: _accounts)
{
m_accounts.push_back(keyPair.address());
m_keyPairs[keyPair.address()] = keyPair;
}
}
vector<Address> AccountHolder::getAllAccounts() const
{
vector<Address> accounts = m_accounts;
for (auto const& pair: m_proxyAccounts)
if (!isRealAccount(pair.first))
accounts.push_back(pair.first);
return accounts;
}
Address const& AccountHolder::getDefaultTransactAccount() const
{
if (m_accounts.empty())
return ZeroAddress;
Address const* bestMatch = &m_accounts.front();
for (auto const& account: m_accounts)
if (m_client()->balanceAt(account) > m_client()->balanceAt(*bestMatch))
bestMatch = &account;
return *bestMatch;
}
int AccountHolder::addProxyAccount(const Address& _account)
{
Guard g(x_rngMutex);
int id = std::uniform_int_distribution<int>(1)(g_randomNumberGenerator);
id = int(u256(FixedHash<32>(sha3(bytesConstRef((byte*)(&id), sizeof(int) / sizeof(byte))))));
if (isProxyAccount(_account) || id == 0 || m_transactionQueues.count(id))
return 0;
m_proxyAccounts.insert(make_pair(_account, id));
m_transactionQueues[id].first = _account;
return id;
}
bool AccountHolder::removeProxyAccount(unsigned _id)
{
if (!m_transactionQueues.count(_id))
return false;
m_proxyAccounts.erase(m_transactionQueues[_id].first);
m_transactionQueues.erase(_id);
return true;
}
void AccountHolder::queueTransaction(TransactionSkeleton const& _transaction)
{
if (!m_proxyAccounts.count(_transaction.from))
return;
int id = m_proxyAccounts[_transaction.from];
m_transactionQueues[id].second.push_back(_transaction);
}
vector<TransactionSkeleton> const& AccountHolder::getQueuedTransactions(int _id) const
{
if (!m_transactionQueues.count(_id))
return g_emptyQueue;
return m_transactionQueues.at(_id).second;
}
void AccountHolder::clearQueue(int _id)
{
if (m_transactionQueues.count(_id))
m_transactionQueues.at(_id).second.clear();
}

74
libweb3jsonrpc/AccountHolder.h

@ -0,0 +1,74 @@
/*
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 AccountHolder.h
* @authors:
* Christian R <c@ethdev.com>
* Lefteris Karapetsas <lefteris@ethdev.com>
* @date 2015
*/
#pragma once
#include <functional>
#include <vector>
#include <map>
#include <libdevcrypto/Common.h>
#include <libethcore/CommonJS.h>
namespace dev
{
namespace eth
{
class Interface;
}
/**
* Manages real accounts (where we know the secret key) and proxy accounts (where transactions
* to be sent from these accounts are forwarded to a proxy on the other side).
*/
class AccountHolder
{
public:
explicit AccountHolder(std::function<eth::Interface*()> const& _client): m_client(_client) {}
/// Sets or resets the list of real accounts.
void setAccounts(std::vector<KeyPair> const& _accounts);
std::vector<Address> const& getRealAccounts() const { return m_accounts; }
bool isRealAccount(Address const& _account) const { return m_keyPairs.count(_account) > 0; }
bool isProxyAccount(Address const& _account) const { return m_proxyAccounts.count(_account) > 0; }
Secret const& secretKey(Address const& _account) const { return m_keyPairs.at(_account).secret(); }
std::vector<Address> getAllAccounts() const;
Address const& getDefaultTransactAccount() const;
int addProxyAccount(Address const& _account);
bool removeProxyAccount(unsigned _id);
void queueTransaction(eth::TransactionSkeleton const& _transaction);
std::vector<eth::TransactionSkeleton> const& getQueuedTransactions(int _id) const;
void clearQueue(int _id);
private:
using TransactionQueue = std::vector<eth::TransactionSkeleton>;
std::map<Address, KeyPair> m_keyPairs;
std::vector<Address> m_accounts;
std::map<Address, int> m_proxyAccounts;
std::map<int, std::pair<Address, TransactionQueue>> m_transactionQueues;
std::function<eth::Interface*()> m_client;
};
}

108
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -35,11 +35,13 @@
#include <libserpent/funcs.h>
#endif
#include "WebThreeStubServerBase.h"
#include "AccountHolder.h"
using namespace std;
using namespace dev;
using namespace dev::eth;
static Json::Value toJson(dev::eth::BlockInfo const& _bi)
{
Json::Value res;
@ -72,6 +74,18 @@ static Json::Value toJson(dev::eth::Transaction const& _t)
return res;
}
static Json::Value toJson(dev::eth::TransactionSkeleton const& _t)
{
Json::Value res;
res["to"] = toJS(_t.to);
res["from"] = toJS(_t.from);
res["gas"] = toJS(_t.gas);
res["gasPrice"] = toJS(_t.gasPrice);
res["value"] = toJS(_t.value);
res["data"] = jsFromBinary(_t.data);
return res;
}
static Json::Value toJson(dev::eth::LocalisedLogEntry const& _e)
{
Json::Value res;
@ -212,19 +226,9 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message
}
WebThreeStubServerBase::WebThreeStubServerBase(jsonrpc::AbstractServerConnector& _conn, std::vector<dev::KeyPair> const& _accounts):
AbstractWebThreeStubServer(_conn)
{
setAccounts(_accounts);
}
void WebThreeStubServerBase::setAccounts(std::vector<dev::KeyPair> const& _accounts)
AbstractWebThreeStubServer(_conn), m_accounts(make_shared<AccountHolder>(std::bind(&WebThreeStubServerBase::client, this)))
{
m_accounts.clear();
for (auto const& i: _accounts)
{
m_accounts.push_back(i.address());
m_accountsLookup[i.address()] = i;
}
m_accounts->setAccounts(_accounts);
}
void WebThreeStubServerBase::setIdentities(std::vector<dev::KeyPair> const& _ids)
@ -242,7 +246,7 @@ std::string WebThreeStubServerBase::web3_sha3(std::string const& _param1)
Json::Value WebThreeStubServerBase::eth_accounts()
{
Json::Value ret(Json::arrayValue);
for (auto const& i: m_accounts)
for (auto const& i: m_accounts->getAllAccounts())
ret.append(toJS(i));
return ret;
}
@ -326,21 +330,15 @@ std::string WebThreeStubServerBase::eth_call(Json::Value const& _json)
{
std::string ret;
TransactionSkeleton t = toTransaction(_json);
if (!t.from && m_accounts.size())
{
auto b = m_accounts.front();
for (auto const& a: m_accounts)
if (client()->balanceAt(a) > client()->balanceAt(b))
b = a;
t.from = b;
}
if (!m_accountsLookup.count(t.from))
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
if (!m_accounts->isRealAccount(t.from))
return ret;
if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo;
if (!t.gas)
t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice);
ret = toJS(client()->call(m_accountsLookup[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice));
ret = toJS(client()->call(m_accounts->secretKey(t.from), t.value, t.to, t.data, t.gas, t.gasPrice));
return ret;
}
@ -464,6 +462,25 @@ bool WebThreeStubServerBase::eth_submitWork(std::string const& _nonce)
return client()->submitNonce(jsToFixed<32>(_nonce));
}
int WebThreeStubServerBase::eth_register(std::string const& _address)
{
return m_accounts->addProxyAccount(jsToAddress(_address));
}
bool WebThreeStubServerBase::eth_unregister(int _id)
{
return m_accounts->removeProxyAccount(_id);
}
Json::Value WebThreeStubServerBase::eth_queuedTransactions(int _id)
{
Json::Value ret(Json::arrayValue);
for (TransactionSkeleton const& t: m_accounts->getQueuedTransactions(_id))
ret.append(toJson(t));
m_accounts->clearQueue(_id);
return ret;
}
std::string WebThreeStubServerBase::shh_newGroup(std::string const& _id, std::string const& _who)
{
(void)_id;
@ -542,7 +559,7 @@ std::string WebThreeStubServerBase::eth_solidity(std::string const& _code)
int WebThreeStubServerBase::eth_number()
{
return client()->number() + 1;
return client()->number();
}
int WebThreeStubServerBase::eth_peerCount()
@ -684,36 +701,31 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json)
{
std::string ret;
TransactionSkeleton t = toTransaction(_json);
if (!t.from && m_accounts.size())
{
auto b = m_accounts.front();
for (auto const& a: m_accounts)
if (client()->balanceAt(a) > client()->balanceAt(b))
b = a;
t.from = b;
}
if (!m_accountsLookup.count(t.from))
return ret;
if (t.creation)
ret = right160(sha3(rlpList(t.from, client()->countAt(t.from))));;
if (!t.from)
t.from = m_accounts->getDefaultTransactAccount();
if (!t.gasPrice)
t.gasPrice = 10 * dev::eth::szabo;
if (!t.gas)
t.gas = min<u256>(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice);
if (authenticate(t))
{
if (t.to)
// TODO: from qethereum, insert validification hook here.
client()->transact(m_accountsLookup[t.from].secret(), t.value, t.to, t.data, t.gas, t.gasPrice);
else
ret = toJS(client()->transact(m_accountsLookup[t.from].secret(), t.value, t.data, t.gas, t.gasPrice));
client()->flushTransactions();
}
if (m_accounts->isRealAccount(t.from))
authenticate(t, false);
else if (m_accounts->isProxyAccount(t.from))
authenticate(t, true);
return ret;
}
bool WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t)
void WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t, bool _toProxy)
{
cwarn << "Silently signing transaction from address" << _t.from.abridged() << ": User validation hook goes here.";
return true;
if (_toProxy)
m_accounts->queueTransaction(_t);
else if (_t.to)
client()->transact(m_accounts->secretKey(_t.from), _t.value, _t.to, _t.data, _t.gas, _t.gasPrice);
else
client()->transact(m_accounts->secretKey(_t.from), _t.value, _t.data, _t.gas, _t.gasPrice);
}
Json::Value WebThreeStubServerBase::eth_transactionByHash(std::string const& _hash, int _i)
@ -742,3 +754,7 @@ bool WebThreeStubServerBase::eth_uninstallFilter(int _id)
return true;
}
void WebThreeStubServerBase::setAccounts(const std::vector<KeyPair>& _accounts)
{
m_accounts->setAccounts(_accounts);
}

12
libweb3jsonrpc/WebThreeStubServerBase.h

@ -23,6 +23,7 @@
#pragma once
#include <memory>
#include <iostream>
#include <jsonrpccpp/server.h>
#include <libdevcrypto/Common.h>
@ -35,6 +36,7 @@
namespace dev
{
class WebThreeNetworkFace;
class AccountHolder;
class KeyPair;
namespace eth
{
@ -110,6 +112,10 @@ public:
virtual Json::Value eth_getWork();
virtual bool eth_submitWork(std::string const& _nonce);
virtual int eth_register(std::string const& _address);
virtual bool eth_unregister(int _id);
virtual Json::Value eth_queuedTransactions(int _id);
virtual std::string db_get(std::string const& _name, std::string const& _key);
virtual std::string db_getString(std::string const& _name, std::string const& _key);
virtual bool db_put(std::string const& _name, std::string const& _key, std::string const& _value);
@ -130,7 +136,7 @@ public:
std::map<dev::Public, dev::Secret> const& ids() const { return m_ids; }
protected:
virtual bool authenticate(dev::eth::TransactionSkeleton const& _t);
virtual void authenticate(dev::eth::TransactionSkeleton const& _t, bool _toProxy);
protected:
virtual dev::eth::Interface* client() = 0;
@ -138,11 +144,9 @@ protected:
virtual dev::WebThreeNetworkFace* network() = 0;
virtual dev::WebThreeStubDatabaseFace* db() = 0;
std::map<dev::Address, dev::KeyPair> m_accountsLookup;
std::vector<dev::Address> m_accounts;
std::map<dev::Public, dev::Secret> m_ids;
std::map<unsigned, dev::Public> m_shhWatches;
std::shared_ptr<dev::AccountHolder> m_accounts;
};
} //namespace dev

18
libweb3jsonrpc/abstractwebthreestubserver.h

@ -55,6 +55,9 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
this->bindAndAddMethod(jsonrpc::Procedure("eth_logs", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_OBJECT, NULL), &AbstractWebThreeStubServer::eth_logsI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_getWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, NULL), &AbstractWebThreeStubServer::eth_getWorkI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_submitWork", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_submitWorkI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_register", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_INTEGER, "param1",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::eth_registerI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_unregister", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_unregisterI);
this->bindAndAddMethod(jsonrpc::Procedure("eth_queuedTransactions", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_ARRAY, "param1",jsonrpc::JSON_INTEGER, NULL), &AbstractWebThreeStubServer::eth_queuedTransactionsI);
this->bindAndAddMethod(jsonrpc::Procedure("db_put", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putI);
this->bindAndAddMethod(jsonrpc::Procedure("db_get", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_STRING, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_getI);
this->bindAndAddMethod(jsonrpc::Procedure("db_putString", jsonrpc::PARAMS_BY_POSITION, jsonrpc::JSON_BOOLEAN, "param1",jsonrpc::JSON_STRING,"param2",jsonrpc::JSON_STRING,"param3",jsonrpc::JSON_STRING, NULL), &AbstractWebThreeStubServer::db_putStringI);
@ -253,6 +256,18 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
{
response = this->eth_submitWork(request[0u].asString());
}
inline virtual void eth_registerI(const Json::Value &request, Json::Value &response)
{
response = this->eth_register(request[0u].asString());
}
inline virtual void eth_unregisterI(const Json::Value &request, Json::Value &response)
{
response = this->eth_unregister(request[0u].asInt());
}
inline virtual void eth_queuedTransactionsI(const Json::Value &request, Json::Value &response)
{
response = this->eth_queuedTransactions(request[0u].asInt());
}
inline virtual void db_putI(const Json::Value &request, Json::Value &response)
{
response = this->db_put(request[0u].asString(), request[1u].asString(), request[2u].asString());
@ -349,6 +364,9 @@ class AbstractWebThreeStubServer : public jsonrpc::AbstractServer<AbstractWebThr
virtual Json::Value eth_logs(const Json::Value& param1) = 0;
virtual Json::Value eth_getWork() = 0;
virtual bool eth_submitWork(const std::string& param1) = 0;
virtual int eth_register(const std::string& param1) = 0;
virtual bool eth_unregister(int param1) = 0;
virtual Json::Value eth_queuedTransactions(int param1) = 0;
virtual bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) = 0;
virtual std::string db_get(const std::string& param1, const std::string& param2) = 0;
virtual bool db_putString(const std::string& param1, const std::string& param2, const std::string& param3) = 0;

4
libweb3jsonrpc/spec.json

@ -50,6 +50,10 @@
{ "name": "eth_getWork", "params": [], "order": [], "returns": []},
{ "name": "eth_submitWork", "params": [""], "order": [], "returns": true},
{ "name": "eth_register", "params": [""], "order": [], "returns": 0},
{ "name": "eth_unregister", "params": [0], "order": [], "returns": true},
{ "name": "eth_queuedTransactions", "params": [0], "order": [], "returns": []},
{ "name": "db_put", "params": ["", "", ""], "order": [], "returns": true},
{ "name": "db_get", "params": ["", ""], "order": [], "returns": ""},
{ "name": "db_putString", "params": ["", "", ""], "order": [], "returns": true},

14
mix/qml/Debugger.qml

@ -164,7 +164,7 @@ Rectangle {
Rectangle {
// step button + slider
id: buttonRow
height: 27
height: 30
Layout.fillWidth: true
color: "transparent"
@ -184,7 +184,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoutback.png"
disableStateImg: "qrc:/qml/img/jumpoutbackdisabled.png"
onClicked: Debugger.stepOutBack()
width: 28
width: 30
height: 30
buttonShortcut: "Ctrl+Shift+F11"
buttonTooltip: qsTr("Step Out Back")
@ -196,7 +196,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpintoback.png"
disableStateImg: "qrc:/qml/img/jumpintobackdisabled.png"
onClicked: Debugger.stepIntoBack()
width: 28
width: 30
height: 30
buttonShortcut: "Ctrl+F11"
buttonTooltip: qsTr("Step Into Back")
@ -208,7 +208,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoverback.png"
disableStateImg: "qrc:/qml/img/jumpoverbackdisabled.png"
onClicked: Debugger.stepOverBack()
width: 28
width: 30
height: 30
buttonShortcut: "Ctrl+F10"
buttonTooltip: qsTr("Step Over Back")
@ -220,7 +220,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoverforward.png"
disableStateImg: "qrc:/qml/img/jumpoverforwarddisabled.png"
onClicked: Debugger.stepOverForward()
width: 28
width: 30
height: 30
buttonShortcut: "F10"
buttonTooltip: qsTr("Step Over Forward")
@ -232,7 +232,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpintoforward.png"
disableStateImg: "qrc:/qml/img/jumpintoforwarddisabled.png"
onClicked: Debugger.stepIntoForward()
width: 28
width: 30
height: 30
buttonShortcut: "F11"
buttonTooltip: qsTr("Step Into Forward")
@ -244,7 +244,7 @@ Rectangle {
enabledStateImg: "qrc:/qml/img/jumpoutforward.png"
disableStateImg: "qrc:/qml/img/jumpoutforwarddisabled.png"
onClicked: Debugger.stepOutForward()
width: 28
width: 30
height: 30
buttonShortcut: "Shift+F11"
buttonTooltip: qsTr("Step Out Forward")

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save