Browse Source

natspec changes

cl-refactor
Marek Kotewicz 10 years ago
parent
commit
475d4b1e4d
  1. 6
      alethzero/MainWin.cpp
  2. 1
      alethzero/MainWin.h
  3. 33
      alethzero/OurWebThreeStubServer.cpp
  4. 9
      alethzero/OurWebThreeStubServer.h
  5. 5
      libjsqrc/ethereumjs/example/natspec_contract.html
  6. 56
      libjsqrc/natspec.js
  7. 2
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  8. 2
      libweb3jsonrpc/WebThreeStubServerBase.h

6
alethzero/MainWin.cpp

@ -434,6 +434,12 @@ QVariant Main::evalRaw(QString const& _js)
return ui->webView->page()->currentFrame()->evaluateJavaScript(_js); return ui->webView->page()->currentFrame()->evaluateJavaScript(_js);
} }
void Main::addToWindowObject(QObject* _object, QString const& _name)
{
QWebFrame* f = ui->webView->page()->mainFrame();
f->addToJavaScriptWindowObject(_name, _object, QWebFrame::QtOwnership);
}
void Main::eval(QString const& _js) void Main::eval(QString const& _js)
{ {
if (_js.trimmed().isEmpty()) if (_js.trimmed().isEmpty())

1
alethzero/MainWin.h

@ -91,6 +91,7 @@ public:
QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; } QList<dev::KeyPair> owned() const { return m_myIdentities + m_myKeys; }
QVariant evalRaw(QString const& _js); QVariant evalRaw(QString const& _js);
void addToWindowObject(QObject* _object, QString const& _name);
public slots: public slots:
void load(QString _file); void load(QString _file);

33
alethzero/OurWebThreeStubServer.cpp

@ -21,9 +21,13 @@
#include "OurWebThreeStubServer.h" #include "OurWebThreeStubServer.h"
#include <QtCore/QString>
#include <QtCore/QtCore>
#include <QMessageBox> #include <QMessageBox>
#include <QAbstractButton> #include <QAbstractButton>
#include <libwebthree/WebThree.h> #include <libwebthree/WebThree.h>
#include <jsoncpp/json/json.h>
#include "MainWin.h" #include "MainWin.h"
using namespace std; using namespace std;
@ -54,7 +58,7 @@ bool OurWebThreeStubServer::showAuthenticationPopup(std::string const& _title, s
return userInput.exec() == QMessageBox::Ok; 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); h256 contractCodeHash = m_web3->ethereum()->postState().codeHash(_t.to);
if (contractCodeHash == EmptySHA3) if (contractCodeHash == EmptySHA3)
@ -69,15 +73,15 @@ bool OurWebThreeStubServer::authenticate(dev::TransactionSkeleton const& _t) con
// return showAuthenticationPopup("Unverified Pending Transaction", // return showAuthenticationPopup("Unverified Pending Transaction",
// "An undocumented transaction is about to be executed."); // "An undocumented transaction is about to be executed.");
QNatspecExpressionEvaluator evaluator(*m_web3, m_main); QNatspecExpressionEvaluator evaluator(this, m_main);
userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString(); userNotice = evaluator.evalExpression(QString::fromStdString(userNotice)).toStdString();
// otherwise it's a transaction to a contract for which we have the natspec // otherwise it's a transaction to a contract for which we have the natspec
return showAuthenticationPopup("Pending Transaction", userNotice); return showAuthenticationPopup("Pending Transaction", userNotice);
} }
QNatspecExpressionEvaluator::QNatspecExpressionEvaluator(dev::WebThreeDirect& _web3, Main* _main): QNatspecExpressionEvaluator::QNatspecExpressionEvaluator(OurWebThreeStubServer* _server, Main* _main)
m_web3(&_web3), m_main(_main) : m_server(_server), m_main(_main)
{} {}
QNatspecExpressionEvaluator::~QNatspecExpressionEvaluator() QNatspecExpressionEvaluator::~QNatspecExpressionEvaluator()
@ -85,20 +89,35 @@ QNatspecExpressionEvaluator::~QNatspecExpressionEvaluator()
QString QNatspecExpressionEvaluator::stateAt(QString _key) QString QNatspecExpressionEvaluator::stateAt(QString _key)
{ {
(void)_key;
return "1"; return "1";
} }
QString QNatspecExpressionEvaluator::call(QString _method) QString QNatspecExpressionEvaluator::call(QString _json)
{
QJsonObject jsonObject = QJsonDocument::fromJson(_json.toUtf8()).object();
Json::Value input;
input["to"] = jsonObject["to"].toString().toStdString();
input["data"] = jsonObject["data"].toString().toStdString();
return QString::fromStdString(m_server->eth_call(input));
}
QString QNatspecExpressionEvaluator::sha3(QString _method)
{ {
return "2"; return QString::fromStdString(m_server->web3_sha3(_method.toStdString()));
} }
QString QNatspecExpressionEvaluator::evalExpression(QString const& _expression) QString QNatspecExpressionEvaluator::evalExpression(QString const& _expression)
{ {
// evaluate the natspec // evaluate the natspec
m_main->addToWindowObject(this, "_natspec");
m_main->evalRaw(contentsOfQResource(":/js/natspec.js")); m_main->evalRaw(contentsOfQResource(":/js/natspec.js"));
auto result = m_main->evalRaw("evaluateExpression(\"2 + 1\")");
(void)_expression;
auto result = m_main->evalRaw(QString::fromStdString((string)"evaluateExpression('" + "multiply(4)" + "')"));
// auto result = m_main->evalRaw(_expression); // auto result = m_main->evalRaw(_expression);
return result.toString(); return result.toString();
} }

9
alethzero/OurWebThreeStubServer.h

@ -35,7 +35,7 @@ public:
std::vector<dev::KeyPair> const& _accounts, Main* main); std::vector<dev::KeyPair> const& _accounts, Main* main);
virtual std::string shh_newIdentity() override; virtual std::string shh_newIdentity() override;
virtual bool authenticate(dev::TransactionSkeleton const& _t) const; virtual bool authenticate(dev::TransactionSkeleton const& _t);
signals: signals:
void onNewId(QString _s); void onNewId(QString _s);
@ -53,15 +53,16 @@ class QNatspecExpressionEvaluator: public QObject
Q_OBJECT Q_OBJECT
public: public:
QNatspecExpressionEvaluator(dev::WebThreeDirect& _web3, Main* _main); QNatspecExpressionEvaluator(OurWebThreeStubServer* _server, Main* _main);
virtual ~QNatspecExpressionEvaluator(); virtual ~QNatspecExpressionEvaluator();
QString evalExpression(QString const& _expression); QString evalExpression(QString const& _expression);
Q_INVOKABLE QString stateAt(QString _key); Q_INVOKABLE QString stateAt(QString _key);
Q_INVOKABLE QString call(QString _method); Q_INVOKABLE QString call(QString _json);
Q_INVOKABLE QString sha3(QString _method);
private: private:
dev::WebThreeDirect* m_web3; OurWebThreeStubServer* m_server;
Main* m_main; Main* m_main;
}; };

5
libjsqrc/ethereumjs/example/natspec_contract.html

@ -5,6 +5,7 @@
<script type="text/javascript" src="js/es6-promise/promise.min.js"></script> <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="js/bignumber.js/bignumber.min.js"></script>
<script type="text/javascript" src="../dist/ethereum.js"></script> <script type="text/javascript" src="../dist/ethereum.js"></script>
<script type="text/javascript" src="../../natspec.js"></script>
<script type="text/javascript"> <script type="text/javascript">
var web3 = require('web3'); var web3 = require('web3');
@ -13,7 +14,7 @@
// solidity source code // solidity source code
var source = "" + var source = "" +
"contract test {\n" + "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" + " function multiply(uint a) returns(uint d) {\n" +
" return a * 7;\n" + " return a * 7;\n" +
" }\n" + " }\n" +
@ -21,7 +22,7 @@
// contract description, this will be autogenerated somehow // contract description, this will be autogenerated somehow
var desc = [{ var desc = [{
"name": "multiply", "name": "multiply(uint256)",
"inputs": [ "inputs": [
{ {
"name": "a", "name": "a",

56
libjsqrc/natspec.js

@ -1,7 +1,12 @@
/** /**
* This plugin should be reloaded each time we want to evaluate set of expressions * 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 * 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 /// Should be called to copy values from object to global context
@ -15,25 +20,41 @@ var copyToContext = function (obj, context) {
/// Function called to get all contract's storage values /// Function called to get all contract's storage values
/// @returns hashmap with contract properties which are used /// @returns hashmap with contract properties which are used
var getContractProperties = function (expression, abi) { var getContractProperties = function (expression, abi) {
var keys = ['test']; return {};
return keys.reduce(function (acc, current) {
acc[current] = natspec.stateAt(current);
return acc;
}, {});
}; };
/// Function called to get all contract's methods /// Function called to get all contract's methods
/// @returns hashmap with used contract's methods /// @returns hashmap with used contract's methods
var getContractMethods = function (expression, abi) { var getContractMethods = function (address, abi) {
var keys = ['testMethod'];
var contract = {};
var inputParser = web3.abi.inputParser(abi);
var outputParser = web3.abi.outputParser(abi);
abi.forEach(function (method) {
return keys.reduce(function (acc, current) { var displayName = web3.abi.methodDisplayName(method.name);
acc[current] = function () { var typeName = web3.abi.methodTypeName(method.name);
// TODO: connect parser
var impl = function () {
var params = Array.prototype.slice.call(arguments);
var parsed = inputParser[displayName][typeName].apply(null, params);
var methodSignature = _natspec.sha3(web3.fromAscii(method.name)).slice(0, 10);
var output = _natspec.call(JSON.stringify({
to: address,
data: methodSignature + parsed
}));
return outputParser[displayName][typeName](output);
}; };
return acc;
}, {}); if (contract[displayName] === undefined) {
contract[displayName] = impl;
}
contract[displayName][typeName] = impl;
});
return contract;
}; };
/// Should be called to evaluate single expression /// Should be called to evaluate single expression
@ -42,15 +63,16 @@ var getContractMethods = function (expression, abi) {
var evaluateExpression = function (expression) { var evaluateExpression = function (expression) {
var self = this; var self = this;
var abi = web3._currentAbi; var abi = web3._currentContractAbi;
var address = web3._currentContractAddress;
var storage = getContractProperties(expression, abi); var storage = getContractProperties(expression, abi);
var methods = getContractMethods(expression, abi); var methods = getContractMethods(address, abi);
copyToContext(storage, self); copyToContext(storage, self);
copyToContext(methods, self); copyToContext(methods, self);
// TODO: check if it is safe // TODO: test if it is safe
return eval(expression).toString(); return eval(expression).toString();
}; };

2
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -631,7 +631,7 @@ std::string WebThreeStubServerBase::eth_transact(Json::Value const& _json)
return ret; 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."; cwarn << "Silently signing transaction from address" << _t.from.abridged() << ": User validation hook goes here.";
return true; return true;

2
libweb3jsonrpc/WebThreeStubServerBase.h

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

Loading…
Cancel
Save