Browse Source

separated libnatspec

cl-refactor
Marek Kotewicz 10 years ago
parent
commit
a4a959b1b1
  1. 1
      CMakeLists.txt
  2. 1
      libjsqrc/js.qrc
  3. 33
      libnatspec/CMakeLists.txt
  4. 58
      libnatspec/NatspecExpressionEvaluator.cpp
  5. 35
      libnatspec/NatspecExpressionEvaluator.h
  6. 69
      libnatspec/natspec.js
  7. 5
      libnatspec/natspec.qrc
  8. 1
      test/CMakeLists.txt
  9. 124
      test/natspec.cpp

1
CMakeLists.txt

@ -164,6 +164,7 @@ endif ()
if (NOT HEADLESS)
add_subdirectory(libnatspec)
add_subdirectory(libjsqrc)
add_subdirectory(libqwebthree)
add_subdirectory(alethzero)

1
libjsqrc/js.qrc

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

33
libnatspec/CMakeLists.txt

@ -0,0 +1,33 @@
cmake_policy(SET CMP0015 NEW)
# let cmake autolink dependencies on windows
cmake_policy(SET CMP0020 NEW)
# this policy was introduced in cmake 3.0
# remove if, once 3.0 will be used on unix
if (${CMAKE_MAJOR_VERSION} GREATER 2)
cmake_policy(SET CMP0043 OLD)
endif()
set(CMAKE_AUTOMOC OFF)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
aux_source_directory(. SRC_LIST)
include_directories(..)
set(EXECUTABLE natspec)
file(GLOB HEADERS "*.h")
qt5_add_resources(NATSPECQRC natspec.qrc)
if (ETH_STATIC)
add_library(${EXECUTABLE} STATIC ${RESOURCE_ADDED} ${SRC_LIST} ${HEADERS} ${NATSPECQRC})
else()
add_library(${EXECUTABLE} SHARED ${RESOURCE_ADDED} ${SRC_LIST} ${HEADERS} ${NATSPECQRC})
endif()
target_link_libraries(${EXECUTABLE} Qt5::Core)
target_link_libraries(${EXECUTABLE} Qt5::Qml)
target_link_libraries(${EXECUTABLE} devcore)
install( TARGETS ${EXECUTABLE} ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

58
libnatspec/NatspecExpressionEvaluator.cpp

@ -0,0 +1,58 @@
/*
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 NatspecExpressionEvaluator.cpp
* @author Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
#include <libdevcore/Log.h>
#include <libdevcore/Exceptions.h>
#include "NatspecExpressionEvaluator.h"
using namespace std;
using namespace dev;
static QString contentsOfQResource(string const& res)
{
QFile file(QString::fromStdString(res));
if (!file.open(QFile::ReadOnly))
BOOST_THROW_EXCEPTION(FileError());
QTextStream in(&file);
return in.readAll();
}
NatspecExpressionEvaluator::NatspecExpressionEvaluator(QString const& _abi, QString const& _method, QString const& _params)
{
Q_INIT_RESOURCE(natspec);
QJSValue result = m_engine.evaluate(contentsOfQResource(":/natspec/natspec.js"));
if (result.isError())
BOOST_THROW_EXCEPTION(FileError());
m_engine.evaluate("globals.abi = " + _abi);
m_engine.evaluate("globals.method = " + _method);
m_engine.evaluate("globals.params = " + _params);
}
QString NatspecExpressionEvaluator::evalExpression(QString const& _expression)
{
QJSValue result = m_engine.evaluate("evaluateExpression(\"" + _expression + "\")");
if (result.isError())
{
cerr << "Could not evaluate expression: " << _expression.toStdString() << ". result: " << result.toString().toStdString() << endl;
}
return result.toString();
}

35
libnatspec/NatspecExpressionEvaluator.h

@ -0,0 +1,35 @@
/*
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 NatspecExpressionEvaluator.h
* @author Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
#include <QtCore/QObject>
#include <QtCore/QtCore>
#include <QtQml/QJSEngine>
class NatspecExpressionEvaluator
{
public:
NatspecExpressionEvaluator(QString const& _abi = "[]", QString const& _method = "", QString const& _params = "[]");
QString evalExpression(QString const& _expression);
private:
QJSEngine m_engine;
};

69
libjsqrc/natspec.js → libnatspec/natspec.js

@ -2,13 +2,19 @@
/**
* 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)
*/
/// Object which should be used by NatspecExpressionEvaluator
/// abi - abi of the contract that will be used
/// method - name of the method that is called
/// params - input params of the method that will be called
var globals = {
abi: [],
method: "",
params: []
};
/// Helper method
/// Should be called to copy values from object to global context
var copyToContext = function (obj, context) {
var keys = Object.keys(obj);
@ -17,32 +23,38 @@ var copyToContext = function (obj, context) {
});
}
/// Helper method
/// Should be called to get method with given name from the abi
/// @param contract's abi
/// @param name of the method that we are looking for
var getMethodWithName = function(abi, name) {
for (var i = 0; i < abi.length; i++) {
if (abi[i].name === name) {
return abi[i];
}
}
//console.warn('could not find method with name: ' + name);
return undefined;
};
/// Function called to get all contract's storage values
/// @returns hashmap with contract properties which are used
/// TODO: check if this function will be used
var getContractProperties = function (address, abi) {
return {};
};
/// Function called to get all contract's methods
/// @returns hashmap with used contract's methods
/// TODO: check if this function will be used
var getContractMethods = function (address, abi) {
return web3.eth.contract(address, abi);
};
var getMethodWithName = function(abi, name) {
for (var i = 0; i < abi.length; i++) {
if (abi[i].name === name) {
return abi[i];
}
}
console.warn('could not find method with name: ' + name);
return undefined;
//return web3.eth.contract(address, abi); // commented out web3 usage
return {};
};
/// Function called to get all contract method input variables
/// @returns hashmap with all contract's method input variables
var getContractInputParams = function (abi, methodName, params) {
var method = getMethodWithName(abi, methodName);
var getMethodInputParams = function (method, params) {
return method.inputs.reduce(function (acc, current, index) {
acc[current.name] = params[index];
return acc;
@ -55,18 +67,15 @@ var getContractInputParams = function (abi, methodName, params) {
var evaluateExpression = function (expression) {
var self = this;
var abi = web3._currentContractAbi;
var address = web3._currentContractAddress;
var methodName = web3._currentContractMethodName;
var params = web3._currentContractMethodParams;
var storage = getContractProperties(address, abi);
var methods = getContractMethods(address, abi);
var inputParams = getContractInputParams(abi, methodName, params);
copyToContext(storage, self);
copyToContext(methods, self);
copyToContext(inputParams, self);
//var storage = getContractProperties(address, abi);
//var methods = getContractMethods(address, abi);
var method = getMethodWithName(globals.abi, globals.method);
if (method) {
var input = getMethodInputParams(method, globals.params);
copyToContext(input, self);
}
// TODO: test if it is safe
var evaluatedExpression = "";

5
libnatspec/natspec.qrc

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/natspec">
<file>natspec.js</file>
</qresource>
</RCC>

1
test/CMakeLists.txt

@ -22,6 +22,7 @@ target_link_libraries(testeth ethcore)
target_link_libraries(testeth secp256k1)
target_link_libraries(testeth solidity)
target_link_libraries(testeth webthree)
target_link_libraries(testeth natspec)
if (JSONRPC)
target_link_libraries(testeth web3jsonrpc)

124
test/natspec.cpp

@ -0,0 +1,124 @@
/*
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 natspec.cpp
* @author Marek Kotewicz <marek@ethdev.com>
* @date 2015
*/
#include <boost/test/unit_test.hpp>
#include <libdevcore/Log.h>
#include <libnatspec/NatspecExpressionEvaluator.h>
using namespace std;
BOOST_AUTO_TEST_SUITE(natspec)
BOOST_AUTO_TEST_CASE(natspec_eval_function_exists)
{
cnote << "testing existance of evaluateExpression function";
// given
NatspecExpressionEvaluator e;
// when
string result = e.evalExpression("`typeof evaluateExpression`").toStdString();
// then
BOOST_CHECK_EQUAL(result, "function");
}
BOOST_AUTO_TEST_CASE(natspec_js_eval)
{
cnote << "testing natspec basic eval";
// given
NatspecExpressionEvaluator e;
// when
string result = e.evalExpression("`1 + 2`").toStdString();
// then
BOOST_CHECK_EQUAL(result, "3");
}
BOOST_AUTO_TEST_CASE(natspec_create_custom_function)
{
cnote << "testing creation and usage of custom js function";
// given
NatspecExpressionEvaluator e;
// when
auto x = e.evalExpression("`test = function (x) { return x + 'ok'; }`"); // ommit var, make it global
string result = e.evalExpression("`test(5)`").toStdString();
string result2 = e.evalExpression("`typeof test`").toStdString();
// then
BOOST_CHECK_EQUAL(result, "5ok");
BOOST_CHECK_EQUAL(result2, "function");
}
BOOST_AUTO_TEST_CASE(natspec_js_eval_separated_expressions)
{
cnote << "testing natspec evaluation of separated expresioons";
// given
NatspecExpressionEvaluator e;
// when
string result = e.evalExpression("`x = 1` + `y = 2` will be equal `x + y`").toStdString();
// then
BOOST_CHECK_EQUAL(result, "1 + 2 will be equal 3");
}
BOOST_AUTO_TEST_CASE(natspec_js_eval_input_params)
{
cnote << "testing natspec evaluation of input params";
// given
char const* abi = R"([
{
"name": "f",
"constant": false,
"type": "function",
"inputs": [
{
"name": "a",
"type": "uint256"
}
],
"outputs": [
{
"name": "d",
"type": "uint256"
}
]
}
])";
NatspecExpressionEvaluator e(abi, "'f'", "[4]");
// when
string result = e.evalExpression("Will multiply `a` by 7 and return `a * 7`.").toStdString();
// then
BOOST_CHECK_EQUAL(result, "Will multiply 4 by 7 and return 28.");
}
BOOST_AUTO_TEST_SUITE_END()
Loading…
Cancel
Save