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);
}
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)
{
if (_js.trimmed().isEmpty())

1
alethzero/MainWin.h

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

33
alethzero/OurWebThreeStubServer.cpp

@ -21,9 +21,13 @@
#include "OurWebThreeStubServer.h"
#include <QtCore/QString>
#include <QtCore/QtCore>
#include <QMessageBox>
#include <QAbstractButton>
#include <libwebthree/WebThree.h>
#include <jsoncpp/json/json.h>
#include "MainWin.h"
using namespace std;
@ -54,7 +58,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)
@ -69,15 +73,15 @@ bool OurWebThreeStubServer::authenticate(dev::TransactionSkeleton const& _t) con
// return showAuthenticationPopup("Unverified Pending Transaction",
// "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();
// otherwise it's a transaction to a contract for which we have the natspec
return showAuthenticationPopup("Pending Transaction", userNotice);
}
QNatspecExpressionEvaluator::QNatspecExpressionEvaluator(dev::WebThreeDirect& _web3, Main* _main):
m_web3(&_web3), m_main(_main)
QNatspecExpressionEvaluator::QNatspecExpressionEvaluator(OurWebThreeStubServer* _server, Main* _main)
: m_server(_server), m_main(_main)
{}
QNatspecExpressionEvaluator::~QNatspecExpressionEvaluator()
@ -85,20 +89,35 @@ QNatspecExpressionEvaluator::~QNatspecExpressionEvaluator()
QString QNatspecExpressionEvaluator::stateAt(QString _key)
{
(void)_key;
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)
{
// evaluate the natspec
m_main->addToWindowObject(this, "_natspec");
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);
return result.toString();
}

9
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);
@ -53,15 +53,16 @@ class QNatspecExpressionEvaluator: public QObject
Q_OBJECT
public:
QNatspecExpressionEvaluator(dev::WebThreeDirect& _web3, Main* _main);
QNatspecExpressionEvaluator(OurWebThreeStubServer* _server, Main* _main);
virtual ~QNatspecExpressionEvaluator();
QString evalExpression(QString const& _expression);
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:
dev::WebThreeDirect* m_web3;
OurWebThreeStubServer* m_server;
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/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');
@ -13,7 +14,7 @@
// 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" +
@ -21,7 +22,7 @@
// contract description, this will be autogenerated somehow
var desc = [{
"name": "multiply",
"name": "multiply(uint256)",
"inputs": [
{
"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
* 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
@ -15,25 +20,41 @@ var copyToContext = function (obj, context) {
/// Function called to get all contract's storage values
/// @returns hashmap with contract properties which are used
var getContractProperties = function (expression, abi) {
var keys = ['test'];
return keys.reduce(function (acc, current) {
acc[current] = natspec.stateAt(current);
return acc;
}, {});
return {};
};
/// Function called to get all contract's methods
/// @returns hashmap with used contract's methods
var getContractMethods = function (expression, abi) {
var keys = ['testMethod'];
var getContractMethods = function (address, abi) {
var contract = {};
var inputParser = web3.abi.inputParser(abi);
var outputParser = web3.abi.outputParser(abi);
abi.forEach(function (method) {
var displayName = web3.abi.methodDisplayName(method.name);
var typeName = web3.abi.methodTypeName(method.name);
return keys.reduce(function (acc, current) {
acc[current] = function () {
// 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
@ -42,15 +63,16 @@ var getContractMethods = function (expression, abi) {
var evaluateExpression = function (expression) {
var self = this;
var abi = web3._currentAbi;
var abi = web3._currentContractAbi;
var address = web3._currentContractAddress;
var storage = getContractProperties(expression, abi);
var methods = getContractMethods(expression, abi);
var methods = getContractMethods(address, abi);
copyToContext(storage, self);
copyToContext(methods, self);
// TODO: check if it is safe
// TODO: test if it is safe
return eval(expression).toString();
};

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;

Loading…
Cancel
Save