diff --git a/libsolidity/NameAndTypeResolver.cpp b/libsolidity/NameAndTypeResolver.cpp index ba5ca1345..c67cd7279 100644 --- a/libsolidity/NameAndTypeResolver.cpp +++ b/libsolidity/NameAndTypeResolver.cpp @@ -111,7 +111,7 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) { // order in the lists is from derived to base // list of lists to linearize, the last element is the list of direct bases - list> input(1, {&_contract}); + list> input(1, {}); for (ASTPointer const& baseSpecifier: _contract.getBaseContracts()) { ASTPointer baseName = baseSpecifier->getName(); @@ -119,14 +119,15 @@ void NameAndTypeResolver::linearizeBaseContracts(ContractDefinition& _contract) baseName->getReferencedDeclaration()); if (!base) BOOST_THROW_EXCEPTION(baseName->createTypeError("Contract expected.")); - // "push_back" has the effect that bases mentioned earlier can overwrite members of bases - // mentioned later - input.back().push_back(base); + // "push_front" has the effect that bases mentioned later can overwrite members of bases + // mentioned earlier + input.back().push_front(base); vector const& basesBases = base->getLinearizedBaseContracts(); if (basesBases.empty()) BOOST_THROW_EXCEPTION(baseName->createTypeError("Definition of base has to precede definition of derived contract")); input.push_front(list(basesBases.begin(), basesBases.end())); } + input.back().push_front(&_contract); vector result = cThreeMerge(input); if (result.empty()) BOOST_THROW_EXCEPTION(_contract.createTypeError("Linearization of inheritance graph impossible")); diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index 720ee2838..a8bf34f26 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -107,11 +107,10 @@ void ClientModel::debugState(QVariantMap _state) QVariantList transactions = _state.value("transactions").toList(); std::vector transactionSequence; - + TransactionSettings constructorTr; for (auto const& t: transactions) { QVariantMap transaction = t.toMap(); - QString functionId = transaction.value("functionId").toString(); u256 gas = (qvariant_cast(transaction.value("gas")))->toU256Wei(); u256 value = (qvariant_cast(transaction.value("value")))->toU256Wei(); @@ -125,12 +124,15 @@ void ClientModel::debugState(QVariantMap _state) transactionSettings.parameterValues.insert(std::make_pair(p.key(), boost::get(param->internalValue()))); } - transactionSequence.push_back(transactionSettings); + if (transaction.value("executeConstructor").toBool()) + constructorTr = transactionSettings; + else + transactionSequence.push_back(transactionSettings); } - executeSequence(transactionSequence, balance); + executeSequence(transactionSequence, balance, constructorTr); } -void ClientModel::executeSequence(std::vector const& _sequence, u256 _balance) +void ClientModel::executeSequence(std::vector const& _sequence, u256 _balance, TransactionSettings const& ctrTransaction) { if (m_running) throw (std::logic_error("debugging already running")); @@ -180,7 +182,7 @@ void ClientModel::executeSequence(std::vector const& _seque //run contract creation first m_client->resetState(_balance); - ExecutionResult debuggingContent = deployContract(contractCode); + ExecutionResult debuggingContent = deployContract(contractCode, ctrTransaction); Address address = debuggingContent.contractAddress; for (unsigned i = 0; i < _sequence.size(); ++i) debuggingContent = callContract(address, transactonData.at(i), _sequence.at(i)); @@ -232,14 +234,20 @@ void ClientModel::showDebugError(QString const& _error) m_context->displayMessageDialog(tr("Debugger"), _error); } -ExecutionResult ClientModel::deployContract(bytes const& _code) +ExecutionResult ClientModel::deployContract(bytes const& _code, TransactionSettings const& _ctrTransaction) { - u256 gasPrice = 10000000000000; - u256 gas = 125000; - u256 amount = 100; + Address newAddress; + if (!_ctrTransaction.isEmpty()) + newAddress = m_client->transact(m_client->userAccount().secret(), _ctrTransaction.value, _code, _ctrTransaction.gas, _ctrTransaction.gasPrice); + else + { + u256 gasPrice = 10000000000000; + u256 gas = 125000; + u256 amount = 100; + newAddress = m_client->transact(m_client->userAccount().secret(), amount, _code, gas, gasPrice); + } Address lastAddress = m_client->lastContractAddress(); - Address newAddress = m_client->transact(m_client->userAccount().secret(), amount, _code, gas, gasPrice); ExecutionResult r = m_client->lastExecutionResult(); if (newAddress != lastAddress) contractAddressChanged(); @@ -256,4 +264,3 @@ ExecutionResult ClientModel::callContract(Address const& _contract, bytes const& } } - diff --git a/mix/ClientModel.h b/mix/ClientModel.h index aeadfb1c9..b47a73843 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -44,6 +44,7 @@ class RpcConnector; /// Backend transaction config class struct TransactionSettings { + TransactionSettings() {} TransactionSettings(QString const& _functionId, u256 _value, u256 _gas, u256 _gasPrice): functionId(_functionId), value(_value), gas(_gas), gasPrice(_gasPrice) {} @@ -57,6 +58,10 @@ struct TransactionSettings u256 gasPrice; /// Mapping from contract function parameter name to value std::map parameterValues; + +public: + /// @returns true if the functionId has not be set + bool isEmpty() const { return functionId.isNull() || functionId.isEmpty(); } }; @@ -115,8 +120,8 @@ signals: private: QString contractAddress() const; - void executeSequence(std::vector const& _sequence, u256 _balance); - ExecutionResult deployContract(bytes const& _code); + void executeSequence(std::vector const& _sequence, u256 _balance, TransactionSettings const& _ctrTransaction = TransactionSettings()); + ExecutionResult deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); ExecutionResult callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); AppContext* m_context; diff --git a/mix/QContractDefinition.cpp b/mix/QContractDefinition.cpp index bee9cfe49..9f6597d83 100644 --- a/mix/QContractDefinition.cpp +++ b/mix/QContractDefinition.cpp @@ -33,6 +33,11 @@ using namespace dev::mix; QContractDefinition::QContractDefinition(dev::solidity::ContractDefinition const* _contract): QBasicNodeDefinition(_contract) { + if (_contract->getConstructor() != nullptr) + m_constructor = new QFunctionDefinition(_contract->getConstructor(), -1); + else + m_constructor = new QFunctionDefinition(); + auto interfaceFunctions = _contract->getInterfaceFunctions(); unsigned i = 0; for (auto it = interfaceFunctions.cbegin(); it != interfaceFunctions.cend(); ++it, ++i) diff --git a/mix/QContractDefinition.h b/mix/QContractDefinition.h index e9c618804..890b8bc0f 100644 --- a/mix/QContractDefinition.h +++ b/mix/QContractDefinition.h @@ -36,15 +36,19 @@ class QContractDefinition: public QBasicNodeDefinition { Q_OBJECT Q_PROPERTY(QQmlListProperty functions READ functions CONSTANT) + Q_PROPERTY(dev::mix::QFunctionDefinition* constructor READ constructor CONSTANT) public: QContractDefinition() {} QContractDefinition(solidity::ContractDefinition const* _contract); /// Get all the functions of the contract. QQmlListProperty functions() const { return QQmlListProperty(const_cast(this), const_cast(this)->m_functions); } + /// Get the constructor of the contract. + QFunctionDefinition* constructor() const { return m_constructor; } QList const& functionsList() const { return m_functions; } private: QList m_functions; + QFunctionDefinition* m_constructor; }; } diff --git a/mix/qml.qrc b/mix/qml.qrc index 1c7bb2d17..ea10185c6 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -41,6 +41,8 @@ qml/Ether.qml qml/EtherValue.qml qml/BigIntValue.qml + qml/js/QEtherHelper.js + qml/js/TransactionHelper.js qml/Splitter.qml diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 47975db83..3d0fba349 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -114,6 +114,7 @@ Rectangle { contentWidth: parent.width Rectangle { + color: "transparent" anchors.fill: parent ColumnLayout { @@ -317,7 +318,7 @@ Rectangle { Rectangle { Layout.fillWidth: true height: parent.height //- 2 * stateListContainer.border.width - + color: "transparent" ColumnLayout { width: parent.width @@ -431,6 +432,7 @@ Rectangle { Rectangle { id: storageRect + color: "transparent" width: parent.width Layout.minimumHeight: 25 Layout.maximumHeight: 223 @@ -506,6 +508,7 @@ Rectangle { Rectangle { id: memoryRect; + color: "transparent" height: 25 width: parent.width Layout.minimumHeight: 25 @@ -527,6 +530,7 @@ Rectangle { Rectangle { id: callDataRect + color: "transparent" height: 25 width: parent.width Layout.minimumHeight: 25 diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index 7d80de4cf..aed1c94fe 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -4,6 +4,9 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 import CodeEditorExtensionManager 1.0 import Qt.labs.settings 1.0 +import org.ethereum.qml.QEther 1.0 +import "js/QEtherHelper.js" as QEtherHelper +import "js/TransactionHelper.js" as TransactionHelper Rectangle { @@ -30,6 +33,42 @@ Rectangle { contentView.width = parent.width - projectList.width; } + function startQuickDebugging() + { + var item = TransactionHelper.defaultTransaction(); + item.executeConstructor = true; + if (codeModel.code.contract.constructor.parameters.length === 0) + { + ensureRightView(); + startF5Debugging(item); + } + else + transactionDialog.open(0, item); + } + + function startF5Debugging(transaction) + { + var ether = QEtherHelper.createEther("100000000000000000000000000", QEther.Wei); + var state = { + title: "", + balance: ether, + transactions: [transaction] + }; + clientModel.debugState(state); + } + + TransactionDialog { + id: transactionDialog + onAccepted: { + ensureRightView(); + var item = transactionDialog.getItem(); + item.executeConstructor = true; + startF5Debugging(item); + } + useTransactionDefaultValue: true + } + + function toggleRightView() { if (!rightView.visible) rightView.show(); @@ -42,6 +81,11 @@ Rectangle { rightView.show(); } + function rightViewIsVisible() + { + return rightView.visible; + } + function hideRightView() { if (rightView.visible) rightView.hide(); @@ -55,9 +99,6 @@ Rectangle { codeWebSplitter.orientation = (codeWebSplitter.orientation === Qt.Vertical ? Qt.Horizontal : Qt.Vertical); } - function rightViewVisible() { - return rightView.visible; - } CodeEditorExtensionManager { headerView: headerPaneTabs; diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index 099ccf505..079158963 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -4,7 +4,6 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls 1.0 import QtQuick.Dialogs 1.1 import Qt.labs.settings 1.0 - import "js/ProjectModel.js" as ProjectModelCode Item { diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index 28121e0be..f4e061d76 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -3,6 +3,8 @@ import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 import org.ethereum.qml.QEther 1.0 +import "js/QEtherHelper.js" as QEtherHelper +import "js/TransactionHelper.js" as TransactionHelper Window { id: modalStateDialog @@ -118,27 +120,12 @@ Window { transactionDialog.open(index, transactionsModel.get(index)); } - function ether(_value, _unit) - { - var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); - var ether = etherComponent.createObject(modalStateDialog); - ether.setValue(_value); - ether.setUnit(_unit); - return ether; - } - function addTransaction() { // Set next id here to work around Qt bug // https://bugreports.qt-project.org/browse/QTBUG-41327 // Second call to signal handler would just edit the item that was just created, no harm done - var item = { - value: ether("0", QEther.Wei), - functionId: "", - gas: ether("125000", QEther.Wei), - gasPrice: ether("100000", QEther.Wei) - }; - + var item = TransactionHelper.defaultTransaction(); transactionDialog.open(transactionsModel.count, item); } diff --git a/mix/qml/StateList.qml b/mix/qml/StateList.qml index fbb579cb0..007a45d6a 100644 --- a/mix/qml/StateList.qml +++ b/mix/qml/StateList.qml @@ -4,6 +4,7 @@ import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import org.ethereum.qml.QEther 1.0 +import "js/QEtherHelper.js" as QEtherHelper Rectangle { color: "#ededed" @@ -67,15 +68,22 @@ Rectangle { id: stateListModel function addState() { - var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); - var ether = etherComponent.createObject(stateListContainer); - ether.setValue("100000000000000000000000000"); - ether.setUnit(QEther.Wei); + var ether = QEtherHelper.createEther("100000000000000000000000000", QEther.Wei); var item = { title: "", balance: ether, transactions: [] }; + + var ctorTr = { + value: QEtherHelper.createEther("100", QEther.Wei), + functionId: qsTr("Constructor"), + gas: QEtherHelper.createEther("125000", QEther.Wei), + gasPrice: QEtherHelper.createEther("10000000000000", QEther.Wei), + executeConstructor: true + }; + + item.transactions.push(ctorTr); stateDialog.open(stateListModel.count, item); } diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index f9bccef39..07da269ec 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -113,9 +113,10 @@ Rectangle { Action { id: debugRunActionIcon onTriggered: { - mainContent.toggleRightView(); - if (mainContent.rightViewVisible) - clientModel.debugDeployment(); + if (mainContent.rightViewIsVisible()) + mainContent.hideRightView() + else + mainContent.startQuickDebugging(); } enabled: false } diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index 46fe997f0..f18db08a5 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -3,6 +3,7 @@ import QtQuick.Controls 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.0 import org.ethereum.qml.QEther 1.0 +import "js/TransactionHelper.js" as TransactionHelper Window { id: modalTransactionDialog @@ -18,15 +19,25 @@ Window { property alias transactionValue: valueField.value; property alias functionId: functionComboBox.currentText; property var itemParams; + property bool isConstructorTransaction; + property bool useTransactionDefaultValue: false signal accepted; function open(index, item) { + rowFunction.visible = !useTransactionDefaultValue; + rowValue.visible = !useTransactionDefaultValue; + rowGas.visible = !useTransactionDefaultValue; + rowGasPrice.visible = !useTransactionDefaultValue; + transactionIndex = index; gasField.value = item.gas; gasPriceField.value = item.gasPrice; valueField.value = item.value; var functionId = item.functionId; + isConstructorTransaction = item.executeConstructor; + rowFunction.visible = !item.executeConstructor; + itemParams = item.parameters !== undefined ? item.parameters : {}; functionsModel.clear(); var functionIndex = -1; @@ -41,7 +52,17 @@ Window { functionIndex = 0; //@todo suggest unused funtion functionComboBox.currentIndex = functionIndex; - loadParameters(); + paramsModel.clear(); + if (!item.executeConstructor) + loadParameters(); + else + { + var parameters = codeModel.code.contract.constructor.parameters; + for (var p = 0; p < parameters.length; p++) { + var pname = parameters[p].name; + paramsModel.append({ name: pname, type: parameters[p].type, value: itemParams[pname] !== undefined ? itemParams[pname].value() : "" }); + } + } visible = true; valueField.focus = true; } @@ -49,7 +70,6 @@ Window { function loadParameters() { if (!paramsModel) return; - paramsModel.clear(); if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) { var func = codeModel.code.contract.functions[functionComboBox.currentIndex]; var parameters = func.parameters; @@ -67,112 +87,159 @@ Window { function getItem() { - var item = { - functionId: transactionDialog.functionId, - gas: transactionDialog.gas, - gasPrice: transactionDialog.gasPrice, - value: transactionDialog.transactionValue, - parameters: {} + var item; + if (!useTransactionDefaultValue) + { + item = { + functionId: transactionDialog.functionId, + gas: transactionDialog.gas, + gasPrice: transactionDialog.gasPrice, + value: transactionDialog.transactionValue, + parameters: {}, + executeConstructor: isConstructorTransaction + }; } + else + { + item = TransactionHelper.defaultTransaction(); + item.functionId = transactionDialog.functionId; + item.executeConstructor = isConstructorTransaction; + } + + if (isConstructorTransaction) + item.functionId = qsTr("Constructor"); + for (var p = 0; p < transactionDialog.transactionParams.count; p++) { var parameter = transactionDialog.transactionParams.get(p); var intComponent = Qt.createComponent("qrc:/qml/BigIntValue.qml"); var param = intComponent.createObject(modalTransactionDialog); + param.setValue(parameter.value); item.parameters[parameter.name] = param; } return item; } - GridLayout { + ColumnLayout { id: dialogContent - columns: 2 - anchors.fill: parent + width: parent.width + anchors.left: parent.left + anchors.right: parent.right anchors.margins: 10 - rowSpacing: 10 - columnSpacing: 10 - - Label { - text: qsTr("Function") - } - ComboBox { - id: functionComboBox + spacing: 30 + RowLayout + { + id: rowFunction Layout.fillWidth: true - currentIndex: -1 - textRole: "text" - editable: false - model: ListModel { - id: functionsModel + height: 150 + Label { + Layout.preferredWidth: 75 + text: qsTr("Function") } - onCurrentIndexChanged: { - loadParameters(); + ComboBox { + id: functionComboBox + Layout.fillWidth: true + currentIndex: -1 + textRole: "text" + editable: false + model: ListModel { + id: functionsModel + } + onCurrentIndexChanged: { + loadParameters(); + } } } - Label { - text: qsTr("Value") - } - Rectangle + + RowLayout { + id: rowValue Layout.fillWidth: true - Ether { - id: valueField - edit: true - displayFormattedValue: true + Label { + Layout.preferredWidth: 75 + text: qsTr("Value") + } + Rectangle + { + Layout.fillWidth: true + Ether { + id: valueField + edit: true + displayFormattedValue: true + } } } - Label { - text: qsTr("Gas") - } - Rectangle + + RowLayout { + id: rowGas Layout.fillWidth: true - Ether { - id: gasField - edit: true - displayFormattedValue: true + Label { + Layout.preferredWidth: 75 + text: qsTr("Gas") + } + Rectangle + { + Layout.fillWidth: true + Ether { + id: gasField + edit: true + displayFormattedValue: true + } } } - Label { - text: qsTr("Gas Price") - } - Rectangle + RowLayout { + id: rowGasPrice Layout.fillWidth: true - Ether { - id: gasPriceField - edit: true - displayFormattedValue: true + Label { + Layout.preferredWidth: 75 + text: qsTr("Gas Price") + } + Rectangle + { + Layout.fillWidth: true + Ether { + id: gasPriceField + edit: true + displayFormattedValue: true + } } } - Label { - text: qsTr("Parameters") - } - TableView { - model: paramsModel + RowLayout + { Layout.fillWidth: true - - TableViewColumn { - role: "name" - title: "Name" - width: 120 - } - TableViewColumn { - role: "type" - title: "Type" - width: 120 - } - TableViewColumn { - role: "value" - title: "Value" - width: 120 + Label { + text: qsTr("Parameters") + Layout.preferredWidth: 75 } + TableView { + model: paramsModel + Layout.fillWidth: true - itemDelegate: { - return editableDelegate; + TableViewColumn { + role: "name" + title: "Name" + width: 120 + } + TableViewColumn { + role: "type" + title: "Type" + width: 120 + } + TableViewColumn { + role: "value" + title: "Value" + width: 120 + } + + itemDelegate: { + return editableDelegate; + } } } } diff --git a/mix/qml/js/QEtherHelper.js b/mix/qml/js/QEtherHelper.js new file mode 100644 index 000000000..9761b2f45 --- /dev/null +++ b/mix/qml/js/QEtherHelper.js @@ -0,0 +1,8 @@ +function createEther(_value, _unit, _parent) +{ + var etherComponent = Qt.createComponent("qrc:/qml/EtherValue.qml"); + var ether = etherComponent.createObject(); + ether.setValue(_value); + ether.setUnit(_unit); + return ether; +} diff --git a/mix/qml/js/TransactionHelper.js b/mix/qml/js/TransactionHelper.js new file mode 100644 index 000000000..f404685cf --- /dev/null +++ b/mix/qml/js/TransactionHelper.js @@ -0,0 +1,13 @@ +Qt.include("QEtherHelper.js") + +function defaultTransaction() +{ + return { + value: createEther("0", QEther.Wei), + functionId: "", + gas: createEther("125000", QEther.Wei), + gasPrice: createEther("100000", QEther.Wei), + executeConstructor: false, + parameters: {} + }; +} diff --git a/mix/qml/main.qml b/mix/qml/main.qml index 02ee770f6..b7992f092 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -5,6 +5,7 @@ import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 import CodeEditorExtensionManager 1.0 +import org.ethereum.qml.QEther 1.0 ApplicationWindow { id: mainApplication @@ -79,11 +80,8 @@ ApplicationWindow { id: debugRunAction text: "&Run" shortcut: "F5" - onTriggered: { - mainContent.ensureRightView(); - clientModel.debugDeployment(); - } - enabled: codeModel.hasContract && !clientModel.running; + onTriggered: mainContent.startQuickDebugging() + enabled: codeModel.hasContract && !clientModel.running } Action { diff --git a/test/SolidityEndToEndTest.cpp b/test/SolidityEndToEndTest.cpp index cf04edaad..80e9aed46 100644 --- a/test/SolidityEndToEndTest.cpp +++ b/test/SolidityEndToEndTest.cpp @@ -1545,7 +1545,7 @@ BOOST_AUTO_TEST_CASE(single_copy_with_multiple_inheritance) } contract A is Base { function setViaA(uint i) { setData(i); } } contract B is Base { function getViaB() returns (uint i) { return getViaBase(); } } - contract Derived is A, B, Base { } + contract Derived is Base, B, A { } )"; compileAndRun(sourceCode, 0, "Derived"); BOOST_CHECK(callContractFunction("getViaB()") == encodeArgs(0)); @@ -1642,7 +1642,7 @@ BOOST_AUTO_TEST_CASE(constructor_argument_overriding) } } contract Base is BaseBase(2) { } - contract Derived is Base, BaseBase(3) { + contract Derived is BaseBase(3), Base { function getA() returns (uint r) { return m_a; } } )"; diff --git a/test/SolidityNameAndTypeResolution.cpp b/test/SolidityNameAndTypeResolution.cpp index 6c8fd1b1c..079da0a11 100644 --- a/test/SolidityNameAndTypeResolution.cpp +++ b/test/SolidityNameAndTypeResolution.cpp @@ -386,7 +386,7 @@ BOOST_AUTO_TEST_CASE(inheritance_diamond_basic) contract root { function rootFunction() {} } contract inter1 is root { function f() {} } contract inter2 is root { function f() {} } - contract derived is inter1, inter2, root { + contract derived is root, inter2, inter1 { function g() { f(); rootFunction(); } } )"; diff --git a/test/commonjs.cpp b/test/commonjs.cpp new file mode 100644 index 000000000..860b713dd --- /dev/null +++ b/test/commonjs.cpp @@ -0,0 +1,57 @@ +/* + 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 . +*/ +/** @file commonjs.cpp + * @author Marek Kotewicz + * @date 2014 + */ + +#include +#include + +BOOST_AUTO_TEST_SUITE(commonjs) +using namespace std; +using namespace dev; +using namespace dev::eth; + +BOOST_AUTO_TEST_CASE(jsToPublic) +{ + cnote << "Testing jsToPublic..."; + KeyPair kp = KeyPair::create(); + string string = toJS(kp.pub()); + Public pub = dev::jsToPublic(string); + BOOST_CHECK_EQUAL(kp.pub(), pub); +} + +BOOST_AUTO_TEST_CASE(jsToAddress) +{ + cnote << "Testing jsToPublic..."; + KeyPair kp = KeyPair::create(); + string string = toJS(kp.address()); + Address address = dev::jsToAddress(string); + BOOST_CHECK_EQUAL(kp.address(), address); +} + +BOOST_AUTO_TEST_CASE(jsToSecret) +{ + cnote << "Testing jsToPublic..."; + KeyPair kp = KeyPair::create(); + string string = toJS(kp.secret()); + Secret secret = dev::jsToSecret(string); + BOOST_CHECK_EQUAL(kp.secret(), secret); +} + +BOOST_AUTO_TEST_SUITE_END()