Browse Source

Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into mix_cm

cl-refactor
arkpar 10 years ago
parent
commit
a1380361c4
  1. 12
      alethzero/MainWin.cpp
  2. 4
      alethzero/MainWin.h
  3. 34
      alethzero/OurWebThreeStubServer.cpp
  4. 18
      alethzero/OurWebThreeStubServer.h
  5. 14
      evmjit/libevmjit/Compiler.cpp
  6. 8
      libethereum/Executive.cpp
  7. 761
      libjsqrc/ethereumjs/dist/ethereum.js
  8. 26
      libjsqrc/ethereumjs/dist/ethereum.js.map
  9. 2
      libjsqrc/ethereumjs/dist/ethereum.min.js
  10. 18
      libjsqrc/ethereumjs/example/balance.html
  11. 16
      libjsqrc/ethereumjs/example/contract.html
  12. 23
      libjsqrc/ethereumjs/example/natspec_contract.html
  13. 8
      libjsqrc/ethereumjs/index.js
  14. 56
      libjsqrc/ethereumjs/lib/abi.js
  15. 114
      libjsqrc/ethereumjs/lib/autoprovider.js
  16. 88
      libjsqrc/ethereumjs/lib/contract.js
  17. 27
      libjsqrc/ethereumjs/lib/filter.js
  18. 126
      libjsqrc/ethereumjs/lib/httprpc.js
  19. 66
      libjsqrc/ethereumjs/lib/httpsync.js
  20. 63
      libjsqrc/ethereumjs/lib/providermanager.js
  21. 57
      libjsqrc/ethereumjs/lib/qt.js
  22. 32
      libjsqrc/ethereumjs/lib/qtsync.js
  23. 174
      libjsqrc/ethereumjs/lib/web3.js
  24. 98
      libjsqrc/ethereumjs/lib/websocket.js
  25. 7
      libjsqrc/ethereumjs/test/abi.parsers.js
  26. 1
      libjsqrc/ethereumjs/test/db.methods.js
  27. 1
      libjsqrc/ethereumjs/test/eth.methods.js
  28. 1
      libjsqrc/ethereumjs/test/shh.methods.js
  29. 2
      libjsqrc/ethereumjs/test/utils.js
  30. 1
      libjsqrc/ethereumjs/test/web3.methods.js
  31. 1
      libjsqrc/js.qrc
  32. 69
      libjsqrc/natspec.js
  33. 17
      libjsqrc/setup.js
  34. 115
      libqwebthree/QWebThree.cpp
  35. 9
      libqwebthree/QWebThree.h
  36. 6
      libweb3jsonrpc/CorsHttpServer.cpp
  37. 2
      libweb3jsonrpc/CorsHttpServer.h
  38. 2
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  39. 2
      libweb3jsonrpc/WebThreeStubServerBase.h
  40. 5
      mix/ClientModel.cpp
  41. 31
      test/stSpecialTestFiller.json
  42. 4
      third/MainWin.cpp

12
alethzero/MainWin.cpp

@ -102,7 +102,7 @@ static vector<KeyPair> keysAsVector(QList<KeyPair> const& keys)
return {begin(list), end(list)};
}
static QString contentsOfQResource(string const& res)
QString contentsOfQResource(string const& res)
{
QFile file(QString::fromStdString(res));
if (!file.open(QFile::ReadOnly))
@ -178,13 +178,13 @@ Main::Main(QWidget *parent) :
QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qweb));
connect(m_qweb, SIGNAL(onNewId(QString)), this, SLOT(addNewId(QString)));
});
connect(ui->webView, &QWebView::loadFinished, [=]()
{
m_qweb->poll();
});
connect(ui->webView, &QWebView::titleChanged, [=]()
@ -434,6 +434,11 @@ void Main::on_jsInput_returnPressed()
ui->jsInput->setText("");
}
QVariant Main::evalRaw(QString const& _js)
{
return ui->webView->page()->currentFrame()->evaluateJavaScript(_js);
}
void Main::eval(QString const& _js)
{
if (_js.trimmed().isEmpty())
@ -1179,9 +1184,6 @@ void Main::timerEvent(QTimerEvent*)
else
interval += 100;
if (m_qweb)
m_qweb->poll();
for (auto const& i: m_handlers)
{
auto ls = ethereum()->checkWatch(i.first);

4
alethzero/MainWin.h

@ -71,6 +71,8 @@ struct WorldState
using WatchHandler = std::function<void(dev::eth::LocalisedLogEntries const&)>;
QString contentsOfQResource(std::string const& res);
class Main : public QMainWindow
{
Q_OBJECT
@ -87,6 +89,8 @@ public:
std::string lookupNatSpecUserNotice(dev::h256 const& _contractHash, dev::bytes const& _transactionData);
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
QVariant evalRaw(QString const& _js);
public slots:
void load(QString _file);

34
alethzero/OurWebThreeStubServer.cpp

@ -24,6 +24,7 @@
#include <QMessageBox>
#include <QAbstractButton>
#include <libwebthree/WebThree.h>
#include "MainWin.h"
using namespace std;
@ -54,7 +55,7 @@ bool OurWebThreeStubServer::showAuthenticationPopup(std::string const& _title, s
return userInput.exec() == QMessageBox::Ok;
}
bool OurWebThreeStubServer::authenticate(dev::TransactionSkeleton const& _t) const
bool OurWebThreeStubServer::authenticate(dev::TransactionSkeleton const& _t)
{
h256 contractCodeHash = m_web3->ethereum()->postState().codeHash(_t.to);
if (contractCodeHash == EmptySHA3)
@ -63,10 +64,41 @@ bool OurWebThreeStubServer::authenticate(dev::TransactionSkeleton const& _t) con
return true;
std::string userNotice = m_main->lookupNatSpecUserNotice(contractCodeHash, _t.data);
if (userNotice.empty())
return showAuthenticationPopup("Unverified Pending Transaction",
"An undocumented transaction is about to be executed.");
QNatspecExpressionEvaluator evaluator(this, m_main);
userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString();
// otherwise it's a transaction to a contract for which we have the natspec
return showAuthenticationPopup("Pending Transaction", userNotice);
}
QNatspecExpressionEvaluator::QNatspecExpressionEvaluator(OurWebThreeStubServer* _server, Main* _main)
: m_server(_server), m_main(_main)
{}
QNatspecExpressionEvaluator::~QNatspecExpressionEvaluator()
{}
QString QNatspecExpressionEvaluator::evalExpression(QString const& _expression)
{
// evaluate the natspec
m_main->evalRaw(contentsOfQResource(":/js/natspec.js"));
// _expression should be in the format like this
// auto toEval = QString::fromStdString("the result of calling multiply(4) is `multiply(4)`");
auto toEval = _expression;
auto result = m_main->evalRaw("evaluateExpression('" + toEval + "')");
return result.toString();
}

18
alethzero/OurWebThreeStubServer.h

@ -35,7 +35,7 @@ public:
std::vector<dev::KeyPair> const& _accounts, Main* main);
virtual std::string shh_newIdentity() override;
virtual bool authenticate(dev::TransactionSkeleton const& _t) const;
virtual bool authenticate(dev::TransactionSkeleton const& _t);
signals:
void onNewId(QString _s);
@ -46,3 +46,19 @@ private:
dev::WebThreeDirect* m_web3;
Main* m_main;
};
class QNatspecExpressionEvaluator: public QObject
{
Q_OBJECT
public:
QNatspecExpressionEvaluator(OurWebThreeStubServer* _server, Main* _main);
virtual ~QNatspecExpressionEvaluator();
QString evalExpression(QString const& _expression);
private:
OurWebThreeStubServer* m_server;
Main* m_main;
};

14
evmjit/libevmjit/Compiler.cpp

@ -450,13 +450,17 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
auto word = stack.pop();
auto k32_ = m_builder.CreateTrunc(idx, m_builder.getIntNTy(5), "k_32");
auto k32 = m_builder.CreateZExt(k32_, Type::Word);
auto k32x8 = m_builder.CreateMul(k32, Constant::get(8), "kx8");
auto k32 = m_builder.CreateZExt(k32_, Type::lowPrecision);
auto k32x8 = m_builder.CreateMul(k32, m_builder.getInt64(8), "kx8");
// test for word >> (k * 8 + 7)
auto bitpos = m_builder.CreateAdd(k32x8, Constant::get(7), "bitpos");
auto bitval = m_builder.CreateLShr(word, bitpos, "bitval");
auto bittest = m_builder.CreateTrunc(bitval, Type::Bool, "bittest");
auto bitpos = m_builder.CreateAdd(k32x8, m_builder.getInt64(7), "bitpos");
auto bittester = m_builder.CreateShl(Constant::get(1), bitpos);
auto bitresult = m_builder.CreateAnd(word, bittester);
auto bittest = m_builder.CreateICmpUGT(bitresult, Constant::get(0));
// FIXME: The following does not work - LLVM bug, report!
//auto bitval = m_builder.CreateLShr(word, bitpos, "bitval");
//auto bittest = m_builder.CreateTrunc(bitval, Type::Bool, "bittest");
auto mask_ = m_builder.CreateShl(Constant::get(1), bitpos);
auto mask = m_builder.CreateSub(mask_, Constant::get(1), "mask");

8
libethereum/Executive.cpp

@ -72,17 +72,17 @@ bool Executive::setup(bytesConstRef _rlp)
BOOST_THROW_EXCEPTION(OutOfGas() << RequirementError((bigint)gasCost, (bigint)m_t.gas()));
}
u256 cost = m_t.value() + m_t.gas() * m_t.gasPrice();
bigint cost = m_t.value() + (bigint)m_t.gas() * m_t.gasPrice();
// Avoid unaffordable transactions.
if (m_s.balance(m_t.sender()) < cost)
{
clog(StateDetail) << "Not enough cash: Require >" << cost << " Got" << m_s.balance(m_t.sender());
BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError((bigint)cost, (bigint)m_s.balance(m_t.sender())));
BOOST_THROW_EXCEPTION(NotEnoughCash() << RequirementError(cost, (bigint)m_s.balance(m_t.sender())));
}
u256 startGasUsed = m_s.gasUsed();
if (startGasUsed + m_t.gas() > m_s.m_currentBlock.gasLimit)
if (startGasUsed + (bigint)m_t.gas() > m_s.m_currentBlock.gasLimit)
{
clog(StateDetail) << "Too much gas used in this block: Require <" << (m_s.m_currentBlock.gasLimit - startGasUsed) << " Got" << m_t.gas();
BOOST_THROW_EXCEPTION(BlockGasLimitReached() << RequirementError((bigint)(m_s.m_currentBlock.gasLimit - startGasUsed), (bigint)m_t.gas()));
@ -92,7 +92,7 @@ bool Executive::setup(bytesConstRef _rlp)
m_s.noteSending(m_t.sender());
// Pay...
clog(StateDetail) << "Paying" << formatBalance(cost) << "from sender (includes" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")";
clog(StateDetail) << "Paying" << formatBalance(u256(cost)) << "from sender (includes" << m_t.gas() << "gas at" << formatBalance(m_t.gasPrice()) << ")";
m_s.subBalance(m_t.sender(), cost);
if (m_t.isCreation())

761
libjsqrc/ethereumjs/dist/ethereum.js

File diff suppressed because it is too large

26
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

18
libjsqrc/ethereumjs/example/balance.html

@ -8,23 +8,21 @@
<script type="text/javascript">
var web3 = require('web3');
web3.setProvider(new web3.providers.AutoProvider());
web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8080'));
function watchBalance() {
var coinbase = web3.eth.coinbase;
var originalBalance = 0;
web3.eth.balanceAt(coinbase).then(function (balance) {
originalBalance = web3.toDecimal(balance);
document.getElementById('original').innerText = 'original balance: ' + originalBalance + ' watching...';
});
var balance = web3.eth.balanceAt(coinbase);
var originalBalance = web3.toDecimal(balance);
document.getElementById('original').innerText = 'original balance: ' + originalBalance + ' watching...';
web3.eth.watch({altered: coinbase}).changed(function() {
web3.eth.balanceAt(coinbase).then(function (balance) {
var currentBalance = web3.toDecimal(balance);
document.getElementById("current").innerText = 'current: ' + currentBalance;
document.getElementById("diff").innerText = 'diff: ' + (currentBalance - originalBalance);
});
balance = web3.eth.balanceAt(coinbase)
var currentBalance = web3.toDecimal(balance);
document.getElementById("current").innerText = 'current: ' + currentBalance;
document.getElementById("diff").innerText = 'diff: ' + (currentBalance - originalBalance);
});
}

16
libjsqrc/ethereumjs/example/contract.html

@ -8,7 +8,7 @@
<script type="text/javascript">
var web3 = require('web3');
web3.setProvider(new web3.providers.AutoProvider());
web3.setProvider(new web3.providers.HttpSyncProvider());
// solidity source code
var source = "" +
@ -20,7 +20,7 @@
// contract description, this will be autogenerated somehow
var desc = [{
"name": "multiply",
"name": "multiply(uint256)",
"inputs": [
{
"name": "a",
@ -43,10 +43,9 @@
document.getElementById('source').innerText = source;
// create contract
web3.eth.transact({code: web3.eth.solidity(source)}).then(function (address) {
contract = web3.eth.contract(address, desc);
document.getElementById('call').style.visibility = 'visible';
});
var address = web3.eth.transact({code: web3.eth.solidity(source)});
contract = web3.eth.contract(address, desc);
document.getElementById('call').style.visibility = 'visible';
}
function callExampleContract() {
@ -54,9 +53,8 @@
var param = parseInt(document.getElementById('value').value);
// call the contract
contract.multiply(param).call().then(function(res) {
document.getElementById('result').innerText = res[0];
});
var res = contract.multiply(param);
document.getElementById('result').innerText = res[0];
}
</script>

23
libjsqrc/ethereumjs/example/natspec_contract.html

@ -3,16 +3,18 @@
<head>
<script type="text/javascript" src="js/es6-promise/promise.min.js"></script>
<script type="text/javascript" src="js/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript" src="../../natspec.js"></script>
<script type="text/javascript">
var web3 = require('web3');
web3.setProvider(new web3.providers.AutoProvider());
web3.setProvider(new web3.providers.QtSyncProvider());
// solidity source code
var source = "" +
"contract test {\n" +
" /// @notice Will multiplty `a` by 7. \n" +
" /// @notice Will multiply `a` by 7. \n" +
" function multiply(uint a) returns(uint d) {\n" +
" return a * 7;\n" +
" }\n" +
@ -20,7 +22,7 @@
// contract description, this will be autogenerated somehow
var desc = [{
"name": "multiply",
"name": "multiply(uint256)",
"inputs": [
{
"name": "a",
@ -43,20 +45,19 @@
document.getElementById('source').innerText = source;
// create contract
web3.eth.transact({code: web3.eth.solidity(source)}).then(function (address) {
contract = web3.contract(address, desc);
document.getElementById('call').style.visibility = 'visible';
});
var address = web3.eth.transact({code: web3.eth.solidity(source)});
contract = web3.eth.contract(address, desc);
document.getElementById('call').style.visibility = 'visible';
}
function callExampleContract() {
// this should be generated by ethereum
var param = parseInt(document.getElementById('value').value);
// call the contract
contract.multiply(param).transact().then(function(res) {
document.getElementById('result').innerText = res[0];
});
// transaction does not return any result, cause it's not synchronous and we don't know,
// when it will be processed
contract.transact().multiply(param);
document.getElementById('result').innerText = 'transaction made';
}
</script>

8
libjsqrc/ethereumjs/index.js

@ -2,10 +2,10 @@ var web3 = require('./lib/web3');
var ProviderManager = require('./lib/providermanager');
web3.provider = new ProviderManager();
web3.filter = require('./lib/filter');
web3.providers.WebSocketProvider = require('./lib/websocket');
web3.providers.HttpRpcProvider = require('./lib/httprpc');
web3.providers.QtProvider = require('./lib/qt');
web3.providers.AutoProvider = require('./lib/autoprovider');
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;

56
libjsqrc/ethereumjs/lib/abi.js

@ -32,6 +32,9 @@ BigNumber.config({ ROUNDING_MODE: BigNumber.ROUND_DOWN });
var ETH_PADDING = 32;
/// method signature length in bytes
var ETH_METHOD_SIGNATURE_LENGTH = 4;
/// Finds first index of array element matching pattern
/// @param array
/// @param callback pattern
@ -330,15 +333,37 @@ var fromAbiOutput = function (json, methodName, output) {
return result;
};
/// @returns display name for method eg. multiply(uint256) -> multiply
var methodDisplayName = function (method) {
var length = method.indexOf('(');
return length !== -1 ? method.substr(0, length) : method;
};
/// @returns overloaded part of method's name
var methodTypeName = function (method) {
/// TODO: make it not vulnerable
var length = method.indexOf('(');
return length !== -1 ? method.substr(length + 1, method.length - 1 - (length + 1)) : "";
};
/// @param json abi for contract
/// @returns input parser object for given json abi
var inputParser = function (json) {
var parser = {};
json.forEach(function (method) {
parser[method.name] = function () {
var displayName = methodDisplayName(method.name);
var typeName = methodTypeName(method.name);
var impl = function () {
var params = Array.prototype.slice.call(arguments);
return toAbiInput(json, method.name, params);
};
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
parser[displayName][typeName] = impl;
});
return parser;
@ -349,32 +374,35 @@ var inputParser = function (json) {
var outputParser = function (json) {
var parser = {};
json.forEach(function (method) {
parser[method.name] = function (output) {
var displayName = methodDisplayName(method.name);
var typeName = methodTypeName(method.name);
var impl = function (output) {
return fromAbiOutput(json, method.name, output);
};
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
parser[displayName][typeName] = impl;
});
return parser;
};
/// @param json abi for contract
/// @param method name for which we want to get method signature
/// @returns (promise) contract method signature for method with given name
var methodSignature = function (json, name) {
var method = json[findMethodIndex(json, name)];
var result = name + '(';
var inputTypes = method.inputs.map(function (inp) {
return inp.type;
});
result += inputTypes.join(',');
result += ')';
return web3.sha3(web3.fromAscii(result));
var methodSignature = function (name) {
return web3.sha3(web3.fromAscii(name)).slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2);
};
module.exports = {
inputParser: inputParser,
outputParser: outputParser,
methodSignature: methodSignature
methodSignature: methodSignature,
methodDisplayName: methodDisplayName,
methodTypeName: methodTypeName
};

114
libjsqrc/ethereumjs/lib/autoprovider.js

@ -1,114 +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 autoprovider.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* @date 2014
*/
/*
* @brief if qt object is available, uses QtProvider,
* if not tries to connect over websockets
* if it fails, it uses HttpRpcProvider
*/
var web3 = require('./web3'); // jshint ignore:line
if (process.env.NODE_ENV !== 'build') {
var WebSocket = require('ws'); // jshint ignore:line
}
/**
* AutoProvider object prototype is implementing 'provider protocol'
* Automatically tries to setup correct provider(Qt, WebSockets or HttpRpc)
* First it checkes if we are ethereum browser (if navigator.qt object is available)
* if yes, we are using QtProvider
* if no, we check if it is possible to establish websockets connection with ethereum (ws://localhost:40404/eth is default)
* if it's not possible, we are using httprpc provider (http://localhost:8080)
* The constructor allows you to specify uris on which we are trying to connect over http or websockets
* You can do that by passing objects with fields httrpc and websockets
*/
var AutoProvider = function (userOptions) {
if (web3.haveProvider()) {
return;
}
// before we determine what provider we are, we have to cache request
this.sendQueue = [];
this.onmessageQueue = [];
if (navigator.qt) {
this.provider = new web3.providers.QtProvider();
return;
}
userOptions = userOptions || {};
var options = {
httprpc: userOptions.httprpc || 'http://localhost:8080',
websockets: userOptions.websockets || 'ws://localhost:40404/eth'
};
var self = this;
var closeWithSuccess = function (success) {
ws.close();
if (success) {
self.provider = new web3.providers.WebSocketProvider(options.websockets);
} else {
self.provider = new web3.providers.HttpRpcProvider(options.httprpc);
self.poll = self.provider.poll.bind(self.provider);
}
self.sendQueue.forEach(function (payload) {
self.provider.send(payload);
});
self.onmessageQueue.forEach(function (handler) {
self.provider.onmessage = handler;
});
};
var ws = new WebSocket(options.websockets);
ws.onopen = function() {
closeWithSuccess(true);
};
ws.onerror = function() {
closeWithSuccess(false);
};
};
/// Sends message forward to the provider, that is being used
/// if provider is not yet set, enqueues the message
AutoProvider.prototype.send = function (payload) {
if (this.provider) {
this.provider.send(payload);
return;
}
this.sendQueue.push(payload);
};
/// On incoming message sends the message to the provider that is currently being used
Object.defineProperty(AutoProvider.prototype, 'onmessage', {
set: function (handler) {
if (this.provider) {
this.provider.onmessage = handler;
return;
}
this.onmessageQueue.push(handler);
}
});
module.exports = AutoProvider;

88
libjsqrc/ethereumjs/lib/contract.js

@ -23,9 +23,6 @@
var web3 = require('./web3'); // jshint ignore:line
var abi = require('./abi');
/// method signature length in bytes
var ETH_METHOD_SIGNATURE_LENGTH = 4;
/**
* This method should be called when we want to call / transact some solidity method from javascript
* it returns an object which has same methods available as solidity contract description
@ -39,50 +36,77 @@ var ETH_METHOD_SIGNATURE_LENGTH = 4;
*
* var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object
*
* myContract.myMethod('this is test string param for call').call(); // myMethod call
* myContract.myMethod('this is test string param for transact').transact() // myMethod transact
* myContract.myMethod('this is test string param for call'); // myMethod call (implicit, default)
* myContract.myMethod('this is test string param for call').call(); // myMethod call (explicit)
* myContract.transact().myMethod('this is test string param for transact'); // myMethod transact
*
* @param address - address of the contract, which should be called
* @param desc - abi json description of the contract, which is being created
* @returns contract object
*/
var contract = function (address, desc) {
var inputParser = abi.inputParser(desc);
var outputParser = abi.outputParser(desc);
var contract = {};
var result = {};
result.call = function (options) {
result._isTransact = false;
result._options = options;
return result;
};
result.transact = function (options) {
result._isTransact = true;
result._options = options;
return result;
};
desc.forEach(function (method) {
contract[method.name] = function () {
var displayName = abi.methodDisplayName(method.name);
var typeName = abi.methodTypeName(method.name);
var impl = function () {
var params = Array.prototype.slice.call(arguments);
var parsed = inputParser[method.name].apply(null, params);
var onSuccess = function (result) {
return outputParser[method.name](result);
};
return {
call: function (extra) {
extra = extra || {};
extra.to = address;
return abi.methodSignature(desc, method.name).then(function (signature) {
extra.data = signature.slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2) + parsed;
return web3.eth.call(extra).then(onSuccess);
});
},
transact: function (extra) {
extra = extra || {};
extra.to = address;
return abi.methodSignature(desc, method.name).then(function (signature) {
extra.data = signature.slice(0, 2 + ETH_METHOD_SIGNATURE_LENGTH * 2) + parsed;
return web3.eth.transact(extra).then(onSuccess);
});
}
};
var signature = abi.methodSignature(method.name);
var parsed = inputParser[displayName][typeName].apply(null, params);
var options = result._options || {};
options.to = address;
options.data = signature + parsed;
var isTransact = result._isTransact;
// reset
result._options = {};
result._isTransact = false;
if (isTransact) {
// it's used byt natspec.js
// TODO: figure out better way to solve this
web3._currentContractAbi = desc;
web3._currentContractAddress = address;
// transactions do not have any output, cause we do not know, when they will be processed
web3.eth.transact(options);
return;
}
var output = web3.eth.call(options);
return outputParser[displayName][typeName](output);
};
if (result[displayName] === undefined) {
result[displayName] = impl;
}
result[displayName][typeName] = impl;
});
return contract;
return result;
};
module.exports = contract;

27
libjsqrc/ethereumjs/lib/filter.js

@ -31,13 +31,8 @@ var Filter = function(options, impl) {
this.impl = impl;
this.callbacks = [];
var self = this;
this.promise = impl.newFilter(options);
this.promise.then(function (id) {
self.id = id;
web3.on(impl.changed, id, self.trigger.bind(self));
web3.provider.startPolling({call: impl.changed, args: [id]}, id);
});
this.id = impl.newFilter(options);
web3.provider.startPolling({call: impl.changed, args: [this.id]}, this.id, this.trigger.bind(this));
};
/// alias for changed*
@ -47,10 +42,7 @@ Filter.prototype.arrived = function(callback) {
/// gets called when there is new eth/shh message
Filter.prototype.changed = function(callback) {
var self = this;
this.promise.then(function(id) {
self.callbacks.push(callback);
});
this.callbacks.push(callback);
};
/// trigger calling new message from people
@ -62,20 +54,13 @@ Filter.prototype.trigger = function(messages) {
/// should be called to uninstall current filter
Filter.prototype.uninstall = function() {
var self = this;
this.promise.then(function (id) {
self.impl.uninstallFilter(id);
web3.provider.stopPolling(id);
web3.off(impl.changed, id);
});
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() {
var self = this;
return this.promise.then(function (id) {
return self.impl.getMessages(id);
});
return this.impl.getMessages(this.id);
};
/// alias for messages

126
libjsqrc/ethereumjs/lib/httprpc.js

@ -1,126 +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 httprpc.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* @date 2014
*/
// TODO: is these line is supposed to be here?
if (process.env.NODE_ENV !== 'build') {
var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line
}
/**
* HttpRpcProvider object prototype is implementing 'provider protocol'
* Should be used when we want to connect to ethereum backend over http && jsonrpc
* It's compatible with cpp client
* The contructor allows to specify host uri
* This provider is using in-browser polling mechanism
*/
var HttpRpcProvider = function (host) {
this.handlers = [];
this.host = host;
};
/// Transforms inner message to proper jsonrpc object
/// @param inner message object
/// @returns jsonrpc object
function formatJsonRpcObject(object) {
return {
jsonrpc: '2.0',
method: object.call,
params: object.args,
id: object._id
};
}
/// Transforms jsonrpc object to inner message
/// @param incoming jsonrpc message
/// @returns inner message object
function formatJsonRpcMessage(message) {
var object = JSON.parse(message);
return {
_id: object.id,
data: object.result,
error: object.error
};
}
/// Prototype object method
/// Asynchronously sends request to server
/// @param payload is inner message object
/// @param cb is callback which is being called when response is comes back
HttpRpcProvider.prototype.sendRequest = function (payload, cb) {
var data = formatJsonRpcObject(payload);
var request = new XMLHttpRequest();
request.open("POST", this.host, true);
request.send(JSON.stringify(data));
request.onreadystatechange = function () {
if (request.readyState === 4 && cb) {
cb(request);
}
};
};
/// Prototype object method
/// Should be called when we want to send single api request to server
/// Asynchronous
/// On response it passes message to handlers
/// @param payload is inner message object
HttpRpcProvider.prototype.send = function (payload) {
var self = this;
this.sendRequest(payload, function (request) {
self.handlers.forEach(function (handler) {
handler.call(self, formatJsonRpcMessage(request.responseText));
});
});
};
/// Prototype object method
/// Should be called only for polling requests
/// Asynchronous
/// On response it passege message to handlers, but only if message's result is true or not empty array
/// Otherwise response is being silently ignored
/// @param payload is inner message object
/// @id is id of poll that we are calling
HttpRpcProvider.prototype.poll = function (payload, id) {
var self = this;
this.sendRequest(payload, function (request) {
var parsed = JSON.parse(request.responseText);
if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) {
return;
}
self.handlers.forEach(function (handler) {
handler.call(self, {_event: payload.call, _id: id, data: parsed.result});
});
});
};
/// Prototype object property
/// Should be used to set message handlers for this provider
Object.defineProperty(HttpRpcProvider.prototype, "onmessage", {
set: function (handler) {
this.handlers.push(handler);
}
});
module.exports = HttpRpcProvider;

66
libjsqrc/ethereumjs/lib/httpsync.js

@ -0,0 +1,66 @@
/*
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 httpsync.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* @date 2014
*/
var HttpSyncProvider = function (host) {
this.handlers = [];
this.host = host || 'http://localhost:8080';
};
/// Transforms inner message to proper jsonrpc object
/// @param inner message object
/// @returns jsonrpc object
function formatJsonRpcObject(object) {
return {
jsonrpc: '2.0',
method: object.call,
params: object.args,
id: object._id
};
}
/// Transforms jsonrpc object to inner message
/// @param incoming jsonrpc message
/// @returns inner message object
function formatJsonRpcMessage(message) {
var object = JSON.parse(message);
return {
_id: object.id,
data: object.result,
error: object.error
};
}
HttpSyncProvider.prototype.send = function (payload) {
var data = formatJsonRpcObject(payload);
var request = new XMLHttpRequest();
request.open('POST', this.host, false);
request.send(JSON.stringify(data));
// check request.status
return request.responseText;
};
module.exports = HttpSyncProvider;

63
libjsqrc/ethereumjs/lib/providermanager.js

@ -35,19 +35,26 @@ var web3 = require('./web3'); // jshint ignore:line
* and provider manager polling mechanism is not used
*/
var ProviderManager = function() {
this.queued = [];
this.polls = [];
this.ready = false;
this.provider = undefined;
this.id = 1;
var self = this;
var poll = function () {
if (self.provider && self.provider.poll) {
if (self.provider) {
self.polls.forEach(function (data) {
data.data._id = self.id;
self.id++;
self.provider.poll(data.data, data.id);
var result = self.provider.send(data.data);
result = JSON.parse(result);
// dont call the callback if result is an error, empty array or false
if (result.error || (result.result instanceof Array ? result.result.length === 0 : !result.result)) {
return;
}
data.callback(result);
});
}
setTimeout(poll, 12000);
@ -55,54 +62,32 @@ var ProviderManager = function() {
poll();
};
/// sends outgoing requests, if provider is not available, enqueue the request
ProviderManager.prototype.send = function(data, cb) {
data._id = this.id;
if (cb) {
web3._callbacks[data._id] = cb;
}
/// sends outgoing requests
ProviderManager.prototype.send = function(data) {
data.args = data.args || [];
this.id++;
data._id = this.id++;
if(this.provider !== undefined) {
this.provider.send(data);
} else {
console.warn("provider is not set");
this.queued.push(data);
if (this.provider === undefined) {
console.error('provider is not set');
return undefined;
}
//TODO: handle error here?
var result = this.provider.send(data);
result = JSON.parse(result);
return result.result;
};
/// setups provider, which will be used for sending messages
ProviderManager.prototype.set = function(provider) {
if(this.provider !== undefined && this.provider.unload !== undefined) {
this.provider.unload();
}
this.provider = provider;
this.ready = true;
};
/// resends queued messages
ProviderManager.prototype.sendQueued = function() {
for(var i = 0; this.queued.length; i++) {
// Resend
this.send(this.queued[i]);
}
};
/// @returns true if the provider i properly set
ProviderManager.prototype.installed = function() {
return this.provider !== undefined;
};
/// 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) {
if (!this.provider || !this.provider.poll) {
return;
}
this.polls.push({data: data, id: pollId});
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

57
libjsqrc/ethereumjs/lib/qt.js

@ -1,57 +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 qt.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* @date 2014
*/
/**
* QtProvider object prototype is implementing 'provider protocol'
* Should be used inside ethereum browser. It's compatible with cpp and go clients.
* It uses navigator.qt object to pass the messages to native bindings
*/
var QtProvider = function() {
this.handlers = [];
var self = this;
navigator.qt.onmessage = function (message) {
self.handlers.forEach(function (handler) {
handler.call(self, JSON.parse(message.data));
});
};
};
/// Prototype object method
/// Should be called when we want to send single api request to native bindings
/// Asynchronous
/// Response will be received by navigator.qt.onmessage method and passed to handlers
/// @param payload is inner message object
QtProvider.prototype.send = function(payload) {
navigator.qt.postMessage(JSON.stringify(payload));
};
/// Prototype object property
/// Should be used to set message handlers for this provider
Object.defineProperty(QtProvider.prototype, "onmessage", {
set: function(handler) {
this.handlers.push(handler);
}
});
module.exports = QtProvider;

32
libjsqrc/ethereumjs/lib/qtsync.js

@ -0,0 +1,32 @@
/*
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) {
return navigator.qt.callMethod(JSON.stringify(payload));
};
module.exports = QtSyncProvider;

174
libjsqrc/ethereumjs/lib/web3.js

@ -23,48 +23,32 @@
* @date 2014
*/
/// Recursively resolves all promises in given object and replaces the resolved values with promises
/// @param any object/array/promise/anything else..
/// @returns (resolves) object with replaced promises with their result
function flattenPromise (obj) {
if (obj instanceof Promise) {
return Promise.resolve(obj);
}
if (obj instanceof Array) {
return new Promise(function (resolve) {
var promises = obj.map(function (o) {
return flattenPromise(o);
});
return Promise.all(promises).then(function (res) {
for (var i = 0; i < obj.length; i++) {
obj[i] = res[i];
}
resolve(obj);
});
});
}
if (obj instanceof Object) {
return new Promise(function (resolve) {
var keys = Object.keys(obj);
var promises = keys.map(function (key) {
return flattenPromise(obj[key]);
});
return Promise.all(promises).then(function (res) {
for (var i = 0; i < keys.length; i++) {
obj[keys[i]] = res[i];
}
resolve(obj);
});
});
}
return Promise.resolve(obj);
if (process.env.NODE_ENV !== 'build') {
var BigNumber = require('bignumber.js');
}
var ETH_UNITS = [
'wei',
'Kwei',
'Mwei',
'Gwei',
'szabo',
'finney',
'ether',
'grand',
'Mether',
'Gether',
'Tether',
'Pether',
'Eether',
'Zether',
'Yether',
'Nether',
'Dether',
'Vether',
'Uether'
];
/// @returns an array of objects describing web3 api methods
var web3Methods = function () {
return [
@ -169,21 +153,11 @@ var shhWatchMethods = function () {
var setupMethods = function (obj, methods) {
methods.forEach(function (method) {
obj[method.name] = function () {
return flattenPromise(Array.prototype.slice.call(arguments)).then(function (args) {
var call = typeof method.call === "function" ? method.call(args) : method.call;
return {call: call, args: args};
}).then(function (request) {
return new Promise(function (resolve, reject) {
web3.provider.send(request, function (err, result) {
if (!err) {
resolve(result);
return;
}
reject(err);
});
});
}).catch(function(err) {
console.error(err);
var args = Array.prototype.slice.call(arguments);
var call = typeof method.call === 'function' ? method.call(args) : method.call;
return web3.provider.send({
call: call,
args: args
});
};
});
@ -195,30 +169,16 @@ var setupProperties = function (obj, properties) {
properties.forEach(function (property) {
var proto = {};
proto.get = function () {
return new Promise(function(resolve, reject) {
web3.provider.send({call: property.getter}, function(err, result) {
if (!err) {
resolve(result);
return;
}
reject(err);
});
return web3.provider.send({
call: property.getter
});
};
if (property.setter) {
proto.set = function (val) {
return flattenPromise([val]).then(function (args) {
return new Promise(function (resolve) {
web3.provider.send({call: property.setter, args: args}, function (err, result) {
if (!err) {
resolve(result);
return;
}
reject(err);
});
});
}).catch(function (err) {
console.error(err);
return web3.provider.send({
call: property.setter,
args: [val]
});
};
}
@ -226,15 +186,6 @@ var setupProperties = function (obj, properties) {
});
};
// TODO: import from a dependency, don't duplicate.
var hexToDec = function (hex) {
return parseInt(hex, 16).toString();
};
var decToHex = function (dec) {
return parseInt(dec).toString(16);
};
/// setups web3 object, and it's in-browser executed methods
var web3 = {
_callbacks: {},
@ -281,19 +232,20 @@ var web3 = {
/// @returns decimal representaton of hex value prefixed by 0x
toDecimal: function (val) {
return hexToDec(val.substring(2));
return (new BigNumber(val.substring(2), 16).toString(10));
},
/// @returns hex representation (prefixed by 0x) of decimal value
fromDecimal: function (val) {
return "0x" + decToHex(val);
return "0x" + (new BigNumber(val).toString(16));
},
/// used to transform value/string to eth string
/// TODO: use BigNumber.js to parse int
toEth: function(str) {
var val = typeof str === "string" ? str.indexOf('0x') === 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str;
var unit = 0;
var units = [ 'wei', 'Kwei', 'Mwei', 'Gwei', 'szabo', 'finney', 'ether', 'grand', 'Mether', 'Gether', 'Tether', 'Pether', 'Eether', 'Zether', 'Yether', 'Nether', 'Dether', 'Vether', 'Uether' ];
var units = ETH_UNITS;
while (val > 3000 && unit < units.length - 1)
{
val /= 1000;
@ -330,35 +282,6 @@ var web3 = {
}
},
/// used by filter to register callback with given id
on: function(event, id, cb) {
if(web3._events[event] === undefined) {
web3._events[event] = {};
}
web3._events[event][id] = cb;
return this;
},
/// used by filter to unregister callback with given id
off: function(event, id) {
if(web3._events[event] !== undefined) {
delete web3._events[event][id];
}
return this;
},
/// used to trigger callback registered by filter
trigger: function(event, id, data) {
var callbacks = web3._events[event];
if (!callbacks || !callbacks[id]) {
return;
}
var cb = callbacks[id];
cb(data);
},
/// @returns true if provider is installed
haveProvider: function() {
return !!web3.provider.provider;
@ -385,26 +308,9 @@ var shhWatch = {
setupMethods(shhWatch, shhWatchMethods());
web3.setProvider = function(provider) {
provider.onmessage = messageHandler;
//provider.onmessage = messageHandler; // there will be no async calls, to remove
web3.provider.set(provider);
web3.provider.sendQueued();
};
/// callled when there is new incoming message
function messageHandler(data) {
if(data._event !== undefined) {
web3.trigger(data._event, data._id, data.data);
return;
}
if(data._id) {
var cb = web3._callbacks[data._id];
if (cb) {
cb.call(this, data.error, data.data);
delete web3._callbacks[data._id];
}
}
}
module.exports = web3;

98
libjsqrc/ethereumjs/lib/websocket.js

@ -1,98 +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 websocket.js
* @authors:
* Jeffrey Wilcke <jeff@ethdev.com>
* Marek Kotewicz <marek@ethdev.com>
* Marian Oancea <marian@ethdev.com>
* @date 2014
*/
// TODO: is these line is supposed to be here?
if (process.env.NODE_ENV !== 'build') {
var WebSocket = require('ws'); // jshint ignore:line
}
/**
* WebSocketProvider object prototype is implementing 'provider protocol'
* Should be used when we want to connect to ethereum backend over websockets
* It's compatible with go client
* The constructor allows to specify host uri
*/
var WebSocketProvider = function(host) {
// onmessage handlers
this.handlers = [];
// queue will be filled with messages if send is invoked before the ws is ready
this.queued = [];
this.ready = false;
this.ws = new WebSocket(host);
var self = this;
this.ws.onmessage = function(event) {
for(var i = 0; i < self.handlers.length; i++) {
self.handlers[i].call(self, JSON.parse(event.data), event);
}
};
this.ws.onopen = function() {
self.ready = true;
for (var i = 0; i < self.queued.length; i++) {
// Resend
self.send(self.queued[i]);
}
};
};
/// Prototype object method
/// Should be called when we want to send single api request to server
/// Asynchronous, it's using websockets
/// Response for the call will be received by ws.onmessage
/// @param payload is inner message object
WebSocketProvider.prototype.send = function(payload) {
if (this.ready) {
var data = JSON.stringify(payload);
this.ws.send(data);
} else {
this.queued.push(payload);
}
};
/// Prototype object method
/// Should be called to add handlers
WebSocketProvider.prototype.onMessage = function(handler) {
this.handlers.push(handler);
};
/// Prototype object method
/// Should be called to close websockets connection
WebSocketProvider.prototype.unload = function() {
this.ws.close();
};
/// Prototype object property
/// Should be used to set message handlers for this provider
Object.defineProperty(WebSocketProvider.prototype, "onmessage", {
set: function(provider) { this.onMessage(provider); }
});
if (typeof(module) !== "undefined")
module.exports = WebSocketProvider;

7
libjsqrc/ethereumjs/test/abi.parsers.js

@ -48,7 +48,6 @@ describe('abi', function() {
assert.equal(parser.test('0.1'), "0000000000000000000000000000000000000000000000000000000000000000");
assert.equal(parser.test('3.9'), "0000000000000000000000000000000000000000000000000000000000000003");
});
it('should parse input uint128', function() {
@ -321,7 +320,7 @@ describe('abi', function() {
// given
var d = clone(description);
d[0].name = 'helloworld';
d[0].name = 'helloworld(int)';
d[0].inputs = [
{ type: "int" }
];
@ -331,6 +330,7 @@ describe('abi', function() {
// then
assert.equal(parser.helloworld(1), "0000000000000000000000000000000000000000000000000000000000000001");
assert.equal(parser.helloworld['int'](1), "0000000000000000000000000000000000000000000000000000000000000001");
});
@ -755,7 +755,7 @@ describe('abi', function() {
// given
var d = clone(description);
d[0].name = 'helloworld';
d[0].name = 'helloworld(int)';
d[0].outputs = [
{ type: "int" }
];
@ -765,6 +765,7 @@ describe('abi', function() {
// then
assert.equal(parser.helloworld("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
assert.equal(parser.helloworld['int']("0x0000000000000000000000000000000000000000000000000000000000000001")[0], 1);
});

1
libjsqrc/ethereumjs/test/db.methods.js

@ -3,7 +3,6 @@ require('es6-promise').polyfill();
var assert = require('assert');
var web3 = require('../index.js');
var u = require('./utils.js');
web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
describe('web3', function() {
describe('db', function() {

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

@ -3,7 +3,6 @@ require('es6-promise').polyfill();
var assert = require('assert');
var web3 = require('../index.js');
var u = require('./utils.js');
web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
describe('web3', function() {
describe('eth', function() {

1
libjsqrc/ethereumjs/test/shh.methods.js

@ -3,7 +3,6 @@ require('es6-promise').polyfill();
var assert = require('assert');
var web3 = require('../index.js');
var u = require('./utils.js');
web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
describe('web3', function() {
describe('shh', function() {

2
libjsqrc/ethereumjs/test/utils.js

@ -8,7 +8,7 @@ var methodExists = function (object, method) {
var propertyExists = function (object, property) {
it('should have property ' + property + ' implemented', function() {
assert.equal('object', typeof object[property], 'property ' + property + ' is not implemented');
assert.notEqual('undefined', typeof object[property], 'property ' + property + ' is not implemented');
});
};

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

@ -3,7 +3,6 @@ require('es6-promise').polyfill();
var assert = require('assert');
var web3 = require('../index.js');
var u = require('./utils.js');
web3.setProvider(new web3.providers.WebSocketProvider('http://localhost:8080')); // TODO: create some mock provider
describe('web3', function() {
u.methodExists(web3, 'sha3');

1
libjsqrc/js.qrc

@ -4,5 +4,6 @@
<file>bignumber.min.js</file>
<file>setup.js</file>
<file alias="webthree.js">ethereumjs/dist/ethereum.js</file>
<file>natspec.js</file>
</qresource>
</RCC>

69
libjsqrc/natspec.js

@ -0,0 +1,69 @@
/**
* This plugin exposes 'evaluateExpression' method which should be used
* to evaluate natspec description
* It should be reloaded each time we want to evaluate set of expressions
* Just because of security reasons
* TODO: make use of sync api (once it's finished) and remove unnecessary
* code from 'getContractMethods'
* TODO: unify method signature creation with abi.js (and make a separate method from it)
*/
/// Should be called to copy values from object to global context
var copyToContext = function (obj, context) {
var keys = Object.keys(obj);
keys.forEach(function (key) {
context[key] = obj[key];
});
}
/// Function called to get all contract's storage values
/// @returns hashmap with contract properties which are used
var getContractProperties = function (address, abi) {
return {};
};
/// Function called to get all contract's methods
/// @returns hashmap with used contract's methods
var getContractMethods = function (address, abi) {
return web3.eth.contract(address, abi);
};
/// Should be called to evaluate single expression
/// Is internally using javascript's 'eval' method
/// Should be checked if it is safe
var evaluateExpression = function (expression) {
var self = this;
var abi = web3._currentContractAbi;
var address = web3._currentContractAddress;
var storage = getContractProperties(address, abi);
var methods = getContractMethods(address, abi);
copyToContext(storage, self);
copyToContext(methods, self);
// TODO: test if it is safe
var evaluatedExpression = "";
// match everything in `` quotes
var pattern = /\`(?:\\.|[^`\\])*\`/gim
var match;
var lastIndex = 0;
while ((match = pattern.exec(expression)) !== null) {
var startIndex = pattern.lastIndex - match[0].length;
var toEval = match[0].slice(1, match[0].length - 1);
evaluatedExpression += expression.slice(lastIndex, startIndex);
evaluatedExpression += eval(toEval).toString();
lastIndex = pattern.lastIndex;
}
evaluatedExpression += expression.slice(lastIndex);
return evaluatedExpression;
};

17
libjsqrc/setup.js

@ -22,25 +22,10 @@
navigator.qt = _web3;
(function () {
navigator.qt.handlers = [];
Object.defineProperty(navigator.qt, 'onmessage', {
set: function (handler) {
navigator.qt.handlers.push(handler);
}
});
})();
navigator.qt.response.connect(function (res) {
navigator.qt.handlers.forEach(function (handler) {
handler({data: res});
});
});
if (window.Promise === undefined) {
window.Promise = ES6Promise.Promise;
}
var web3 = require('web3');
web3.setProvider(new web3.providers.QtProvider());
web3.setProvider(new web3.providers.QtSyncProvider());

115
libqwebthree/QWebThree.cpp

@ -36,58 +36,8 @@ QWebThree::~QWebThree()
clientDieing();
}
static QString toJsonRpcBatch(std::vector<unsigned> const& _watches, QString _method)
{
QJsonArray batch;
for (int w: _watches)
{
QJsonObject res;
res["jsonrpc"] = QString::fromStdString("2.0");
res["method"] = _method;
QJsonArray params;
params.append(w);
res["params"] = params;
res["id"] = w;
batch.append(res);
}
return QString::fromUtf8(QJsonDocument(batch).toJson());
}
void QWebThree::poll()
{
if (m_watches.size() > 0)
{
QString batch = toJsonRpcBatch(m_watches, "eth_changed");
emit processData(batch, "eth_changed");
}
if (m_shhWatches.size() > 0)
{
QString batch = toJsonRpcBatch(m_shhWatches, "shh_changed");
emit processData(batch, "shh_changed");
}
}
void QWebThree::clearWatches()
{
if (m_watches.size() > 0)
{
QString batch = toJsonRpcBatch(m_watches, "eth_uninstallFilter");
m_watches.clear();
emit processData(batch, "internal");
}
if (m_shhWatches.size() > 0)
{
QString batch = toJsonRpcBatch(m_shhWatches, "shh_uninstallFilter");
m_shhWatches.clear();
emit processData(batch, "internal");
}
}
void QWebThree::clientDieing()
{
clearWatches();
this->disconnect();
}
@ -101,71 +51,22 @@ static QString formatInput(QJsonObject const& _object)
return QString::fromUtf8(QJsonDocument(res).toJson());
}
void QWebThree::postMessage(QString _json)
QString QWebThree::callMethod(QString _json)
{
QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object();
QString method = f["call"].toString();
if (!method.compare("eth_uninstallFilter") && f["args"].isArray() && f["args"].toArray().size())
{
int idToRemove = f["args"].toArray()[0].toInt();
m_watches.erase(std::remove(m_watches.begin(), m_watches.end(), idToRemove), m_watches.end());
}
else if (!method.compare("eth_uninstallFilter") && f["args"].isArray() && f["args"].toArray().size())
{
int idToRemove = f["args"].toArray()[0].toInt();
m_watches.erase(std::remove(m_watches.begin(), m_watches.end(), idToRemove), m_watches.end());
}
emit processData(formatInput(f), method);
emit processData(formatInput(f), ""); // it's synchronous
return m_response;
}
static QString formatOutput(QJsonObject const& _object)
void QWebThree::onDataProcessed(QString _json, QString)
{
QJsonObject res;
res["_id"] = _object["id"];
res["data"] = _object["result"];
res["error"] = _object["error"];
return QString::fromUtf8(QJsonDocument(res).toJson());
QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object();
syncResponse(QString::fromUtf8(QJsonDocument(f).toJson()));
}
void QWebThree::onDataProcessed(QString _json, QString _addInfo)
void QWebThree::syncResponse(QString _json)
{
if (!_addInfo.compare("internal"))
return;
if (!_addInfo.compare("shh_changed") || !_addInfo.compare("eth_changed"))
{
QJsonArray resultsArray = QJsonDocument::fromJson(_json.toUtf8()).array();
for (int i = 0; i < resultsArray.size(); i++)
{
QJsonObject elem = resultsArray[i].toObject();
if (elem["result"].isArray() && elem["result"].toArray().size() > 0)
{
QJsonObject res;
res["_event"] = _addInfo;
if (!_addInfo.compare("shh_changed"))
res["_id"] = (int)m_shhWatches[i]; // we can do that couse poll is synchronous
else
res["_id"] = (int)m_watches[i];
res["data"] = elem["result"].toArray();
response(QString::fromUtf8(QJsonDocument(res).toJson()));
}
}
}
QJsonObject f = QJsonDocument::fromJson(_json.toUtf8()).object();
if ((!_addInfo.compare("eth_newFilter") || !_addInfo.compare("eth_newFilterString")) && f.contains("result"))
m_watches.push_back(f["result"].toInt());
else if (!_addInfo.compare("shh_newFilter") && f.contains("result"))
m_shhWatches.push_back(f["result"].toInt());
else if (!_addInfo.compare("shh_newIdentity") && f.contains("result"))
emit onNewId(f["result"].toString());
response(formatOutput(f));
m_response = _json;
}
QWebThreeConnector::QWebThreeConnector()

9
libqwebthree/QWebThree.h

@ -34,12 +34,10 @@ class QWebThree: public QObject
public:
QWebThree(QObject* _p);
virtual ~QWebThree();
void poll();
void clearWatches();
void clientDieing();
Q_INVOKABLE void postMessage(QString _json);
Q_INVOKABLE QString callMethod(QString _json);
void syncResponse(QString _json);
public slots:
void onDataProcessed(QString _json, QString _addInfo);
@ -50,8 +48,7 @@ signals:
void onNewId(QString _id);
private:
std::vector<unsigned> m_watches;
std::vector<unsigned> m_shhWatches;
QString m_response;
};
class QWebThreeConnector: public QObject, public jsonrpc::AbstractServerConnector

6
libweb3jsonrpc/CorsHttpServer.cpp

@ -24,6 +24,11 @@
namespace jsonrpc
{
int HttpServer::callback(struct mg_connection*)
{
return 0;
}
bool CorsHttpServer::SendResponse(std::string const& _response, void* _addInfo)
{
struct mg_connection* conn = (struct mg_connection*) _addInfo;
@ -36,7 +41,6 @@ bool CorsHttpServer::SendResponse(std::string const& _response, void* _addInfo)
"%s",(int)_response.length(), _response.c_str()) > 0)
return true;
return false;
}
}

2
libweb3jsonrpc/CorsHttpServer.h

@ -24,7 +24,7 @@
namespace jsonrpc
{
class CorsHttpServer : public HttpServer
class CorsHttpServer: public HttpServer
{
public:
using HttpServer::HttpServer;

2
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -631,7 +631,7 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json)
return ret;
}
bool WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t) const
bool WebThreeStubServerBase::authenticate(TransactionSkeleton const& _t)
{
cwarn << "Silently signing transaction from address" << _t.from.abridged() << ": User validation hook goes here.";
return true;

2
libweb3jsonrpc/WebThreeStubServerBase.h

@ -121,7 +121,7 @@ public:
std::map<dev::Public, dev::Secret> const& ids() const { return m_ids; }
protected:
virtual bool authenticate(dev::TransactionSkeleton const& _t) const;
virtual bool authenticate(dev::TransactionSkeleton const& _t);
protected:
virtual dev::eth::Interface* client() = 0;

5
mix/ClientModel.cpp

@ -68,9 +68,10 @@ ClientModel::~ClientModel()
{
}
void ClientModel::apiRequest(const QString& _message)
void ClientModel::apiRequest(QString const& _message)
{
m_qWebThree->postMessage(_message);
(void)_message;
// m_qWebThree->postMessage(_message);
}
QString ClientModel::contractAddress() const

31
test/stSpecialTestFiller.json

@ -37,5 +37,36 @@
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"data" : ""
}
},
"OverflowGasMakeMoney" : {
"env" : {
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"currentDifficulty" : "45678256",
"currentGasLimit" : "(2**256)-1",
"currentGasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639935",
"currentNumber" : "0",
"currentTimestamp" : 1,
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6"
},
"pre" : {
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "1000",
"code" : "",
"nonce" : "0",
"storage" : {
}
}
},
"transaction" :
{
"data" : "",
"gasLimit" : "115792089237316195423570985008687907853269984665640564039457584007913129639435",
"gasPrice" : "1",
"nonce" : "0",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "b94f5374fce5edbc8e2a8697c15331677e6ebf0b",
"value" : "501"
}
}
}

4
third/MainWin.cpp

@ -135,7 +135,6 @@ Main::Main(QWidget *parent) :
connect(ui->webView, &QWebView::loadFinished, [=]()
{
m_qweb->poll();
});
connect(ui->webView, &QWebView::titleChanged, [=]()
@ -531,9 +530,6 @@ void Main::timerEvent(QTimerEvent*)
}
else
interval += 100;
if (m_qweb)
m_qweb->poll();
for (auto const& i: m_handlers)
{

Loading…
Cancel
Save