Browse Source

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

mix_tx

Conflicts:
	mix/ClientModel.cpp
cl-refactor
arkpar 10 years ago
parent
commit
f0519c5888
  1. 9
      libsolidity/NameAndTypeResolver.cpp
  2. 33
      mix/ClientModel.cpp
  3. 9
      mix/ClientModel.h
  4. 5
      mix/QContractDefinition.cpp
  5. 4
      mix/QContractDefinition.h
  6. 2
      mix/qml.qrc
  7. 6
      mix/qml/Debugger.qml
  8. 47
      mix/qml/MainContent.qml
  9. 1
      mix/qml/ProjectModel.qml
  10. 19
      mix/qml/StateDialog.qml
  11. 16
      mix/qml/StateList.qml
  12. 7
      mix/qml/StatusPane.qml
  13. 211
      mix/qml/TransactionDialog.qml
  14. 8
      mix/qml/js/QEtherHelper.js
  15. 13
      mix/qml/js/TransactionHelper.js
  16. 8
      mix/qml/main.qml
  17. 4
      test/SolidityEndToEndTest.cpp
  18. 2
      test/SolidityNameAndTypeResolution.cpp
  19. 57
      test/commonjs.cpp

9
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<list<ContractDefinition const*>> input(1, {&_contract});
list<list<ContractDefinition const*>> input(1, {});
for (ASTPointer<InheritanceSpecifier> const& baseSpecifier: _contract.getBaseContracts())
{
ASTPointer<Identifier> 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<ContractDefinition const*> 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<ContractDefinition const*>(basesBases.begin(), basesBases.end()));
}
input.back().push_front(&_contract);
vector<ContractDefinition const*> result = cThreeMerge(input);
if (result.empty())
BOOST_THROW_EXCEPTION(_contract.createTypeError("Linearization of inheritance graph impossible"));

33
mix/ClientModel.cpp

@ -106,11 +106,10 @@ void ClientModel::debugState(QVariantMap _state)
QVariantList transactions = _state.value("transactions").toList();
std::vector<TransactionSettings> transactionSequence;
TransactionSettings constructorTr;
for (auto const& t: transactions)
{
QVariantMap transaction = t.toMap();
QString functionId = transaction.value("functionId").toString();
u256 gas = (qvariant_cast<QEther*>(transaction.value("gas")))->toU256Wei();
u256 value = (qvariant_cast<QEther*>(transaction.value("value")))->toU256Wei();
@ -124,12 +123,15 @@ void ClientModel::debugState(QVariantMap _state)
transactionSettings.parameterValues.insert(std::make_pair(p.key(), boost::get<dev::u256>(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<TransactionSettings> const& _sequence, u256 _balance)
void ClientModel::executeSequence(std::vector<TransactionSettings> const& _sequence, u256 _balance, TransactionSettings const& ctrTransaction)
{
if (m_running)
throw (std::logic_error("debugging already running"));
@ -179,8 +181,8 @@ void ClientModel::executeSequence(std::vector<TransactionSettings> const& _seque
//run contract creation first
m_client->resetState(_balance);
ExecutionResult debuggingContent = deployContract(contractCode);
Address address = m_contractAddress;
ExecutionResult debuggingContent = deployContract(contractCode, ctrTransaction);
Address address = m_contractAddress
for (unsigned i = 0; i < _sequence.size(); ++i)
debuggingContent = callContract(address, transactonData.at(i), _sequence.at(i));
@ -231,13 +233,19 @@ 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 newAddress = m_client->transact(m_client->userAccount().secret(), amount, _code, gas, gasPrice);
if (newAddress != m_contractAddress)
{
m_contractAddress = newAddress;
@ -256,4 +264,3 @@ ExecutionResult ClientModel::callContract(Address const& _contract, bytes const&
}
}

9
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<QString, u256> 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<TransactionSettings> const& _sequence, u256 _balance);
ExecutionResult deployContract(bytes const& _code);
void executeSequence(std::vector<TransactionSettings> 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;

5
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)

4
mix/QContractDefinition.h

@ -36,15 +36,19 @@ class QContractDefinition: public QBasicNodeDefinition
{
Q_OBJECT
Q_PROPERTY(QQmlListProperty<dev::mix::QFunctionDefinition> 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<QFunctionDefinition> functions() const { return QQmlListProperty<QFunctionDefinition>(const_cast<QContractDefinition*>(this), const_cast<QContractDefinition*>(this)->m_functions); }
/// Get the constructor of the contract.
QFunctionDefinition* constructor() const { return m_constructor; }
QList<QFunctionDefinition*> const& functionsList() const { return m_functions; }
private:
QList<QFunctionDefinition*> m_functions;
QFunctionDefinition* m_constructor;
};
}

2
mix/qml.qrc

@ -41,6 +41,8 @@
<file>qml/Ether.qml</file>
<file>qml/EtherValue.qml</file>
<file>qml/BigIntValue.qml</file>
<file>qml/js/QEtherHelper.js</file>
<file>qml/js/TransactionHelper.js</file>
<file>qml/Splitter.qml</file>
</qresource>
</RCC>

6
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

47
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;

1
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 {

19
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);
}

16
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);
}

7
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
}

211
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;
}
}
}
}

8
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;
}

13
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: {}
};
}

8
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 {

4
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; }
}
)";

2
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(); }
}
)";

57
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 <http://www.gnu.org/licenses/>.
*/
/** @file commonjs.cpp
* @author Marek Kotewicz <marek@ethdev.com>
* @date 2014
*/
#include <boost/test/unit_test.hpp>
#include <libdevcore/CommonJS.h>
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()
Loading…
Cancel
Save