From cd70218cd1801a3fe990651efc7cd8ed903b681b Mon Sep 17 00:00:00 2001 From: yann300 Date: Mon, 27 Apr 2015 15:06:21 +0200 Subject: [PATCH 01/17] Deploy To Network: users choose which state to use for deploying --- mix/ClientModel.cpp | 33 ++ mix/ClientModel.h | 6 + mix/CodeModel.h | 2 +- mix/ContractCallDataEncoder.cpp | 12 +- mix/ContractCallDataEncoder.h | 2 + mix/qml/DeploymentDialog.qml | 26 +- mix/qml/ProjectModel.qml | 1 + mix/qml/StateListModel.qml | 2 +- mix/qml/js/NetworkDeployment.js | 159 +++++++-- test/webthreestubclient.h | 596 ++++++++++++++++++++++++++++++++ 10 files changed, 794 insertions(+), 45 deletions(-) create mode 100644 test/webthreestubclient.h diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index c0ce36ab5..d305287ee 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -151,6 +151,39 @@ QString ClientModel::encodeAbiString(QString _string) return QString::fromStdString(toHex(encoder.encodeBytes(_string))); } +QString ClientModel::encodeString(QString const& _param) +{ + ContractCallDataEncoder encoder; + return QString::fromStdString(toHex(encoder.encodeBytesParam(_param, 32))); +} + +QStringList ClientModel::encodeParams(QVariant const& _param, QString const& _contract, QString const& _function) +{ + QStringList ret; + CompiledContract const& compilerRes = m_codeModel->contract(_contract); + QList paramsList; + shared_ptr contractDef = compilerRes.sharedContract(); + if (_contract == _function) + paramsList = contractDef->constructor()->parametersList(); + else + for (QFunctionDefinition* tf: contractDef->functionsList()) + if (tf->name() == _function) + { + paramsList = tf->parametersList(); + break; + } + if (paramsList.length() > 0) + for (QVariableDeclaration* var: paramsList) + { + ContractCallDataEncoder encoder; + QSolidityType const* type = var->type(); + QVariant value = _param.toMap().value(var->name()); + encoder.encode(value, type->type()); + ret.push_back(QString::fromStdString(toHex(encoder.encodedData()))); + } + return ret; +} + QVariantMap ClientModel::contractAddresses() const { QVariantMap res; diff --git a/mix/ClientModel.h b/mix/ClientModel.h index dcb62f55d..78bd60598 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -26,8 +26,10 @@ #include #include #include +#include #include #include +#include #include "MachineStates.h" namespace dev @@ -153,6 +155,10 @@ public: Q_INVOKABLE void mine(); /// Get/set code model. Should be set from qml Q_PROPERTY(CodeModel* codeModel MEMBER m_codeModel) + /// Encode parameters + Q_INVOKABLE QStringList encodeParams(QVariant const& _param, QString const& _contract, QString const& _function); + /// Encode parameter + Q_INVOKABLE QString encodeString(QString const& _param); public slots: /// Setup state, run transaction sequence, show debugger for the last transaction diff --git a/mix/CodeModel.h b/mix/CodeModel.h index 6fb914118..b9a6f041d 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -145,7 +145,7 @@ public: CompiledContract const& contract(QString const& _name) const; /// Get contract by name /// @returns nullptr if not found - CompiledContract const* tryGetContract(QString const& _name) const; + Q_INVOKABLE CompiledContract const* tryGetContract(QString const& _name) const; /// Find a contract by document id /// @returns CompiledContract object or null if not found Q_INVOKABLE CompiledContract* contractByDocumentId(QString const& _documentId) const; diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index c561c0017..36089dcae 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -121,9 +121,7 @@ unsigned ContractCallDataEncoder::encodeSingleItem(QString const& _data, Solidit catch (std::exception const&) { // manage input as a string. - QByteArray bytesAr = src.toLocal8Bit(); - result = bytes(bytesAr.begin(), bytesAr.end()); - result = paddedRight(result, alignSize); + result = encodeBytesParam(src, alignSize); } } @@ -167,6 +165,14 @@ QString ContractCallDataEncoder::toString(bool _b) return _b ? "true" : "false"; } +dev::bytes ContractCallDataEncoder::encodeBytesParam(QString const& _str, unsigned alignSize) +{ + bytes result; + QByteArray bytesAr = _str.toLocal8Bit(); + result = bytes(bytesAr.begin(), bytesAr.end()); + return paddedRight(result, alignSize); +} + dev::bytes ContractCallDataEncoder::encodeBytes(QString const& _str) { QByteArray bytesAr = _str.toLocal8Bit(); diff --git a/mix/ContractCallDataEncoder.h b/mix/ContractCallDataEncoder.h index 805f26691..44f65d37a 100644 --- a/mix/ContractCallDataEncoder.h +++ b/mix/ContractCallDataEncoder.h @@ -52,6 +52,8 @@ public: QVariant decode(SolidityType const& _type, bytes const& _value); /// Get all encoded data encoded by encode function. bytes encodedData(); + /// Encode a string to bytes (in order to be used as funtion param) + dev::bytes encodeBytesParam(QString const& _str, unsigned _alignSize); /// Encode a string to ABI bytes dev::bytes encodeBytes(QString const& _str); /// Decode bytes from ABI diff --git a/mix/qml/DeploymentDialog.qml b/mix/qml/DeploymentDialog.qml index 9235bfaab..ade97008a 100644 --- a/mix/qml/DeploymentDialog.qml +++ b/mix/qml/DeploymentDialog.qml @@ -26,6 +26,7 @@ Dialog { property string eth: registrarAddr.text property string currentAccount property alias gasToUse: gasToUseInput.text + property variant paramsModel: [] function close() { @@ -54,8 +55,8 @@ Dialog { requests.push({ //accounts jsonrpc: "2.0", - method: "eth_balanceAt", - params: [ids[k]], + method: "eth_getBalance", + params: [ids[k], 'latest'], id: k }); } @@ -135,6 +136,7 @@ Dialog { TransactionHelper.rpcCall(requests, function (httpRequest, response){ response = response.replace(/,0+/, ''); // ==> result:27,00000000 var count = JSON.parse(response)[0].result + console.log("count " + count); if (k < parseInt(count) && k > 0) { stop(); @@ -247,6 +249,25 @@ Dialog { columns: 2 width: parent.width + DefaultLabel + { + text: qsTr("State:") + } + + Rectangle + { + width: 300 + color: "transparent" + height: 25 + id: paramsRect + ComboBox + { + id: statesList + textRole: "title" + model: projectModel.stateListModel + } + } + DefaultLabel { text: qsTr("Root Registrar address:") @@ -364,6 +385,7 @@ Dialog { } if (!stopForInputError(inError)) { + projectModel.deployedState = statesList.currentText; if (contractRedeploy.checked) deployWarningDialog.open(); else diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index b15c996fb..0bf7c0fb2 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -48,6 +48,7 @@ Item { property CodeEditorView codeEditor: null property var unsavedFiles: [] property alias newProjectDialog: newProjectDialog + property string deployedState //interface function saveAll() { ProjectModelCode.saveAll(); } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index 35d106b5f..cb08790c5 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -246,7 +246,7 @@ Item { function addNewContracts() { //add new contracts for all states var changed = false; - for(var c in codeModel.contracts) { + for (var c in codeModel.contracts) { for (var s = 0; s < stateListModel.count; s++) { var state = stateList[s]; for (var t = 0; t < state.transactions.length; t++) { diff --git a/mix/qml/js/NetworkDeployment.js b/mix/qml/js/NetworkDeployment.js index 627277f20..40963d7c7 100644 --- a/mix/qml/js/NetworkDeployment.js +++ b/mix/qml/js/NetworkDeployment.js @@ -20,6 +20,8 @@ * @date 2015 * Ethereum IDE client. */ +.import org.ethereum.qml.QSolidityType 1.0 as QSolidityType + Qt.include("TransactionHelper.js") @@ -43,40 +45,116 @@ function startDeployProject(erasePrevious) console.log("Deploying " + deploymentId + " to " + jsonRpcUrl); deploymentStarted(); - var ctrNames = Object.keys(codeModel.contracts); var ctrAddresses = {}; - deployContracts(0, ctrAddresses, ctrNames, function (){ + var state = retrieveState(projectModel.deployedState); + if (!state) + { + var txt = qsTr("Unable to find state " + projectModel.deployedState); + deploymentError(txt); + console.log(txt); + return; + } + executeTr(0, state, ctrAddresses, function (){ finalizeDeployment(deploymentId, ctrAddresses); }); } -function deployContracts(ctrIndex, ctrAddresses, ctrNames, callBack) +function retrieveState(state) { - var code = codeModel.contracts[ctrNames[ctrIndex]].codeHex; - var requests = [{ - jsonrpc: "2.0", - method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": deploymentDialog.gasToUse, "code": code } ], - id: 0 - }]; - rpcCall(requests, function (httpCall, response){ - var txt = qsTr("Please wait while " + ctrNames[ctrIndex] + " is published ...") - deploymentStepChanged(txt); - console.log(txt); - ctrAddresses[ctrNames[ctrIndex]] = JSON.parse(response)[0].result - deploymentDialog.waitForTrCountToIncrement(function(status) { - if (status === -1) + for (var k = 0; k < projectModel.stateListModel.count; k++) + { + if (projectModel.stateListModel.get(k).title === state) + return projectModel.stateListModel.get(k); + } + return null; +} + +function replaceParamToken(paramsDef, params, ctrAddresses) +{ + var retParams = {}; + for (var k in paramsDef) + { + var value = ""; + if (params[paramsDef[k].name] !== undefined) + { + value = params[paramsDef[k].name]; + if (paramsDef[k].type.category === 4 && value.indexOf("<") === 0) { - trCountIncrementTimeOut(); - return; + value = value.replace("<", "").replace(">", ""); + value = ctrAddresses[value]; } - ctrIndex++; - if (ctrIndex < ctrNames.length) - deployContracts(ctrIndex, ctrAddresses, ctrNames, callBack); - else - callBack(); + } + retParams[paramsDef[k].name] = value; + } + return retParams; +} + +function getFunction(ctrName, functionId) +{ + if (codeModel.contracts[ctrName] === undefined) + return null; + if (ctrName === functionId) + return codeModel.contracts[ctrName].contract.constructor; + else + { + for (var j in codeModel.contracts[ctrName].contract.functions) + { + if (codeModel.contracts[ctrName].contract.functions[j].name === functionId) + return codeModel.contracts[ctrName].contract.functions[j]; + } + } +} + +function executeTr(trIndex, state, ctrAddresses, callBack) +{ + var tr = state.transactions.get(trIndex); + var func = getFunction(tr.contractId, tr.functionId); + if (!func) + executeTrNextStep(trIndex, state, ctrAddresses, callBack); + else + { + var rpcParams = { "from": deploymentDialog.currentAccount, "gas": deploymentDialog.gasToUse }; + var params = replaceParamToken(func.parameters, tr.parameters, ctrAddresses); + var encodedParams = clientModel.encodeParams(params, tr.contractId, tr.functionId); + + if (state.contractId === state.functionId) + rpcParams.code = codeModel.contracts[tr.contractId].codeHex + encodedParams.join(""); + else + rpcParams.data = func.hash + encodedParams.join(""); + + var requests = [{ + jsonrpc: "2.0", + method: "eth_sendTransaction", + params: [ rpcParams ], + id: jsonRpcRequestId + }]; + + rpcCall(requests, function (httpCall, response){ + var txt = qsTr(tr.contractId + "." + tr.functionId + "() ...") + deploymentStepChanged(txt); + console.log(txt); + if (tr.contractId === tr.functionId) + { + ctrAddresses[tr.contractId] = JSON.parse(response)[0].result + ctrAddresses[tr.contractId + " - " + trIndex] = JSON.parse(response)[0].result //get right ctr address if deploy more than one contract of same type. + } + deploymentDialog.waitForTrCountToIncrement(function(status) { + if (status === -1) + trCountIncrementTimeOut(); + else + executeTrNextStep(trIndex, state, ctrAddresses, callBack) + }); }); - }); + } +} + +function executeTrNextStep(trIndex, state, ctrAddresses, callBack) +{ + trIndex++; + if (trIndex < state.transactions.count) + executeTr(trIndex, state, ctrAddresses, callBack); + else + callBack(); } function finalizeDeployment(deploymentId, addresses) { @@ -144,14 +222,19 @@ function checkEthPath(dappUrl, callBack) registerContentHash(deploymentDialog.eth, callBack); // we directly create a dapp under the root registrar. else { - // the first owned reigstrar must have been created to follow the path. - var str = createString(dappUrl[0]); + // the first owned registrar must have been created to follow the path. + var str = clientModel.encodeString(dappUrl[0]); + console.log("prarma = " + str + " " + deploymentDialog.eth); + + console.log("0x5a3a05bd" + str); + console.log(deploymentDialog.currentAccount); + console.log(deploymentDialog.eth); var requests = []; requests.push({ - //register() + //subRegistrar() jsonrpc: "2.0", method: "eth_call", - params: [ { "gas": 150000, "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0x6be16bed" + str.encodeValueAsString() } ], + params: [ { "gas": 150000, "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0x5a3a05bd" + str } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -183,12 +266,12 @@ function checkRegistration(dappUrl, addr, callBack) console.log(txt); var requests = []; var registrar = {} - var str = createString(dappUrl[0]); + var str = clientModel.encodeString(dappUrl[0]); requests.push({ //getOwner() jsonrpc: "2.0", method: "eth_call", - params: [ { "gas" : 2000, "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x893d20e8" } ], + params: [ { "gas" : 2000, "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x02571be3" } ], id: jsonRpcRequestId++ }); @@ -196,7 +279,7 @@ function checkRegistration(dappUrl, addr, callBack) //register() jsonrpc: "2.0", method: "eth_call", - params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x6be16bed" + str.encodeValueAsString() } ], + params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x5a3a05bd" + str } ], id: jsonRpcRequestId++ }); @@ -232,7 +315,7 @@ function checkRegistration(dappUrl, addr, callBack) requests.push({ jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": 20000, "code": "0x60056013565b61059e8061001d6000396000f35b33600081905550560060003560e060020a90048063019848921461009a578063449c2090146100af5780635d574e32146100cd5780635fd4b08a146100e1578063618242da146100f65780636be16bed1461010b5780636c4489b414610129578063893d20e8146101585780639607730714610173578063c284bc2a14610187578063e50f599a14610198578063e5811b35146101af578063ec7b9200146101cd57005b6100a560043561031b565b8060005260206000f35b6100ba6004356103a0565b80600160a060020a031660005260206000f35b6100db600435602435610537565b60006000f35b6100ec600435610529565b8060005260206000f35b6101016004356103dd565b8060005260206000f35b6101166004356103bd565b80600160a060020a031660005260206000f35b61013460043561034b565b82600160a060020a031660005281600160a060020a03166020528060405260606000f35b610160610341565b80600160a060020a031660005260206000f35b6101816004356024356102b4565b60006000f35b6101926004356103fd565b60006000f35b6101a96004356024356044356101f2565b60006000f35b6101ba6004356101eb565b80600160a060020a031660005260206000f35b6101d8600435610530565b80600160a060020a031660005260206000f35b6000919050565b600054600160a060020a031633600160a060020a031614610212576102af565b8160026000858152602001908152602001600020819055508061023457610287565b81600160a060020a0316837f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a3826001600084600160a060020a03168152602001908152602001600020819055505b827f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505050565b600054600160a060020a031633600160a060020a0316146102d457610317565b806002600084815260200190815260200160002060010181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b5050565b60006001600083600160a060020a03168152602001908152602001600020549050919050565b6000600054905090565b6000600060006002600085815260200190815260200160002054925060026000858152602001908152602001600020600101549150600260008581526020019081526020016000206002015490509193909250565b600060026000838152602001908152602001600020549050919050565b600060026000838152602001908152602001600020600101549050919050565b600060026000838152602001908152602001600020600201549050919050565b600054600160a060020a031633600160a060020a03161461041d57610526565b80600160006002600085815260200190815260200160002054600160a060020a031681526020019081526020016000205414610458576104d2565b6002600082815260200190815260200160002054600160a060020a0316817f680ad70765443c2967675ab0fb91a46350c01c6df59bf9a41ff8a8dd097464ec60006000a36000600160006002600085815260200190815260200160002054600160a060020a03168152602001908152602001600020819055505b6002600082815260200190815260200160002060008101600090556001810160009055600281016000905550807f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b50565b6000919050565b6000919050565b600054600160a060020a031633600160a060020a0316146105575761059a565b806002600084815260200190815260200160002060020181905550817f18d67da0cd86808336a3aa8912f6ea70c5250f1a98b586d1017ef56fe199d4fc60006000a25b505056" } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": 20000, "code": "0x600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317815561058990819061003990396000f3007c010000000000000000000000000000000000000000000000000000000060003504630198489281146100a757806302571be3146100d957806321f8a721146100e35780632dff6941146100ed5780633b3b57de1461010d5780635a3a05bd1461013d5780635fd4b08a1461017057806389a69c0e1461017c578063b5c645bd146101b0578063be99a9801461022c578063c3d014d614610264578063d93e75731461029857005b73ffffffffffffffffffffffffffffffffffffffff600435166000908152600160205260409020548060005260206000f35b6000808052602081f35b6000808052602081f35b600435600090815260026020819052604090912001548060005260206000f35b600435600090815260026020908152604082205473ffffffffffffffffffffffffffffffffffffffff1680835291f35b600435600090815260026020908152604082206001015473ffffffffffffffffffffffffffffffffffffffff1680835291f35b60008060005260206000f35b6000546102c89060043590602435903373ffffffffffffffffffffffffffffffffffffffff908116911614610451576104b1565b600435600090815260026020819052604090912080546001820154919092015473ffffffffffffffffffffffffffffffffffffffff9283169291909116908273ffffffffffffffffffffffffffffffffffffffff166000528173ffffffffffffffffffffffffffffffffffffffff166020528060405260606000f35b6000546102ce906004359060243590604435903373ffffffffffffffffffffffffffffffffffffffff9081169116146104b557610584565b6000546102d49060043590602435903373ffffffffffffffffffffffffffffffffffffffff9081169116146102e05761031d565b6000546102da90600435903373ffffffffffffffffffffffffffffffffffffffff9081169116146103215761044e565b60006000f35b60006000f35b60006000f35b60006000f35b600082815260026020819052604080832090910183905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b60008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff1683526001909152902054811461035e576103de565b6000818152600260205260408082205473ffffffffffffffffffffffffffffffffffffffff169183917ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85459190a360008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091528120555b600081815260026020819052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168255600182018054909116905590910182905582917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b50565b60008281526002602052604080822060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b600083815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016831790558061051c57827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc60006040a2610583565b73ffffffffffffffffffffffffffffffffffffffff8216837ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a854560006040a373ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090208390555b5b50505056" } ], id: jsonRpcRequestId++ }); @@ -248,12 +331,12 @@ function checkRegistration(dappUrl, addr, callBack) trCountIncrementTimeOut(); return; } - var crLevel = createString(dappUrl[0]).encodeValueAsString(); + var crLevel = clientModel.encodeString(dappUrl[0]); requests.push({ //setRegister() jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "to": '0x' + addr, "data": "0x96077307" + crLevel + deploymentDialog.pad(newCtrAddress) } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "to": '0x' + addr, "data": "0x89a69c0e" + crLevel + deploymentDialog.pad(newCtrAddress) } ], id: jsonRpcRequestId++ }); @@ -286,7 +369,7 @@ function registerContentHash(registrar, callBack) //setContent() jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "gasPrice": "10", "to": '0x' + registrar, "data": "0x5d574e32" + paramTitle + deploymentDialog.packageHash } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "gasPrice": "10", "to": '0x' + registrar, "data": "0xc3d014d6" + paramTitle + deploymentDialog.packageHash } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -298,12 +381,12 @@ function registerToUrlHint() { deploymentStepChanged(qsTr("Registering application Resources (" + deploymentDialog.applicationUrlHttp) + ") ..."); var requests = []; - var paramUrlHttp = createString(deploymentDialog.applicationUrlHttp); + var paramUrlHttp = clientModel.encodeString(deploymentDialog.applicationUrlHttp); requests.push({ //urlHint => suggestUrl jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "to": '0x' + deploymentDialog.urlHintContract, "gas": 30000, "data": "0x4983e19c" + deploymentDialog.packageHash + paramUrlHttp.encodeValueAsString() } ], + params: [ { "to": '0x' + deploymentDialog.urlHintContract, "gas": 30000, "data": "0x584e86ad" + deploymentDialog.packageHash + paramUrlHttp } ], id: jsonRpcRequestId++ }); diff --git a/test/webthreestubclient.h b/test/webthreestubclient.h new file mode 100644 index 000000000..fd71bfb5d --- /dev/null +++ b/test/webthreestubclient.h @@ -0,0 +1,596 @@ +/** + * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! + */ + +#ifndef JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ +#define JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ + +#include + +class WebThreeStubClient : public jsonrpc::Client +{ + public: + WebThreeStubClient(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {} + + std::string web3_sha3(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("web3_sha3",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string web3_clientVersion() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("web3_clientVersion",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string net_version() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("net_version",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string net_peerCount() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("net_peerCount",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool net_listening() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("net_listening",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_protocolVersion() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_protocolVersion",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_hashrate() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_hashrate",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_coinbase() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_coinbase",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_mining() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_mining",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_gasPrice() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_gasPrice",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_accounts() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_accounts",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_blockNumber() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_blockNumber",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getBalance(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getBalance",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("eth_getStorageAt",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getTransactionCount(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getTransactionCount",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getBlockTransactionCountByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getBlockTransactionCountByHash",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getBlockTransactionCountByNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getBlockTransactionCountByNumber",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getUncleCountByBlockHash(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getUncleCountByBlockHash",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getUncleCountByBlockNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getUncleCountByBlockNumber",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_getCode(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getCode",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_sendTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_sendTransaction",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_call(const Json::Value& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_call",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_flush() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_flush",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getBlockByHash(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getBlockByHash",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getBlockByNumber(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getBlockByNumber",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getTransactionByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getTransactionByHash",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getTransactionByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getTransactionByBlockHashAndIndex",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getTransactionByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getTransactionByBlockNumberAndIndex",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getUncleByBlockHashAndIndex",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getUncleByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("eth_getUncleByBlockNumberAndIndex",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getCompilers() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_getCompilers",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_compileLLL(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_compileLLL",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_compileSerpent(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_compileSerpent",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_compileSolidity(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_compileSolidity",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_newFilter",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_newBlockFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_newBlockFilter",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_uninstallFilter",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getFilterChanges",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getFilterLogs(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getFilterLogs",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getLogs(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_getLogs",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_getWork() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("eth_getWork",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("eth_submitWork",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string eth_register(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_register",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_unregister(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_unregister",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_fetchQueuedTransactions(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_fetchQueuedTransactions",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + p.append(param3); + Json::Value result = this->CallMethod("db_put",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string db_get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("db_get",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool shh_post(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_post",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string shh_newIdentity() throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p = Json::nullValue; + Json::Value result = this->CallMethod("shh_newIdentity",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool shh_hasIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_hasIdentity",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string shh_newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("shh_newGroup",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string shh_addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + p.append(param2); + Json::Value result = this->CallMethod("shh_addToGroup",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + std::string shh_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_newFilter",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool shh_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_uninstallFilter",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value shh_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_getFilterChanges",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value shh_getMessages(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("shh_getMessages",p); + if (result.isArray()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } +}; + +#endif //JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ From 4bc11ad6cbf46d9445aa7d65c87dcbc649300df9 Mon Sep 17 00:00:00 2001 From: yann300 Date: Tue, 28 Apr 2015 13:42:28 +0200 Subject: [PATCH 02/17] fix bug why deploying to network --- alethzero/DappLoader.cpp | 10 +++++----- mix/ClientModel.cpp | 4 ++-- mix/ClientModel.h | 2 +- mix/ContractCallDataEncoder.cpp | 4 ++-- mix/ContractCallDataEncoder.h | 2 +- mix/qml/DeploymentDialog.qml | 6 +++--- mix/qml/js/NetworkDeployment.js | 21 +++++++++++++-------- 7 files changed, 27 insertions(+), 22 deletions(-) diff --git a/alethzero/DappLoader.cpp b/alethzero/DappLoader.cpp index 69555521d..f179734a2 100644 --- a/alethzero/DappLoader.cpp +++ b/alethzero/DappLoader.cpp @@ -39,8 +39,8 @@ using namespace dev; using namespace dev::eth; using namespace dev::crypto; -Address c_registrar = Address("0000000000000000000000000000000000000a28"); -Address c_urlHint = Address("0000000000000000000000000000000000000a29"); +Address c_registrar = Address("6a16d3a392de03c67c1880acca6a9d650015c8ae"); +Address c_urlHint = Address("43c6d48ef55d10a786eb3e244824c820d5359b43"); QString contentsOfQResource(std::string const& res); @@ -73,19 +73,19 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri) string32 name = ZeroString32; QByteArray utf8 = parts[partIndex].toUtf8(); std::copy(utf8.data(), utf8.data() + utf8.size(), name.data()); - address = abiOut
(web3()->ethereum()->call(address, abiIn("addr(string32)", name)).output); + address = abiOut
(web3()->ethereum()->call(address, abiIn("subRegistrar(bytes32)", name)).output); domainParts.append(parts[partIndex]); if (!address) { //we have the address of the last part, try to get content hash - contentHash = abiOut(web3()->ethereum()->call(lastAddress, abiIn("content(string32)", name)).output); + contentHash = abiOut(web3()->ethereum()->call(lastAddress, abiIn("content(bytes32)", name)).output); if (!contentHash) throw dev::Exception() << errinfo_comment("Can't resolve address"); } ++partIndex; } - string32 contentUrl = abiOut(web3()->ethereum()->call(c_urlHint, abiIn("url(hash256)", contentHash)).output); + string32 contentUrl = abiOut(web3()->ethereum()->call(c_urlHint, abiIn("url(bytes32)", contentHash)).output); QString domain = domainParts.join('/'); parts.erase(parts.begin(), parts.begin() + partIndex); QString path = parts.join('/'); diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index d305287ee..11122c9ee 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -151,10 +151,10 @@ QString ClientModel::encodeAbiString(QString _string) return QString::fromStdString(toHex(encoder.encodeBytes(_string))); } -QString ClientModel::encodeString(QString const& _param) +QString ClientModel::encodeStringParam(QString const& _param) { ContractCallDataEncoder encoder; - return QString::fromStdString(toHex(encoder.encodeBytesParam(_param, 32))); + return QString::fromStdString(toHex(encoder.encodeStringParam(_param, 32))); } QStringList ClientModel::encodeParams(QVariant const& _param, QString const& _contract, QString const& _function) diff --git a/mix/ClientModel.h b/mix/ClientModel.h index 78bd60598..79cbe27be 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -158,7 +158,7 @@ public: /// Encode parameters Q_INVOKABLE QStringList encodeParams(QVariant const& _param, QString const& _contract, QString const& _function); /// Encode parameter - Q_INVOKABLE QString encodeString(QString const& _param); + Q_INVOKABLE QString encodeStringParam(QString const& _param); public slots: /// Setup state, run transaction sequence, show debugger for the last transaction diff --git a/mix/ContractCallDataEncoder.cpp b/mix/ContractCallDataEncoder.cpp index 36089dcae..8ad4614ab 100644 --- a/mix/ContractCallDataEncoder.cpp +++ b/mix/ContractCallDataEncoder.cpp @@ -121,7 +121,7 @@ unsigned ContractCallDataEncoder::encodeSingleItem(QString const& _data, Solidit catch (std::exception const&) { // manage input as a string. - result = encodeBytesParam(src, alignSize); + result = encodeStringParam(src, alignSize); } } @@ -165,7 +165,7 @@ QString ContractCallDataEncoder::toString(bool _b) return _b ? "true" : "false"; } -dev::bytes ContractCallDataEncoder::encodeBytesParam(QString const& _str, unsigned alignSize) +dev::bytes ContractCallDataEncoder::encodeStringParam(QString const& _str, unsigned alignSize) { bytes result; QByteArray bytesAr = _str.toLocal8Bit(); diff --git a/mix/ContractCallDataEncoder.h b/mix/ContractCallDataEncoder.h index 44f65d37a..cab00dd93 100644 --- a/mix/ContractCallDataEncoder.h +++ b/mix/ContractCallDataEncoder.h @@ -53,7 +53,7 @@ public: /// Get all encoded data encoded by encode function. bytes encodedData(); /// Encode a string to bytes (in order to be used as funtion param) - dev::bytes encodeBytesParam(QString const& _str, unsigned _alignSize); + dev::bytes encodeStringParam(QString const& _str, unsigned _alignSize); /// Encode a string to ABI bytes dev::bytes encodeBytes(QString const& _str); /// Decode bytes from ABI diff --git a/mix/qml/DeploymentDialog.qml b/mix/qml/DeploymentDialog.qml index ade97008a..9a4e18792 100644 --- a/mix/qml/DeploymentDialog.qml +++ b/mix/qml/DeploymentDialog.qml @@ -25,7 +25,7 @@ Dialog { property string packageBase64 property string eth: registrarAddr.text property string currentAccount - property alias gasToUse: gasToUseInput.text + property string gasToUse: "0x188132" //gasToUseInput.text property variant paramsModel: [] function close() @@ -341,7 +341,7 @@ Dialog { width: 200 id: applicationUrlEth onTextChanged: { - appUrlFormatted.text = ProjectModelCode.formatAppUrl(text).join('/'); + appUrlFormatted.text = NetworkDeploymentCode.formatAppUrl(text).join('/'); } } @@ -516,7 +516,7 @@ Dialog { if (applicationUrlHttp.text.length > 32) inError.push(qsTr(applicationUrlHttp.text)); if (!stopForInputError(inError)) - ProjectModelCode.registerToUrlHint(); + NetworkDeploymentCode.registerToUrlHint(); } } } diff --git a/mix/qml/js/NetworkDeployment.js b/mix/qml/js/NetworkDeployment.js index 40963d7c7..b4dca1106 100644 --- a/mix/qml/js/NetworkDeployment.js +++ b/mix/qml/js/NetworkDeployment.js @@ -223,7 +223,7 @@ function checkEthPath(dappUrl, callBack) else { // the first owned registrar must have been created to follow the path. - var str = clientModel.encodeString(dappUrl[0]); + var str = clientModel.encodeStringParam(dappUrl[0]); console.log("prarma = " + str + " " + deploymentDialog.eth); console.log("0x5a3a05bd" + str); @@ -234,7 +234,7 @@ function checkEthPath(dappUrl, callBack) //subRegistrar() jsonrpc: "2.0", method: "eth_call", - params: [ { "gas": 150000, "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0x5a3a05bd" + str } ], + params: [ { "gas": "0xffff", "from": deploymentDialog.currentAccount, "to": '0x' + deploymentDialog.eth, "data": "0x5a3a05bd" + str }, "pending" ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -266,7 +266,7 @@ function checkRegistration(dappUrl, addr, callBack) console.log(txt); var requests = []; var registrar = {} - var str = clientModel.encodeString(dappUrl[0]); + var str = clientModel.encodeStringParam(dappUrl[0]); requests.push({ //getOwner() jsonrpc: "2.0", @@ -331,7 +331,7 @@ function checkRegistration(dappUrl, addr, callBack) trCountIncrementTimeOut(); return; } - var crLevel = clientModel.encodeString(dappUrl[0]); + var crLevel = clientModel.encodeStringParam(dappUrl[0]); requests.push({ //setRegister() jsonrpc: "2.0", @@ -363,13 +363,17 @@ function registerContentHash(registrar, callBack) var txt = qsTr("Finalizing Dapp registration ..."); deploymentStepChanged(txt); console.log(txt); + console.log(" 45 64 564 0 " + deploymentDialog.packageHash); var requests = []; - var paramTitle = clientModel.encodeAbiString(projectModel.projectTitle); + var paramTitle = clientModel.encodeStringParam(projectModel.projectTitle); + console.log("ggg " + paramTitle); + console.log('registrar ' + registrar); + requests.push({ //setContent() jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": 30000, "gasPrice": "10", "to": '0x' + registrar, "data": "0xc3d014d6" + paramTitle + deploymentDialog.packageHash } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": "0xfffff", "to": '0x' + registrar, "data": "0xc3d014d6" + paramTitle + deploymentDialog.packageHash } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -381,12 +385,13 @@ function registerToUrlHint() { deploymentStepChanged(qsTr("Registering application Resources (" + deploymentDialog.applicationUrlHttp) + ") ..."); var requests = []; - var paramUrlHttp = clientModel.encodeString(deploymentDialog.applicationUrlHttp); + var paramUrlHttp = clientModel.encodeStringParam(deploymentDialog.applicationUrlHttp); + console.log("package hash " + deploymentDialog.packageHash); requests.push({ //urlHint => suggestUrl jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "to": '0x' + deploymentDialog.urlHintContract, "gas": 30000, "data": "0x584e86ad" + deploymentDialog.packageHash + paramUrlHttp } ], + params: [ { "to": '0x' + deploymentDialog.urlHintContract, "from": deploymentDialog.currentAccount, "gas": "0xfffff", "data": "0x584e86ad" + deploymentDialog.packageHash + paramUrlHttp } ], id: jsonRpcRequestId++ }); From 2623bee198e4aac0236f4f39f7bb6ced337f9736 Mon Sep 17 00:00:00 2001 From: arkpar Date: Mon, 27 Apr 2015 17:50:20 +0200 Subject: [PATCH 03/17] import/export state --- alethzero/CMakeLists.txt | 3 +- alethzero/ExportState.cpp | 183 ++++++++++ alethzero/ExportState.h | 57 +++ alethzero/ExportState.ui | 183 ++++++++++ alethzero/Main.ui | 7 + alethzero/MainWin.cpp | 7 + alethzero/MainWin.h | 1 + mix/ClientModel.cpp | 45 ++- mix/ClientModel.h | 5 +- mix/MixClient.cpp | 18 +- mix/MixClient.h | 4 +- mix/qml/StateDialog.qml | 427 ++++++++++++++--------- mix/qml/StateListModel.qml | 15 +- test/libweb3jsonrpc/webthreestubclient.h | 30 ++ 14 files changed, 797 insertions(+), 188 deletions(-) create mode 100644 alethzero/ExportState.cpp create mode 100644 alethzero/ExportState.h create mode 100644 alethzero/ExportState.ui diff --git a/alethzero/CMakeLists.txt b/alethzero/CMakeLists.txt index d9e8dff6f..9abb3f1a4 100644 --- a/alethzero/CMakeLists.txt +++ b/alethzero/CMakeLists.txt @@ -22,6 +22,7 @@ qt5_wrap_ui(ui_Main.h Main.ui) qt5_wrap_ui(ui_Connect.h Connect.ui) qt5_wrap_ui(ui_Debugger.h Debugger.ui) qt5_wrap_ui(ui_Transact.h Transact.ui) +qt5_wrap_ui(ui_ExportState.h ExportState.ui) file(GLOB HEADERS "*.h") @@ -34,7 +35,7 @@ endif () # eth_add_executable is defined in cmake/EthExecutableHelper.cmake eth_add_executable(${EXECUTABLE} ICON alethzero - UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui + UI_RESOURCES alethzero.icns Main.ui Connect.ui Debugger.ui Transact.ui ExportState.ui WIN_RESOURCES alethzero.rc ) diff --git a/alethzero/ExportState.cpp b/alethzero/ExportState.cpp new file mode 100644 index 000000000..e39b74b76 --- /dev/null +++ b/alethzero/ExportState.cpp @@ -0,0 +1,183 @@ +/* + 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 ExportState.cpp + * @author Arkadiy Paronyan + * @date 2015 + */ + +#include "ExportState.h" +#include +#include +#include +#include "MainWin.h" +#include "ui_ExportState.h" + +using namespace std; +using namespace dev; +using namespace dev::eth; + +ExportStateDialog::ExportStateDialog(Main* _parent): + QDialog(_parent), + ui(new Ui::ExportState), + m_main(_parent) +{ + ui->setupUi(this); + connect(ui->close, &QPushButton::clicked, this, &ExportStateDialog::close); + connect(ui->accounts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON); + connect(ui->contracts, &QListWidget::itemSelectionChanged, this, &ExportStateDialog::generateJSON); + fillBlocks(); +} + +ExportStateDialog::~ExportStateDialog() +{ +} + +dev::eth::Client* ExportStateDialog::ethereum() const +{ + return m_main->ethereum(); +} + +void ExportStateDialog::on_block_editTextChanged() +{ + QString text = ui->block->currentText(); + int i = ui->block->count(); + while (i-- >= 0) + if (ui->block->itemText(i) == text) + return; + fillBlocks(); +} + +void ExportStateDialog::on_block_currentIndexChanged(int _index) +{ + m_block = ui->block->itemData(_index).toUInt(); + fillContracts(); +} + +void ExportStateDialog::fillBlocks() +{ + BlockChain const& bc = ethereum()->blockChain(); + QStringList filters = ui->block->currentText().toLower().split(QRegExp("\\s+"), QString::SkipEmptyParts); + const unsigned numLastBlocks = 10; + if (ui->block->count() == 0) + { + unsigned i = numLastBlocks; + for (auto h = bc.currentHash(); bc.details(h) && i; h = bc.details(h).parent, --i) + { + auto d = bc.details(h); + ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number); + if (h == bc.genesisHash()) + break; + } + if (ui->block->currentIndex() < 0) + ui->block->setCurrentIndex(0); + m_recentBlocks = numLastBlocks - i; + } + + int i = ui->block->count(); + while (i > 0 && i >= m_recentBlocks) + ui->block->removeItem(i--); + + h256Set blocks; + for (QString f: filters) + { + if (f.startsWith("#")) + f = f.remove(0, 1); + if (f.size() == 64) + { + h256 h(f.toStdString()); + if (bc.isKnown(h)) + blocks.insert(h); + for (auto const& b: bc.withBlockBloom(LogBloom().shiftBloom<3>(sha3(h)), 0, -1)) + blocks.insert(bc.numberHash(b)); + } + else if (f.toLongLong() <= bc.number()) + blocks.insert(bc.numberHash((unsigned)f.toLongLong())); + else if (f.size() == 40) + { + Address h(f.toStdString()); + for (auto const& b: bc.withBlockBloom(LogBloom().shiftBloom<3>(sha3(h)), 0, -1)) + blocks.insert(bc.numberHash(b)); + } + } + + for (auto const& h: blocks) + { + auto d = bc.details(h); + ui->block->addItem(QString("#%1 %2").arg(d.number).arg(h.abridged().c_str()), d.number); + } +} + +void ExportStateDialog::fillContracts() +{ + ui->accounts->clear(); + ui->contracts->clear(); + ui->accounts->setEnabled(true); + ui->contracts->setEnabled(true); + for (auto i: ethereum()->addresses(m_block)) + { + QString r = m_main->render(i); + (new QListWidgetItem(QString("%2: %1 [%3]").arg(formatBalance(ethereum()->balanceAt(i)).c_str()).arg(r).arg((unsigned)ethereum()->countAt(i)), ethereum()->codeAt(i).empty() ? ui->accounts : ui->contracts)) + ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); + } +} + +void ExportStateDialog::generateJSON() +{ + std::stringstream json; + json << "{\n"; + std::string prefix; + for(QListWidgetItem* item: ui->accounts->selectedItems()) + { + auto hba = item->data(Qt::UserRole).toByteArray(); + auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer); + json << prefix << "\t\"" << toHex(address.ref()) << "\": { \"wei\": \"" << ethereum()->balanceAt(address, m_block) << "\" }"; + prefix = ",\n"; + } + for(QListWidgetItem* item: ui->contracts->selectedItems()) + { + auto hba = item->data(Qt::UserRole).toByteArray(); + auto address = Address((byte const*)hba.data(), Address::ConstructFromPointer); + json << prefix << "\t\"" << toHex(address.ref()) << "\":\n\t{\n\t\t\"wei\": \"" << ethereum()->balanceAt(address, m_block) << "\",\n"; + json << "\t\t\"code\": \"" << toHex(ethereum()->codeAt(address, m_block)) << "\",\n"; + std::map storage = ethereum()->storageAt(address, m_block); + if (!storage.empty()) + { + json << "\t\t\"storage\":\n\t\t{\n"; + for (auto s: storage) + json << "\t\t\t\"" << toHex(s.first) << "\": \"" << toHex(s.second) << "\"" << (s.first == storage.rbegin()->first ? "" : ",") <<"\n"; + json << "\t\t}\n"; + } + json << "\t}"; + prefix = ",\n"; + } + json << "\n}"; + json.flush(); + + ui->json->setEnabled(true); + ui->json->setText(QString::fromStdString(json.str())); + ui->saveButton->setEnabled(true); +} + +void ExportStateDialog::on_saveButton_clicked() +{ + QString fn = QFileDialog::getSaveFileName(this, "Save state", QString(), "JSON Files (*.json)"); + if (!fn.endsWith(".json")) + fn = fn.append(".json"); + ofstream file(fn.toStdString()); + if (file.is_open()) + file << ui->json->toPlainText().toStdString(); +} diff --git a/alethzero/ExportState.h b/alethzero/ExportState.h new file mode 100644 index 000000000..e8e045855 --- /dev/null +++ b/alethzero/ExportState.h @@ -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 ExportState.h + * @author Arkadiy Paronyan + * @date 2015 + */ + +#pragma once + +#include +#include +#include + +namespace Ui { class ExportState; } +namespace dev { namespace eth { class Client; } } + +class Main; + +class ExportStateDialog: public QDialog +{ + Q_OBJECT + +public: + explicit ExportStateDialog(Main* _parent = 0); + virtual ~ExportStateDialog(); + +private slots: + void on_block_editTextChanged(); + void on_block_currentIndexChanged(int _index); + void on_saveButton_clicked(); + +private: + dev::eth::Client* ethereum() const; + void fillBlocks(); + void fillContracts(); + void generateJSON(); + +private: + std::unique_ptr ui; + Main* m_main; + int m_recentBlocks = 0; + dev::eth::BlockNumber m_block = dev::eth::LatestBlock; +}; diff --git a/alethzero/ExportState.ui b/alethzero/ExportState.ui new file mode 100644 index 000000000..96256bc7f --- /dev/null +++ b/alethzero/ExportState.ui @@ -0,0 +1,183 @@ + + + ExportState + + + + 0 + 0 + 490 + 522 + + + + Export State + + + true + + + + + + + 0 + 0 + + + + &Block + + + block + + + + + + + true + + + + + + + + + + &Accounts + + + accounts + + + + + + + false + + + + 0 + 1 + + + + QAbstractItemView::MultiSelection + + + + + + + &Contracts + + + contracts + + + + + + + false + + + + 0 + 1 + + + + QAbstractItemView::MultiSelection + + + + + + + + 0 + 0 + + + + &JSON + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + json + + + + + + + false + + + + 0 + 2 + + + + true + + + + + + + + + false + + + + 0 + 0 + + + + &Save... + + + Esc + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + &Close + + + Esc + + + + + + + + + + diff --git a/alethzero/Main.ui b/alethzero/Main.ui index 1fd9669e9..ee46017f5 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -160,6 +160,8 @@ + + @@ -1478,6 +1480,11 @@ font-size: 14pt &Load Javascript... + + + &Export State... + + false diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 247e7fde3..023351361 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -72,6 +72,7 @@ #include "DappLoader.h" #include "DappHost.h" #include "WebPage.h" +#include "ExportState.h" #include "ui_Main.h" using namespace std; using namespace dev; @@ -820,6 +821,12 @@ void Main::on_exportKey_triggered() } } +void Main::on_exportState_triggered() +{ + ExportStateDialog dialog(this); + dialog.exec(); +} + void Main::on_usePrivate_triggered() { if (ui->usePrivate->isChecked()) diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index 4ef1e8d54..2a0c1401d 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -134,6 +134,7 @@ private slots: // Tools void on_newTransaction_triggered(); void on_loadJS_triggered(); + void on_exportState_triggered(); // Stuff concerning the blocks/transactions/accounts panels void ourAccountsRowsMoved(); diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp index c0ce36ab5..7863eb31d 100644 --- a/mix/ClientModel.cpp +++ b/mix/ClientModel.cpp @@ -85,7 +85,7 @@ ClientModel::ClientModel(): connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection); m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString())); - m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), m_client->userAccounts(), m_client.get())); + m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), std::vector(), m_client.get())); connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection); } @@ -169,14 +169,41 @@ QVariantMap ClientModel::gasCosts() const void ClientModel::setupState(QVariantMap _state) { - QVariantList balances = _state.value("accounts").toList(); + QVariantList stateAccounts = _state.value("accounts").toList(); + QVariantList stateContracts = _state.value("contracts").toList(); QVariantList transactions = _state.value("transactions").toList(); - map accounts; - for (auto const& b: balances) + map accounts; + std::vector userAccounts; + + for (auto const& b: stateAccounts) + { + QVariantMap account = b.toMap(); + Address address = {}; + if (account.contains("secret")) + { + KeyPair key(Secret(account.value("secret").toString().toStdString())); + userAccounts.push_back(key); + address = key.address(); + } + else if (account.contains("address")) + address = Address(fromHex(account.value("address").toString().toStdString())); + if (!address) + continue; + + accounts[address] = Account(qvariant_cast(account.value("balance"))->toU256Wei(), Account::NormalCreation); + } + for (auto const& c: stateContracts) { - QVariantMap address = b.toMap(); - accounts.insert(make_pair(Secret(address.value("secret").toString().toStdString()), (qvariant_cast(address.value("balance")))->toU256Wei())); + QVariantMap contract = c.toMap(); + Address address = Address(fromHex(contract.value("address").toString().toStdString())); + Account account(qvariant_cast(contract.value("balance"))->toU256Wei(), Account::ContractConception); + bytes code = fromHex(contract.value("code").toString().toStdString()); + account.setCode(code); + QVariantMap storageMap = contract.value("storage").toMap(); + for(auto s = storageMap.cbegin(); s != storageMap.cend(); ++s) + account.setStorage(fromBigEndian(fromHex(s.key().toStdString())), fromBigEndian(fromHex(s.value().toString().toStdString()))); + accounts[address] = account; } vector transactionSequence; @@ -215,10 +242,11 @@ void ClientModel::setupState(QVariantMap _state) transactionSequence.push_back(transactionSettings); } } + m_web3Server->setAccounts(userAccounts); executeSequence(transactionSequence, accounts, Secret(_state.value("miner").toMap().value("secret").toString().toStdString())); } -void ClientModel::executeSequence(vector const& _sequence, map const& _balances, Secret const& _miner) +void ClientModel::executeSequence(vector const& _sequence, std::map const& _accounts, Secret const& _miner) { if (m_running) { @@ -230,8 +258,7 @@ void ClientModel::executeSequence(vector const& _sequence, emit runStarted(); emit runStateChanged(); - m_client->resetState(_balances, _miner); - m_web3Server->setAccounts(m_client->userAccounts()); + m_client->resetState(_accounts, _miner); //run sequence m_runFuture = QtConcurrent::run([=]() { diff --git a/mix/ClientModel.h b/mix/ClientModel.h index dcb62f55d..714b81431 100644 --- a/mix/ClientModel.h +++ b/mix/ClientModel.h @@ -32,6 +32,9 @@ namespace dev { + +namespace eth { class Account; } + namespace mix { @@ -209,7 +212,7 @@ private: RecordLogEntry* lastBlock() const; QVariantMap contractAddresses() const; QVariantMap gasCosts() const; - void executeSequence(std::vector const& _sequence, std::map const& _balances, Secret const& _miner); + void executeSequence(std::vector const& _sequence, std::map const& _accounts, Secret const& _miner); dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); void callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); void onNewTransaction(); diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index 0b7d22f3f..3fb325bd4 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -39,7 +39,6 @@ namespace dev namespace mix { -Secret const c_defaultUserAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074"); u256 const c_mixGenesisDifficulty = 131072; //TODO: make it lower for Mix somehow namespace @@ -69,16 +68,14 @@ bytes MixBlockChain::createGenesisBlock(h256 _stateRoot) MixClient::MixClient(std::string const& _dbPath): m_dbPath(_dbPath) { - std::map account; - account.insert(std::make_pair(c_defaultUserAccountSecret, 1000000 * ether)); - resetState(account); + resetState(std::map()); } MixClient::~MixClient() { } -void MixClient::resetState(std::map _accounts, Secret _miner) +void MixClient::resetState(std::map const& _accounts, Secret const& _miner) { WriteGuard l(x_state); Guard fl(x_filtersWatches); @@ -89,16 +86,7 @@ void MixClient::resetState(std::map _accounts, Secret _miner) SecureTrieDB accountState(&m_stateDB); accountState.init(); - m_userAccounts.clear(); - std::map genesisState; - for (auto account: _accounts) - { - KeyPair a = KeyPair(account.first); - m_userAccounts.push_back(a); - genesisState.insert(std::make_pair(a.address(), Account(account.second, Account::NormalCreation))); - } - - dev::eth::commit(genesisState, static_cast(m_stateDB), accountState); + dev::eth::commit(_accounts, static_cast(m_stateDB), accountState); h256 stateRoot = accountState.root(); m_bc.reset(); m_bc.reset(new MixBlockChain(m_dbPath, stateRoot)); diff --git a/mix/MixClient.h b/mix/MixClient.h index eec58413b..182e333c2 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -48,7 +48,7 @@ public: MixClient(std::string const& _dbPath); virtual ~MixClient(); /// Reset state to the empty state with given balance. - void resetState(std::map _accounts, Secret _miner = Secret()); + void resetState(std::map const& _accounts, Secret const& _miner = Secret()); void mine(); ExecutionResult lastExecution() const; ExecutionResult execution(unsigned _index) const; @@ -75,7 +75,6 @@ public: /// @returns the last mined block information using Interface::blockInfo; // to remove warning about hiding virtual function eth::BlockInfo blockInfo() const; - std::vector userAccounts() { return m_userAccounts; } protected: /// ClientBase methods @@ -92,7 +91,6 @@ private: void noteChanged(h256Set const& _filters); dev::eth::Transaction replaceGas(dev::eth::Transaction const& _t, dev::Secret const& _secret, dev::u256 const& _gas); - std::vector m_userAccounts; eth::State m_state; eth::State m_startState; OverlayDB m_stateDB; diff --git a/mix/qml/StateDialog.qml b/mix/qml/StateDialog.qml index b85996b29..3a3a060c3 100644 --- a/mix/qml/StateDialog.qml +++ b/mix/qml/StateDialog.qml @@ -14,7 +14,7 @@ Dialog { modality: Qt.ApplicationModal width: 630 - height: 500 + height: 660 title: qsTr("Edit State") visible: false @@ -27,6 +27,7 @@ Dialog { property int stateIndex property var stateTransactions: [] property var stateAccounts: [] + property var stateContracts: [] signal accepted StateDialogStyle { @@ -34,63 +35,67 @@ Dialog { } function open(index, item, setDefault) { - stateIndex = index; - stateTitle = item.title; - transactionsModel.clear(); + stateIndex = index + stateTitle = item.title + transactionsModel.clear() - stateTransactions = []; - var transactions = item.transactions; + stateTransactions = [] + var transactions = item.transactions for (var t = 0; t < transactions.length; t++) { - transactionsModel.append(item.transactions[t]); - stateTransactions.push(item.transactions[t]); + transactionsModel.append(item.transactions[t]) + stateTransactions.push(item.transactions[t]) } - accountsModel.clear(); - stateAccounts = []; - var miner = 0; - for (var k = 0; k < item.accounts.length; k++) - { - accountsModel.append(item.accounts[k]); - stateAccounts.push(item.accounts[k]); + accountsModel.clear() + stateAccounts = [] + var miner = 0 + for (var k = 0; k < item.accounts.length; k++) { + accountsModel.append(item.accounts[k]) + stateAccounts.push(item.accounts[k]) if (item.miner && item.accounts[k].name === item.miner.name) - miner = k; + miner = k } - visible = true; - isDefault = setDefault; - titleField.focus = true; - defaultCheckBox.enabled = !isDefault; - comboMiner.model = stateAccounts; - comboMiner.currentIndex = miner; - forceActiveFocus(); + stateContracts = [] + if (item.contracts) { + for (k = 0; k < item.contracts.length; k++) { + contractsModel.append(item.contracts[k]) + stateContracts.push(item.contracts[k]) + } + } + + visible = true + isDefault = setDefault + titleField.focus = true + defaultCheckBox.enabled = !isDefault + comboMiner.model = stateAccounts + comboMiner.currentIndex = miner + forceActiveFocus() } function acceptAndClose() { - close(); - accepted(); + close() + accepted() } function close() { - visible = false; + visible = false } function getItem() { var item = { title: stateDialog.stateTitle, - transactions: [], - accounts: [] + transactions: stateTransactions, + accounts: stateAccounts, + contracts: stateContracts } - item.transactions = stateTransactions; - item.accounts = stateAccounts; - for (var k = 0; k < stateAccounts.length; k++) - { - if (stateAccounts[k].name === comboMiner.currentText) - { - item.miner = stateAccounts[k]; - break; + for (var k = 0; k < stateAccounts.length; k++) { + if (stateAccounts[k].name === comboMiner.currentText) { + item.miner = stateAccounts[k] + break } } - return item; + return item } contentItem: Rectangle { @@ -106,31 +111,147 @@ Dialog { ColumnLayout { id: dialogContent anchors.top: parent.top - RowLayout - { + RowLayout { Layout.fillWidth: true DefaultLabel { Layout.preferredWidth: 85 text: qsTr("Title") } - DefaultTextField - { + DefaultTextField { id: titleField Layout.fillWidth: true } } - CommonSeparator - { + CommonSeparator { + Layout.fillWidth: true + } + + RowLayout { + Layout.fillWidth: true + + Rectangle { + Layout.preferredWidth: 85 + DefaultLabel { + id: contractsLabel + Layout.preferredWidth: 85 + wrapMode: Text.WrapAnywhere + text: qsTr("Genesis\nContracts") + } + + Button { + id: importStateButton + anchors.top: contractsLabel.bottom + anchors.topMargin: 10 + action: importStateAction + } + + Action { + id: importStateAction + tooltip: qsTr("Import genesis state from JSON file") + text: qsTr("Import...") + onTriggered: { + importJsonFileDialog.open() + } + } + FileDialog { + id: importJsonFileDialog + visible: false + title: qsTr("Select State File") + nameFilters: [qsTr("JSON files (*.json)", "All files (*)")] + onAccepted: { + var path = importJsonFileDialog.fileUrl.toString() + var jsonData = fileIo.readFile(path) + if (jsonData) { + var json = JSON.parse(jsonData) + for (var address in json) { + var account = { + address: address, + name: (json[address].name ? json[address].name : address), + balance: QEtherHelper.createEther(json[address].wei, QEther.Wei), + code: json[address].code, + storage: json[address].storage + } + if (account.code) { + contractsModel.append(account) + stateContracts.push(account) + } else { + accountsModel.append(account) + stateAccounts.push(account) + } + } + } + } + } + } + + TableView { + id: genesisContractsView + Layout.fillWidth: true + model: contractsModel + headerVisible: false + TableViewColumn { + role: "name" + title: qsTr("Name") + width: 230 + delegate: Item { + RowLayout { + height: 25 + width: parent.width + anchors.verticalCenter: parent.verticalCenter + Button { + iconSource: "qrc:/qml/img/delete_sign.png" + action: deleteContractAction + } + + Action { + id: deleteContractAction + tooltip: qsTr("Delete Contract") + onTriggered: { + stateContracts.splice(styleData.row, 1) + contractsModel.remove(styleData.row) + } + } + + DefaultTextField { + anchors.verticalCenter: parent.verticalCenter + onTextChanged: { + if (styleData.row > -1) + stateContracts[styleData.row].name = text + } + text: styleData.value + } + } + } + } + + TableViewColumn { + role: "balance" + title: qsTr("Balance") + width: 200 + delegate: Item { + Ether { + edit: true + displayFormattedValue: false + value: styleData.value + } + } + } + rowDelegate: Rectangle { + color: styleData.alternate ? "transparent" : "#f0f0f0" + height: 30 + } + } + } + + CommonSeparator { Layout.fillWidth: true } - RowLayout - { + RowLayout { Layout.fillWidth: true - Rectangle - { + Rectangle { Layout.preferredWidth: 85 DefaultLabel { id: accountsLabel @@ -138,8 +259,7 @@ Dialog { text: qsTr("Accounts") } - Button - { + Button { id: newAccountButton anchors.top: accountsLabel.bottom anchors.topMargin: 10 @@ -150,31 +270,28 @@ Dialog { Action { id: newAccountAction tooltip: qsTr("Add new Account") - onTriggered: - { - add(); + onTriggered: { + add() } - function add() - { - var account = stateListModel.newAccount("1000000", QEther.Ether); - stateAccounts.push(account); - accountsModel.append(account); - return account; + function add() { + var account = stateListModel.newAccount( + "1000000", QEther.Ether) + stateAccounts.push(account) + accountsModel.append(account) + return account } } } - MessageDialog - { + MessageDialog { id: alertAlreadyUsed text: qsTr("This account is in use. You cannot remove it. The first account is used to deploy config contract and cannot be removed.") icon: StandardIcon.Warning standardButtons: StandardButton.Ok } - TableView - { + TableView { id: accountsView Layout.fillWidth: true model: accountsModel @@ -184,12 +301,10 @@ Dialog { title: qsTr("Name") width: 230 delegate: Item { - RowLayout - { + RowLayout { height: 25 width: parent.width - Button - { + Button { iconSource: "qrc:/qml/img/delete_sign.png" action: deleteAccountAction } @@ -197,18 +312,21 @@ Dialog { Action { id: deleteAccountAction tooltip: qsTr("Delete Account") - onTriggered: - { - if (transactionsModel.isUsed(stateAccounts[styleData.row].secret)) - alertAlreadyUsed.open(); - else - { - if (stateAccounts[styleData.row].name === comboMiner.currentText) - comboMiner.currentIndex = 0; - stateAccounts.splice(styleData.row, 1); - accountsModel.remove(styleData.row); - comboMiner.model = stateAccounts; - comboMiner.update(); + onTriggered: { + if (transactionsModel.isUsed( + stateAccounts[styleData.row].secret)) + alertAlreadyUsed.open() + else { + if (stateAccounts[styleData.row].name + === comboMiner.currentText) + comboMiner.currentIndex = 0 + stateAccounts.splice( + styleData.row, + 1) + accountsModel.remove( + styleData.row) + comboMiner.model = stateAccounts //TODO: filter accounts wo private keys + comboMiner.update() } } } @@ -216,15 +334,14 @@ Dialog { DefaultTextField { anchors.verticalCenter: parent.verticalCenter onTextChanged: { - if (styleData.row > -1) - { + if (styleData.row > -1) { stateAccounts[styleData.row].name = text - var index = comboMiner.currentIndex; - comboMiner.model = stateAccounts; - comboMiner.currentIndex = index; + var index = comboMiner.currentIndex + comboMiner.model = stateAccounts + comboMiner.currentIndex = index } } - text: { + text: { return styleData.value } } @@ -238,28 +355,24 @@ Dialog { width: 200 delegate: Item { Ether { - id: balanceField edit: true displayFormattedValue: false value: styleData.value } } } - rowDelegate: - Rectangle { + rowDelegate: Rectangle { color: styleData.alternate ? "transparent" : "#f0f0f0" - height: 30; + height: 30 } } } - CommonSeparator - { + CommonSeparator { Layout.fillWidth: true } - RowLayout - { + RowLayout { Layout.fillWidth: true DefaultLabel { Layout.preferredWidth: 85 @@ -272,13 +385,11 @@ Dialog { } } - CommonSeparator - { + CommonSeparator { Layout.fillWidth: true } - RowLayout - { + RowLayout { Layout.fillWidth: true DefaultLabel { Layout.preferredWidth: 85 @@ -290,17 +401,14 @@ Dialog { } } - CommonSeparator - { + CommonSeparator { Layout.fillWidth: true } - RowLayout - { + RowLayout { Layout.fillWidth: true - Rectangle - { + Rectangle { Layout.preferredWidth: 85 DefaultLabel { id: transactionsLabel @@ -308,8 +416,7 @@ Dialog { text: qsTr("Transactions") } - Button - { + Button { anchors.top: transactionsLabel.bottom anchors.topMargin: 10 iconSource: "qrc:/qml/img/plus.png" @@ -323,8 +430,7 @@ Dialog { } } - TableView - { + TableView { id: transactionsView Layout.fillWidth: true model: transactionsModel @@ -334,12 +440,10 @@ Dialog { title: qsTr("Name") width: 150 delegate: Item { - RowLayout - { + RowLayout { height: 30 width: parent.width - Button - { + Button { iconSource: "qrc:/qml/img/delete_sign.png" action: deleteTransactionAction } @@ -347,20 +451,23 @@ Dialog { Action { id: deleteTransactionAction tooltip: qsTr("Delete") - onTriggered: transactionsModel.deleteTransaction(styleData.row) + onTriggered: transactionsModel.deleteTransaction( + styleData.row) } - Button - { + Button { iconSource: "qrc:/qml/img/edit.png" action: editAction - visible: styleData.row >= 0 ? !transactionsModel.get(styleData.row).stdContract : false + visible: styleData.row + >= 0 ? !transactionsModel.get( + styleData.row).stdContract : false width: 10 height: 10 Action { id: editAction tooltip: qsTr("Edit") - onTriggered: transactionsModel.editTransaction(styleData.row) + onTriggered: transactionsModel.editTransaction( + styleData.row) } } @@ -368,56 +475,63 @@ Dialog { Layout.preferredWidth: 150 text: { if (styleData.row >= 0) - return transactionsModel.get(styleData.row).functionId; + return transactionsModel.get( + styleData.row).functionId else - return ""; + return "" } } } } } - rowDelegate: - Rectangle { + rowDelegate: Rectangle { color: styleData.alternate ? "transparent" : "#f0f0f0" - height: 30; + height: 30 } } } } - RowLayout - { + RowLayout { anchors.bottom: parent.bottom - anchors.right: parent.right; + anchors.right: parent.right Button { - text: qsTr("Delete"); + text: qsTr("Delete") enabled: !modalStateDialog.isDefault onClicked: { - projectModel.stateListModel.deleteState(stateIndex); - close(); + projectModel.stateListModel.deleteState(stateIndex) + close() } } Button { - text: qsTr("OK"); + text: qsTr("OK") onClicked: { - close(); - accepted(); + close() + accepted() } } Button { - text: qsTr("Cancel"); - onClicked: close(); + text: qsTr("Cancel") + onClicked: close() } } ListModel { id: accountsModel - function removeAccount(_i) - { - accountsModel.remove(_i); - stateAccounts.splice(_i, 1); + function removeAccount(_i) { + accountsModel.remove(_i) + stateAccounts.splice(_i, 1) + } + } + + ListModel { + id: contractsModel + + function removeContract(_i) { + contractsModel.remove(_i) + stateContracts.splice(_i, 1) } } @@ -425,47 +539,46 @@ Dialog { id: transactionsModel function editTransaction(index) { - transactionDialog.stateAccounts = stateAccounts; - transactionDialog.open(index, transactionsModel.get(index)); + transactionDialog.stateAccounts = stateAccounts + transactionDialog.open(index, + transactionsModel.get(index)) } 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 = TransactionHelper.defaultTransaction(); - transactionDialog.stateAccounts = stateAccounts; - transactionDialog.open(transactionsModel.count, item); + var item = TransactionHelper.defaultTransaction() + transactionDialog.stateAccounts = stateAccounts + transactionDialog.open(transactionsModel.count, item) } function deleteTransaction(index) { - stateTransactions.splice(index, 1); - transactionsModel.remove(index); + stateTransactions.splice(index, 1) + transactionsModel.remove(index) } - function isUsed(secret) - { - for (var i in stateTransactions) - { + function isUsed(secret) { + for (var i in stateTransactions) { if (stateTransactions[i].sender === secret) - return true; + return true } - return false; + return false } } - TransactionDialog - { + TransactionDialog { id: transactionDialog - onAccepted: - { - var item = transactionDialog.getItem(); + onAccepted: { + var item = transactionDialog.getItem() if (transactionDialog.transactionIndex < transactionsModel.count) { - transactionsModel.set(transactionDialog.transactionIndex, item); - stateTransactions[transactionDialog.transactionIndex] = item; + transactionsModel.set( + transactionDialog.transactionIndex, + item) + stateTransactions[transactionDialog.transactionIndex] = item } else { - transactionsModel.append(item); - stateTransactions.push(item); + transactionsModel.append(item) + stateTransactions.push(item) } } } diff --git a/mix/qml/StateListModel.qml b/mix/qml/StateListModel.qml index 075a049b6..51df3b1a8 100644 --- a/mix/qml/StateListModel.qml +++ b/mix/qml/StateListModel.qml @@ -18,10 +18,13 @@ Item { function fromPlainStateItem(s) { if (!s.accounts) s.accounts = [stateListModel.newAccount("1000000", QEther.Ether, defaultAccount)]; //support for old project + if (!s.contracts) + s.contracts = []; return { title: s.title, transactions: s.transactions.map(fromPlainTransactionItem), accounts: s.accounts.map(fromPlainAccountItem), + contracts: s.contracts.map(fromPlainAccountItem), miner: s.miner }; } @@ -30,8 +33,11 @@ Item { { return { name: t.name, + address: t.address, secret: t.secret, - balance: QEtherHelper.createEther(t.balance.value, t.balance.unit) + balance: QEtherHelper.createEther(t.balance.value, t.balance.unit), + storage: t.storage, + code: t.code, }; } @@ -62,6 +68,7 @@ Item { title: s.title, transactions: s.transactions.map(toPlainTransactionItem), accounts: s.accounts.map(toPlainAccountItem), + contracts: s.contracts.map(toPlainAccountItem), miner: s.miner }; } @@ -85,6 +92,9 @@ Item { value: t.balance.value, unit: t.balance.unit }, + address: t.address, + storage: t.storage, + code: t.code, }; } @@ -190,7 +200,8 @@ Item { var item = { title: "", transactions: [], - accounts: [] + accounts: [], + contracts: [] }; var account = newAccount("1000000", QEther.Ether, defaultAccount) diff --git a/test/libweb3jsonrpc/webthreestubclient.h b/test/libweb3jsonrpc/webthreestubclient.h index fd71bfb5d..51d556eec 100644 --- a/test/libweb3jsonrpc/webthreestubclient.h +++ b/test/libweb3jsonrpc/webthreestubclient.h @@ -476,6 +476,36 @@ class WebThreeStubClient : public jsonrpc::Client else throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); } + std::string eth_signTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_signTransaction",p); + if (result.isString()) + return result.asString(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + Json::Value eth_inspectTransaction(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_inspectTransaction",p); + if (result.isObject()) + return result; + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } + bool eth_injectTransaction(const std::string& param1) throw (jsonrpc::JsonRpcException) + { + Json::Value p; + p.append(param1); + Json::Value result = this->CallMethod("eth_injectTransaction",p); + if (result.isBool()) + return result.asBool(); + else + throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); + } bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) { Json::Value p; From 8393328eebb1ae20a868b185b3c132fd55cd25ec Mon Sep 17 00:00:00 2001 From: arkpar Date: Tue, 28 Apr 2015 22:45:47 +0200 Subject: [PATCH 04/17] removed webthreestubclient.h --- test/webthreestubclient.h | 626 -------------------------------------- 1 file changed, 626 deletions(-) delete mode 100644 test/webthreestubclient.h diff --git a/test/webthreestubclient.h b/test/webthreestubclient.h deleted file mode 100644 index 51d556eec..000000000 --- a/test/webthreestubclient.h +++ /dev/null @@ -1,626 +0,0 @@ -/** - * This file is generated by jsonrpcstub, DO NOT CHANGE IT MANUALLY! - */ - -#ifndef JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ -#define JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ - -#include - -class WebThreeStubClient : public jsonrpc::Client -{ - public: - WebThreeStubClient(jsonrpc::IClientConnector &conn, jsonrpc::clientVersion_t type = jsonrpc::JSONRPC_CLIENT_V2) : jsonrpc::Client(conn, type) {} - - std::string web3_sha3(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("web3_sha3",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string web3_clientVersion() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("web3_clientVersion",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string net_version() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("net_version",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string net_peerCount() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("net_peerCount",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool net_listening() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("net_listening",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_protocolVersion() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_protocolVersion",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_hashrate() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_hashrate",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_coinbase() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_coinbase",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_mining() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_mining",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_gasPrice() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_gasPrice",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_accounts() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_accounts",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_blockNumber() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_blockNumber",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getBalance(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getBalance",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getStorageAt(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - p.append(param3); - Json::Value result = this->CallMethod("eth_getStorageAt",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getTransactionCount(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getTransactionCount",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getBlockTransactionCountByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getBlockTransactionCountByHash",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getBlockTransactionCountByNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getBlockTransactionCountByNumber",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getUncleCountByBlockHash(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getUncleCountByBlockHash",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getUncleCountByBlockNumber(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getUncleCountByBlockNumber",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_getCode(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getCode",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_sendTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_sendTransaction",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_call(const Json::Value& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_call",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_flush() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_flush",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getBlockByHash(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getBlockByHash",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getBlockByNumber(const std::string& param1, bool param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getBlockByNumber",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getTransactionByHash(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getTransactionByHash",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getTransactionByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getTransactionByBlockHashAndIndex",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getTransactionByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getTransactionByBlockNumberAndIndex",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getUncleByBlockHashAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getUncleByBlockHashAndIndex",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getUncleByBlockNumberAndIndex(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("eth_getUncleByBlockNumberAndIndex",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getCompilers() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_getCompilers",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_compileLLL(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_compileLLL",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_compileSerpent(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_compileSerpent",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_compileSolidity(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_compileSolidity",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_newFilter",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_newBlockFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_newBlockFilter",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_uninstallFilter",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getFilterChanges",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getFilterLogs(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getFilterLogs",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getLogs(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_getLogs",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_getWork() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("eth_getWork",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_submitWork(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - p.append(param3); - Json::Value result = this->CallMethod("eth_submitWork",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_register(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_register",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_unregister(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_unregister",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_fetchQueuedTransactions(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_fetchQueuedTransactions",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string eth_signTransaction(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_signTransaction",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value eth_inspectTransaction(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_inspectTransaction",p); - if (result.isObject()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool eth_injectTransaction(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("eth_injectTransaction",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool db_put(const std::string& param1, const std::string& param2, const std::string& param3) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - p.append(param3); - Json::Value result = this->CallMethod("db_put",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string db_get(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("db_get",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool shh_post(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_post",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string shh_newIdentity() throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p = Json::nullValue; - Json::Value result = this->CallMethod("shh_newIdentity",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool shh_hasIdentity(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_hasIdentity",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string shh_newGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("shh_newGroup",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string shh_addToGroup(const std::string& param1, const std::string& param2) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - p.append(param2); - Json::Value result = this->CallMethod("shh_addToGroup",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - std::string shh_newFilter(const Json::Value& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_newFilter",p); - if (result.isString()) - return result.asString(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - bool shh_uninstallFilter(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_uninstallFilter",p); - if (result.isBool()) - return result.asBool(); - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value shh_getFilterChanges(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_getFilterChanges",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } - Json::Value shh_getMessages(const std::string& param1) throw (jsonrpc::JsonRpcException) - { - Json::Value p; - p.append(param1); - Json::Value result = this->CallMethod("shh_getMessages",p); - if (result.isArray()) - return result; - else - throw jsonrpc::JsonRpcException(jsonrpc::Errors::ERROR_CLIENT_INVALID_RESPONSE, result.toStyledString()); - } -}; - -#endif //JSONRPC_CPP_STUB_WEBTHREESTUBCLIENT_H_ From 9524ca5e3199c2a069ff7e7b532450cb04dc3346 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 29 Apr 2015 15:52:56 +0200 Subject: [PATCH 05/17] Utility class to find a suitable AST node for a given location. --- libevmcore/SourceLocation.h | 25 +++++++++++++++++ libsolidity/ASTUtils.cpp | 48 +++++++++++++++++++++++++++++++++ libsolidity/ASTUtils.h | 54 +++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 libsolidity/ASTUtils.cpp create mode 100644 libsolidity/ASTUtils.h diff --git a/libevmcore/SourceLocation.h b/libevmcore/SourceLocation.h index c373e9cf3..abe291d0f 100644 --- a/libevmcore/SourceLocation.h +++ b/libevmcore/SourceLocation.h @@ -25,6 +25,7 @@ #include #include #include +#include namespace dev { @@ -45,6 +46,9 @@ struct SourceLocation bool operator==(SourceLocation const& _other) const { return start == _other.start && end == _other.end;} bool operator!=(SourceLocation const& _other) const { return !operator==(_other); } + inline bool operator<(SourceLocation const& _other) const; + inline bool contains(SourceLocation const& _other) const; + inline bool intersects(SourceLocation const& _other) const; bool isEmpty() const { return start == -1 && end == -1; } @@ -61,4 +65,25 @@ inline std::ostream& operator<<(std::ostream& _out, SourceLocation const& _locat return _out << *_location.sourceName << "[" << _location.start << "," << _location.end << ")"; } +bool SourceLocation::operator<(SourceLocation const& _other) const +{ + if (!!sourceName != !!_other.sourceName) + return int(!!sourceName) < int(!!_other.sourceName); + return make_tuple(*sourceName, start, end) < make_tuple(*_other.sourceName, _other.start, _other.end); +} + +bool SourceLocation::contains(SourceLocation const& _other) const +{ + if (isEmpty() || _other.isEmpty() || !sourceName || !_other.sourceName || *sourceName != *_other.sourceName) + return false; + return start <= _other.start && _other.end <= end; +} + +bool SourceLocation::intersects(SourceLocation const& _other) const +{ + if (isEmpty() || _other.isEmpty() || !sourceName || !_other.sourceName || *sourceName != *_other.sourceName) + return false; + return _other.start < end && start < _other.end; +} + } diff --git a/libsolidity/ASTUtils.cpp b/libsolidity/ASTUtils.cpp new file mode 100644 index 000000000..081d6b317 --- /dev/null +++ b/libsolidity/ASTUtils.cpp @@ -0,0 +1,48 @@ +/* + 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 . +*/ +/** + * @author Christian + * @date 2015 + * Utilities to work with the AST. + */ + +#include + +using namespace std; +using namespace dev; +using namespace dev::solidity; + + + +ASTNode const* LocationFinder::leastUpperBound() +{ + m_bestMatch = nullptr; + for (ASTNode const* rootNode: m_rootNodes) + rootNode->accept(*this); + + return m_bestMatch; +} + +bool LocationFinder::visitNode(const ASTNode& _node) +{ + if (_node.getLocation().contains(m_location)) + { + m_bestMatch = &_node; + return true; + } + return false; +} diff --git a/libsolidity/ASTUtils.h b/libsolidity/ASTUtils.h new file mode 100644 index 000000000..f2b90ea53 --- /dev/null +++ b/libsolidity/ASTUtils.h @@ -0,0 +1,54 @@ +/* + 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 . +*/ +/** + * @author Christian + * @date 2015 + * Utilities to work with the AST. + */ + +#pragma once + +#include +#include + +namespace dev +{ +namespace solidity +{ + +class LocationFinder: private ASTConstVisitor +{ +public: + LocationFinder(SourceLocation const& _location, std::vector _rootNodes): + m_rootNodes(_rootNodes), m_location(_location) + { + } + + /// @returns the "closest" (in the sense of most-leafward) AST node which is a descendant of + /// _node and whose source location contains _location. + ASTNode const* leastUpperBound(); + +private: + bool visitNode(ASTNode const& _node); + + std::vector m_rootNodes; + SourceLocation m_location; + ASTNode const* m_bestMatch = nullptr; +}; + +} +} From 6b4fd27dfdeac9e8be405776652781898ee3bd99 Mon Sep 17 00:00:00 2001 From: yann300 Date: Wed, 29 Apr 2015 17:10:46 +0200 Subject: [PATCH 06/17] add UrlHint Registration in NameReg --- alethzero/DappLoader.cpp | 18 +++++++------ alethzero/DappLoader.h | 4 ++- alethzero/MainWin.cpp | 4 +-- mix/qml/DeploymentDialog.qml | 19 +++----------- mix/qml/js/NetworkDeployment.js | 45 +++++++++++++++++++++------------ 5 files changed, 48 insertions(+), 42 deletions(-) diff --git a/alethzero/DappLoader.cpp b/alethzero/DappLoader.cpp index f179734a2..6ac1afbcb 100644 --- a/alethzero/DappLoader.cpp +++ b/alethzero/DappLoader.cpp @@ -39,13 +39,10 @@ using namespace dev; using namespace dev::eth; using namespace dev::crypto; -Address c_registrar = Address("6a16d3a392de03c67c1880acca6a9d650015c8ae"); -Address c_urlHint = Address("43c6d48ef55d10a786eb3e244824c820d5359b43"); - QString contentsOfQResource(std::string const& res); -DappLoader::DappLoader(QObject* _parent, WebThreeDirect* _web3): - QObject(_parent), m_web3(_web3) +DappLoader::DappLoader(QObject* _parent, WebThreeDirect* _web3, Address _nameReg): + QObject(_parent), m_web3(_web3), m_nameReg(_nameReg) { connect(&m_net, &QNetworkAccessManager::finished, this, &DappLoader::downloadComplete); } @@ -61,12 +58,11 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri) std::reverse(parts.begin(), parts.end()); parts.append(url.path().split('/', QString::SkipEmptyParts)); - Address address = c_registrar; + Address address = m_nameReg; Address lastAddress; int partIndex = 0; h256 contentHash; - while (address && partIndex < parts.length()) { lastAddress = address; @@ -85,7 +81,12 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri) ++partIndex; } - string32 contentUrl = abiOut(web3()->ethereum()->call(c_urlHint, abiIn("url(bytes32)", contentHash)).output); + string32 urlHintName = ZeroString32; + QByteArray utf8 = QString("UrlHint").toUtf8(); + std::copy(utf8.data(), utf8.data() + utf8.size(), urlHintName.data()); + + Address urlHint = abiOut
(web3()->ethereum()->call(m_nameReg, abiIn("addr(bytes32)", urlHintName)).output); + string32 contentUrl = abiOut(web3()->ethereum()->call(urlHint, abiIn("url(bytes32)", contentHash)).output); QString domain = domainParts.join('/'); parts.erase(parts.begin(), parts.begin() + partIndex); QString path = parts.join('/'); @@ -237,6 +238,7 @@ void DappLoader::loadDapp(QString const& _uri) DappLocation location = resolveAppUri(_uri); contentUri = location.contentUri; hash = location.contentHash; + uri = contentUri; } QNetworkRequest request(contentUri); m_uriHashes[uri] = hash; diff --git a/alethzero/DappLoader.h b/alethzero/DappLoader.h index deba62c68..f2d3ee5e5 100644 --- a/alethzero/DappLoader.h +++ b/alethzero/DappLoader.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace dev { @@ -69,7 +70,7 @@ class DappLoader: public QObject { Q_OBJECT public: - DappLoader(QObject* _parent, dev::WebThreeDirect* _web3); + DappLoader(QObject* _parent, dev::WebThreeDirect* _web3, dev::Address _nameReg); ///Load a new DApp. Resolves a name with a name reg contract. Asynchronous. dappReady is emitted once everything is read, dappError othervise ///@param _uri Eth name path void loadDapp(QString const& _uri); @@ -97,5 +98,6 @@ private: std::map m_uriHashes; std::set m_pageUrls; QByteArray m_web3Js; + dev::Address m_nameReg; }; diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 247e7fde3..923d46760 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -173,7 +173,7 @@ Main::Main(QWidget *parent) : ui->blockCount->setText(QString("PV%1.%2 D%3 %4-%5 v%6").arg(eth::c_protocolVersion).arg(eth::c_minorProtocolVersion).arg(c_databaseVersion).arg(QString::fromStdString(ProofOfWork::name())).arg(ProofOfWork::revision()).arg(dev::Version)); connect(ui->ourAccounts->model(), SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), SLOT(ourAccountsRowsMoved())); - + QSettings s("ethereum", "alethzero"); m_networkConfig = s.value("peers").toByteArray(); bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size()); @@ -196,7 +196,7 @@ Main::Main(QWidget *parent) : }); m_dappHost.reset(new DappHost(8081)); - m_dappLoader = new DappLoader(this, web3()); + m_dappLoader = new DappLoader(this, web3(), getNameReg()); connect(m_dappLoader, &DappLoader::dappReady, this, &Main::dappLoaded); connect(m_dappLoader, &DappLoader::pageReady, this, &Main::pageLoaded); // ui->webView->page()->settings()->setAttribute(QWebEngineSettings::DeveloperExtrasEnabled, true); diff --git a/mix/qml/DeploymentDialog.qml b/mix/qml/DeploymentDialog.qml index 9a4e18792..f8eeb7a88 100644 --- a/mix/qml/DeploymentDialog.qml +++ b/mix/qml/DeploymentDialog.qml @@ -19,7 +19,6 @@ Dialog { visible: false property alias applicationUrlEth: applicationUrlEth.text property alias applicationUrlHttp: applicationUrlHttp.text - property alias urlHintContract: urlHintAddr.text property alias localPackageUrl: localPackageUrl.text property string packageHash property string packageBase64 @@ -44,6 +43,7 @@ Dialog { id: 0 }]; + console.log(packageHash); TransactionHelper.rpcCall(requests, function(arg1, arg2) { modelAccounts.clear(); @@ -271,12 +271,15 @@ Dialog { DefaultLabel { text: qsTr("Root Registrar address:") + visible: false //still use it for now in dev env. } DefaultTextField { Layout.preferredWidth: 350 id: registrarAddr + text: "c6d9d2cd449a754c494264e1809c50e34d64562b" + visible: false } DefaultLabel @@ -449,20 +452,6 @@ Dialog { Layout.preferredWidth: 350 id: localPackageUrl readOnly: true - - } - - DefaultLabel - { - Layout.preferredWidth: 355 - text: qsTr("URL Hint contract address:") - } - - DefaultTextField - { - Layout.preferredWidth: 350 - id: urlHintAddr - enabled: rowRegister.isOkToRegister() } DefaultLabel diff --git a/mix/qml/js/NetworkDeployment.js b/mix/qml/js/NetworkDeployment.js index b4dca1106..fa85ddc54 100644 --- a/mix/qml/js/NetworkDeployment.js +++ b/mix/qml/js/NetworkDeployment.js @@ -224,11 +224,6 @@ function checkEthPath(dappUrl, callBack) { // the first owned registrar must have been created to follow the path. var str = clientModel.encodeStringParam(dappUrl[0]); - console.log("prarma = " + str + " " + deploymentDialog.eth); - - console.log("0x5a3a05bd" + str); - console.log(deploymentDialog.currentAccount); - console.log(deploymentDialog.eth); var requests = []; requests.push({ //subRegistrar() @@ -271,7 +266,7 @@ function checkRegistration(dappUrl, addr, callBack) //getOwner() jsonrpc: "2.0", method: "eth_call", - params: [ { "gas" : 2000, "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x02571be3" } ], + params: [ { "gas" : 2000, "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x02571be3" }, "pending" ], id: jsonRpcRequestId++ }); @@ -279,7 +274,7 @@ function checkRegistration(dappUrl, addr, callBack) //register() jsonrpc: "2.0", method: "eth_call", - params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x5a3a05bd" + str } ], + params: [ { "from": deploymentDialog.currentAccount, "to": '0x' + addr, "data": "0x5a3a05bd" + str }, "pending" ], id: jsonRpcRequestId++ }); @@ -363,11 +358,8 @@ function registerContentHash(registrar, callBack) var txt = qsTr("Finalizing Dapp registration ..."); deploymentStepChanged(txt); console.log(txt); - console.log(" 45 64 564 0 " + deploymentDialog.packageHash); var requests = []; var paramTitle = clientModel.encodeStringParam(projectModel.projectTitle); - console.log("ggg " + paramTitle); - console.log('registrar ' + registrar); requests.push({ //setContent() @@ -384,19 +376,40 @@ function registerContentHash(registrar, callBack) function registerToUrlHint() { deploymentStepChanged(qsTr("Registering application Resources (" + deploymentDialog.applicationUrlHttp) + ") ..."); + + urlHintAddress(function(urlHint){ + var requests = []; + var paramUrlHttp = clientModel.encodeStringParam(deploymentDialog.applicationUrlHttp); + + requests.push({ + //urlHint => suggestUrl + jsonrpc: "2.0", + method: "eth_sendTransaction", + params: [ { "to": '0x' + urlHint, "from": deploymentDialog.currentAccount, "gas": "0xfffff", "data": "0x584e86ad" + deploymentDialog.packageHash + paramUrlHttp } ], + id: jsonRpcRequestId++ + }); + + rpcCall(requests, function (httpRequest, response) { + deploymentComplete(); + }); + }); +} + +function urlHintAddress(callBack) +{ var requests = []; - var paramUrlHttp = clientModel.encodeStringParam(deploymentDialog.applicationUrlHttp); - console.log("package hash " + deploymentDialog.packageHash); + var urlHint = clientModel.encodeStringParam("UrlHint"); requests.push({ - //urlHint => suggestUrl + //registrar: get UrlHint addr jsonrpc: "2.0", - method: "eth_sendTransaction", - params: [ { "to": '0x' + deploymentDialog.urlHintContract, "from": deploymentDialog.currentAccount, "gas": "0xfffff", "data": "0x584e86ad" + deploymentDialog.packageHash + paramUrlHttp } ], + method: "eth_call", + params: [ { "to": '0x' + deploymentDialog.eth, "from": deploymentDialog.currentAccount, "gas": "0xfffff", "data": "0x3b3b57de" + urlHint }, "pending" ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { - deploymentComplete(); + var res = JSON.parse(response); + callBack(normalizeAddress(res[0].result)); }); } From 8ca0d6098dbb5c87f5a9bccbed695686c6fb86c4 Mon Sep 17 00:00:00 2001 From: chriseth Date: Wed, 29 Apr 2015 17:20:27 +0200 Subject: [PATCH 07/17] Fixed source location comparison operator. --- libevmcore/SourceLocation.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libevmcore/SourceLocation.h b/libevmcore/SourceLocation.h index abe291d0f..35e3c0318 100644 --- a/libevmcore/SourceLocation.h +++ b/libevmcore/SourceLocation.h @@ -67,7 +67,7 @@ inline std::ostream& operator<<(std::ostream& _out, SourceLocation const& _locat bool SourceLocation::operator<(SourceLocation const& _other) const { - if (!!sourceName != !!_other.sourceName) + if (!sourceName || !_other.sourceName) return int(!!sourceName) < int(!!_other.sourceName); return make_tuple(*sourceName, start, end) < make_tuple(*_other.sourceName, _other.start, _other.end); } From b51f01ed100f97076584c6900f73deb5dc5f6bbc Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 29 Apr 2015 19:17:07 +0200 Subject: [PATCH 08/17] resources scripts --- CMakeLists.txt | 3 +++ cmake/EthUtils.cmake | 28 ++++++++++++++++++++++++++ cmake/scripts/resource.cpp.in | 26 ++++++++++++++++++++++++ cmake/scripts/resources.cmake | 37 +++++++++++++++++++++++++++++++++++ cmake/scripts/test.cmake | 6 ++++++ 5 files changed, 100 insertions(+) create mode 100644 cmake/scripts/resource.cpp.in create mode 100644 cmake/scripts/resources.cmake create mode 100644 cmake/scripts/test.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ff8732156..a770e9704 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -383,6 +383,9 @@ if (GUI) endif() +set(ETH_RESOURCES "LICENSE" "README.md") +eth_create_resources(ETH_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/here.h") + #unset(TARGET_PLATFORM CACHE) if (WIN32) diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake index 69690156a..5d271f341 100644 --- a/cmake/EthUtils.cmake +++ b/cmake/EthUtils.cmake @@ -62,3 +62,31 @@ macro(eth_add_test NAME) endmacro() +# Based on +# http://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake +# Creates C resources file from files +function(eth_create_resources bins output) + set(tmp_output "${output}.tmp") + # Create empty output file + file(WRITE ${tmp_output} "") + # Collect input files +# file(GLOB bins ${dir}/*) + # Iterate through input files + foreach(bin ${${bins}}) + # Get short filename + string(REGEX MATCH "([^/]+)$" filename ${bin}) + # Replace filename spaces & extension separator for C compatibility + string(REGEX REPLACE "\\.| " "_" filename ${filename}) + # Add eth prefix (qt does the same thing) + set(filename "eth_${filename}") + # full name + file(GLOB the_name ${bin}) + # Read hex data from file + file(READ ${bin} filedata HEX) + # Convert hex data for C compatibility + string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata}) + # Append data to output file + file(APPEND ${tmp_output} "static const unsigned char ${filename}[] = {\n // ${the_name}\n ${filedata}};\nstatic const unsigned ${filename}_size = sizeof(${filename});\n") + endforeach() + replace_if_different("${tmp_output}" "${output}") +endfunction() diff --git a/cmake/scripts/resource.cpp.in b/cmake/scripts/resource.cpp.in new file mode 100644 index 000000000..369f7b56f --- /dev/null +++ b/cmake/scripts/resource.cpp.in @@ -0,0 +1,26 @@ + +#include +#include +#include +#include + +using namespace std; + +${ETH_RESULT_DATA} + +static unordered_map eth_resources; +static unordered_map eth_sizes; + +void initResources() +{ + ${ETH_RESULT_INIT} + //eth_resources["LICENSE"] = (char const*)eth_LICENSE; + //eth_sizes["LICENSE"] = sizeof(eth_LICENSE); +} + +string loadResource(string _name) +{ + ostringstream bistream; + bistream.write(eth_resources[_name], eth_sizes[_name]); + return bistream.str(); +} diff --git a/cmake/scripts/resources.cmake b/cmake/scripts/resources.cmake new file mode 100644 index 000000000..2c92103ff --- /dev/null +++ b/cmake/scripts/resources.cmake @@ -0,0 +1,37 @@ + +# cmake -DETH_RES_FILE=... -DETH_DST_NAME=... -P scripts/resources.cmake +# cmake -DETH_RES_FILE=test.cmake -DETH_DST_NAME=dst -P resources.cmake + +# should define ETH_RESOURCES +include(${ETH_RES_FILE}) + +set(ETH_RESULT_DATA) +set(ETH_RESULT_INIT) + +# resource is a name visible for cpp application +foreach(resource ${ETH_RESOURCES}) + + # filename is the name of file which will be used in app + set(filename ${${resource}}) + + # filedata is a file content + file(READ ${filename} filedata HEX) + + # Convert hex data for C compatibility + string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata}) + + # append static variables to result variable + list(APPEND ${ETH_RESULT_DATA} "static const unsigned char eth_${resource}[] = {\n // ${filename}\n ${filedata}\n};\n") + + # append init resources + list(APPEND ${ETH_RESULT_INIT} " eth_resources[\"${resource}\"] = (char const*)eth_${resource};\n") + list(APPEND ${ETH_RESULT_INIT} " eth_sizes[\"${resource}\"] = sizeof(eth_${resource});\n") + +endforeach(resource) + +configure_file("resource.cpp.in" "${ETH_DST_NAME}.cpp.tmp") + +include("../EthUtils.cmake") +replace_if_different("${ETH_DST_NAME}.cpp.tmp" "${ETH_DST_NAME}.cpp") +replace_if_different("resource.h" "${ETH_DST_NAME}.h") + diff --git a/cmake/scripts/test.cmake b/cmake/scripts/test.cmake new file mode 100644 index 000000000..883ed324e --- /dev/null +++ b/cmake/scripts/test.cmake @@ -0,0 +1,6 @@ + +set(copydlls "copydlls.cmake") +set(conf "configure.cmake") + +set(ETH_RESOURCES "copyddls" "conf") + From a7996f4de717da9a82fb740e8d7abbb64d90c1d7 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 29 Apr 2015 22:38:58 +0200 Subject: [PATCH 09/17] finished resource scripts --- CMakeLists.txt | 3 --- cmake/EthUtils.cmake | 30 +++------------------- cmake/scripts/resource.cpp.in | 21 +++++++--------- cmake/scripts/resource.h.in | 26 +++++++++++++++++++ cmake/scripts/resources.cmake | 47 ++++++++++++++++++++++++++--------- cmake/scripts/test.cmake | 6 ----- 6 files changed, 74 insertions(+), 59 deletions(-) create mode 100644 cmake/scripts/resource.h.in delete mode 100644 cmake/scripts/test.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a770e9704..ff8732156 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -383,9 +383,6 @@ if (GUI) endif() -set(ETH_RESOURCES "LICENSE" "README.md") -eth_create_resources(ETH_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/here.h") - #unset(TARGET_PLATFORM CACHE) if (WIN32) diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake index 5d271f341..147ce0737 100644 --- a/cmake/EthUtils.cmake +++ b/cmake/EthUtils.cmake @@ -62,31 +62,9 @@ macro(eth_add_test NAME) endmacro() -# Based on -# http://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake # Creates C resources file from files -function(eth_create_resources bins output) - set(tmp_output "${output}.tmp") - # Create empty output file - file(WRITE ${tmp_output} "") - # Collect input files -# file(GLOB bins ${dir}/*) - # Iterate through input files - foreach(bin ${${bins}}) - # Get short filename - string(REGEX MATCH "([^/]+)$" filename ${bin}) - # Replace filename spaces & extension separator for C compatibility - string(REGEX REPLACE "\\.| " "_" filename ${filename}) - # Add eth prefix (qt does the same thing) - set(filename "eth_${filename}") - # full name - file(GLOB the_name ${bin}) - # Read hex data from file - file(READ ${bin} filedata HEX) - # Convert hex data for C compatibility - string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata}) - # Append data to output file - file(APPEND ${tmp_output} "static const unsigned char ${filename}[] = {\n // ${the_name}\n ${filedata}};\nstatic const unsigned ${filename}_size = sizeof(${filename});\n") - endforeach() - replace_if_different("${tmp_output}" "${output}") +function(eth_add_resources TARGET RESOURCE_FILE) + add_custom_command(TARGET ${TARGET} PRE_BUILD + COMMAND ${CMAKE_COMMAND} -DETH_RES_FILE="${RESOURCE_FILE}" -P "${ETH_SCRIPTS_DIR}/resources.cmake" + ) endfunction() diff --git a/cmake/scripts/resource.cpp.in b/cmake/scripts/resource.cpp.in index 369f7b56f..b73a8df1a 100644 --- a/cmake/scripts/resource.cpp.in +++ b/cmake/scripts/resource.cpp.in @@ -1,26 +1,23 @@ +// this file is autogenerated, do not modify!!! -#include #include #include -#include +#include "${ETH_RESOURCE_NAME}.h" using namespace std; +using namespace dev; +using namespace dev::eth; -${ETH_RESULT_DATA} - -static unordered_map eth_resources; -static unordered_map eth_sizes; - -void initResources() +${ETH_RESOURCE_NAME}::${ETH_RESOURCE_NAME}() { - ${ETH_RESULT_INIT} - //eth_resources["LICENSE"] = (char const*)eth_LICENSE; - //eth_sizes["LICENSE"] = sizeof(eth_LICENSE); +${ETH_RESULT_DATA} +${ETH_RESULT_INIT} } -string loadResource(string _name) +string ${ETH_RESOURCE_NAME}::loadResourceAsString(string _name) { ostringstream bistream; bistream.write(eth_resources[_name], eth_sizes[_name]); return bistream.str(); } + diff --git a/cmake/scripts/resource.h.in b/cmake/scripts/resource.h.in new file mode 100644 index 000000000..b27c3c882 --- /dev/null +++ b/cmake/scripts/resource.h.in @@ -0,0 +1,26 @@ +// this file is autogenerated, do not modify!!! +#pragma once + +#include +#include + +namespace dev +{ +namespace eth +{ + +class ${ETH_RESOURCE_NAME} +{ +public: + ${ETH_RESOURCE_NAME}(); + std::string loadResourceAsString(std::string _name): + +private: + std::unordered_map m_resources; + std::unordered_map m_sizes; + +}; + +} +} + diff --git a/cmake/scripts/resources.cmake b/cmake/scripts/resources.cmake index 2c92103ff..3e47a1bfb 100644 --- a/cmake/scripts/resources.cmake +++ b/cmake/scripts/resources.cmake @@ -1,37 +1,60 @@ - -# cmake -DETH_RES_FILE=... -DETH_DST_NAME=... -P scripts/resources.cmake -# cmake -DETH_RES_FILE=test.cmake -DETH_DST_NAME=dst -P resources.cmake +# based on: http://stackoverflow.com/questions/11813271/embed-resources-eg-shader-code-images-into-executable-library-with-cmake +# +# example: +# cmake -DETH_RES_FILE=test.cmake -P resources.cmake +# +# where test.cmake is: +# +# # BEGIN OF cmake.test +# +# set(copydlls "copydlls.cmake") +# set(conf "configure.cmake") +# +# # this three properties must be set! +# +# set(ETH_RESOURCE_NAME "EthResources") +# set(ETH_RESOURCE_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}") +# set(ETH_RESOURCES "copydlls" "conf") +# +# # END of cmake.test +# # should define ETH_RESOURCES include(${ETH_RES_FILE}) -set(ETH_RESULT_DATA) -set(ETH_RESULT_INIT) +set(ETH_RESULT_DATA "") +set(ETH_RESULT_INIT "") # resource is a name visible for cpp application foreach(resource ${ETH_RESOURCES}) - + # filename is the name of file which will be used in app set(filename ${${resource}}) # filedata is a file content file(READ ${filename} filedata HEX) + # read full name of the file + file(GLOB filename ${filename}) + # Convert hex data for C compatibility string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata}) # append static variables to result variable - list(APPEND ${ETH_RESULT_DATA} "static const unsigned char eth_${resource}[] = {\n // ${filename}\n ${filedata}\n};\n") + set(ETH_RESULT_DATA "${ETH_RESULT_DATA} static const unsigned char eth_${resource}[] = {\n // ${filename}\n ${filedata}\n};\n") # append init resources - list(APPEND ${ETH_RESULT_INIT} " eth_resources[\"${resource}\"] = (char const*)eth_${resource};\n") - list(APPEND ${ETH_RESULT_INIT} " eth_sizes[\"${resource}\"] = sizeof(eth_${resource});\n") + set(ETH_RESULT_INIT "${ETH_RESULT_INIT} eth_resources[\"${resource}\"] = (char const*)eth_${resource};\n") + set(ETH_RESULT_INIT "${ETH_RESULT_INIT} eth_sizes[\"${resource}\"] = sizeof(eth_${resource});\n") endforeach(resource) -configure_file("resource.cpp.in" "${ETH_DST_NAME}.cpp.tmp") +set(ETH_DST_NAME "${ETH_RESOURCE_LOCATION}/${ETH_RESOURCE_NAME}") + +configure_file("${CMAKE_CURRENT_LIST_DIR}/resource.cpp.in" "${ETH_DST_NAME}.cpp.tmp") +configure_file("${CMAKE_CURRENT_LIST_DIR}/resource.h.in" "${ETH_DST_NAME}.h.tmp") -include("../EthUtils.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/../EthUtils.cmake") replace_if_different("${ETH_DST_NAME}.cpp.tmp" "${ETH_DST_NAME}.cpp") -replace_if_different("resource.h" "${ETH_DST_NAME}.h") +replace_if_different("${ETH_DST_NAME}.h.tmp" "${ETH_DST_NAME}.h") diff --git a/cmake/scripts/test.cmake b/cmake/scripts/test.cmake deleted file mode 100644 index 883ed324e..000000000 --- a/cmake/scripts/test.cmake +++ /dev/null @@ -1,6 +0,0 @@ - -set(copydlls "copydlls.cmake") -set(conf "configure.cmake") - -set(ETH_RESOURCES "copyddls" "conf") - From 6da6f4ee53e884fe210ce8804c772c98971db324 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 29 Apr 2015 23:09:40 +0200 Subject: [PATCH 10/17] fixed indention --- cmake/scripts/resources.cmake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/scripts/resources.cmake b/cmake/scripts/resources.cmake index 3e47a1bfb..d69d99e96 100644 --- a/cmake/scripts/resources.cmake +++ b/cmake/scripts/resources.cmake @@ -34,8 +34,8 @@ foreach(resource ${ETH_RESOURCES}) # filedata is a file content file(READ ${filename} filedata HEX) - # read full name of the file - file(GLOB filename ${filename}) + # read full name of the file + file(GLOB filename ${filename}) # Convert hex data for C compatibility string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata}) From 6315351b7af0377fd56c1022ff4991779838111e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 30 Apr 2015 00:57:58 +0200 Subject: [PATCH 11/17] fixes for eth_add_resources --- cmake/EthUtils.cmake | 6 +++++- cmake/scripts/resource.cpp.in | 23 ---------------------- cmake/scripts/resource.h.in | 26 ------------------------- cmake/scripts/resource.hpp.in | 36 +++++++++++++++++++++++++++++++++++ cmake/scripts/resources.cmake | 10 ++++------ 5 files changed, 45 insertions(+), 56 deletions(-) delete mode 100644 cmake/scripts/resource.cpp.in delete mode 100644 cmake/scripts/resource.h.in create mode 100644 cmake/scripts/resource.hpp.in diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake index 147ce0737..d5da866ea 100644 --- a/cmake/EthUtils.cmake +++ b/cmake/EthUtils.cmake @@ -64,7 +64,11 @@ endmacro() # Creates C resources file from files function(eth_add_resources TARGET RESOURCE_FILE) - add_custom_command(TARGET ${TARGET} PRE_BUILD + + add_custom_target("${TARGET}.resources" COMMAND ${CMAKE_COMMAND} -DETH_RES_FILE="${RESOURCE_FILE}" -P "${ETH_SCRIPTS_DIR}/resources.cmake" ) + + add_dependencies(${TARGET} "${TARGET}.resources") + endfunction() diff --git a/cmake/scripts/resource.cpp.in b/cmake/scripts/resource.cpp.in deleted file mode 100644 index b73a8df1a..000000000 --- a/cmake/scripts/resource.cpp.in +++ /dev/null @@ -1,23 +0,0 @@ -// this file is autogenerated, do not modify!!! - -#include -#include -#include "${ETH_RESOURCE_NAME}.h" - -using namespace std; -using namespace dev; -using namespace dev::eth; - -${ETH_RESOURCE_NAME}::${ETH_RESOURCE_NAME}() -{ -${ETH_RESULT_DATA} -${ETH_RESULT_INIT} -} - -string ${ETH_RESOURCE_NAME}::loadResourceAsString(string _name) -{ - ostringstream bistream; - bistream.write(eth_resources[_name], eth_sizes[_name]); - return bistream.str(); -} - diff --git a/cmake/scripts/resource.h.in b/cmake/scripts/resource.h.in deleted file mode 100644 index b27c3c882..000000000 --- a/cmake/scripts/resource.h.in +++ /dev/null @@ -1,26 +0,0 @@ -// this file is autogenerated, do not modify!!! -#pragma once - -#include -#include - -namespace dev -{ -namespace eth -{ - -class ${ETH_RESOURCE_NAME} -{ -public: - ${ETH_RESOURCE_NAME}(); - std::string loadResourceAsString(std::string _name): - -private: - std::unordered_map m_resources; - std::unordered_map m_sizes; - -}; - -} -} - diff --git a/cmake/scripts/resource.hpp.in b/cmake/scripts/resource.hpp.in new file mode 100644 index 000000000..a8bbca377 --- /dev/null +++ b/cmake/scripts/resource.hpp.in @@ -0,0 +1,36 @@ +// this file is autogenerated, do not modify!!! +#pragma once + +#include +#include +#include + +namespace dev +{ +namespace eth +{ + +class ${ETH_RESOURCE_NAME} +{ +public: + ${ETH_RESOURCE_NAME}() + { +${ETH_RESULT_DATA} +${ETH_RESULT_INIT} + } + + std::string loadResourceAsString(std::string _name) + { + std::ostringstream bistream; + bistream.write(m_resources[_name], m_sizes[_name]); + return bistream.str(); + } + +private: + std::map m_resources; + std::map m_sizes; +}; + +} +} + diff --git a/cmake/scripts/resources.cmake b/cmake/scripts/resources.cmake index d69d99e96..93326a257 100644 --- a/cmake/scripts/resources.cmake +++ b/cmake/scripts/resources.cmake @@ -44,17 +44,15 @@ foreach(resource ${ETH_RESOURCES}) set(ETH_RESULT_DATA "${ETH_RESULT_DATA} static const unsigned char eth_${resource}[] = {\n // ${filename}\n ${filedata}\n};\n") # append init resources - set(ETH_RESULT_INIT "${ETH_RESULT_INIT} eth_resources[\"${resource}\"] = (char const*)eth_${resource};\n") - set(ETH_RESULT_INIT "${ETH_RESULT_INIT} eth_sizes[\"${resource}\"] = sizeof(eth_${resource});\n") + set(ETH_RESULT_INIT "${ETH_RESULT_INIT} m_resources[\"${resource}\"] = (char const*)eth_${resource};\n") + set(ETH_RESULT_INIT "${ETH_RESULT_INIT} m_sizes[\"${resource}\"] = sizeof(eth_${resource});\n") endforeach(resource) set(ETH_DST_NAME "${ETH_RESOURCE_LOCATION}/${ETH_RESOURCE_NAME}") -configure_file("${CMAKE_CURRENT_LIST_DIR}/resource.cpp.in" "${ETH_DST_NAME}.cpp.tmp") -configure_file("${CMAKE_CURRENT_LIST_DIR}/resource.h.in" "${ETH_DST_NAME}.h.tmp") +configure_file("${CMAKE_CURRENT_LIST_DIR}/resource.hpp.in" "${ETH_DST_NAME}.hpp.tmp") include("${CMAKE_CURRENT_LIST_DIR}/../EthUtils.cmake") -replace_if_different("${ETH_DST_NAME}.cpp.tmp" "${ETH_DST_NAME}.cpp") -replace_if_different("${ETH_DST_NAME}.h.tmp" "${ETH_DST_NAME}.h") +replace_if_different("${ETH_DST_NAME}.hpp.tmp" "${ETH_DST_NAME}.hpp") From 0cbdda18d18f59fc05c3b2e84097fcf223da8de5 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 30 Apr 2015 10:43:30 +0200 Subject: [PATCH 12/17] simplified loading string from eth resources --- cmake/scripts/resource.hpp.in | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/cmake/scripts/resource.hpp.in b/cmake/scripts/resource.hpp.in index a8bbca377..6a9740616 100644 --- a/cmake/scripts/resource.hpp.in +++ b/cmake/scripts/resource.hpp.in @@ -2,7 +2,6 @@ #pragma once #include -#include #include namespace dev @@ -19,12 +18,7 @@ ${ETH_RESULT_DATA} ${ETH_RESULT_INIT} } - std::string loadResourceAsString(std::string _name) - { - std::ostringstream bistream; - bistream.write(m_resources[_name], m_sizes[_name]); - return bistream.str(); - } + std::string loadResourceAsString(std::string _name) { return std::string(m_resources[_name], m_sizes[_name]); } private: std::map m_resources; From d4373dc185460790e280a35ff3ebe23a13816266 Mon Sep 17 00:00:00 2001 From: arkpar Date: Thu, 30 Apr 2015 12:06:56 +0200 Subject: [PATCH 13/17] deployment fixed to work with GlobalRegistrar --- alethzero/DappLoader.cpp | 2 +- mix/qml/js/NetworkDeployment.js | 28 +++++++++++++++++++++++++--- mix/qml/js/TransactionHelper.js | 4 ++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/alethzero/DappLoader.cpp b/alethzero/DappLoader.cpp index 6ac1afbcb..7c754f8f5 100644 --- a/alethzero/DappLoader.cpp +++ b/alethzero/DappLoader.cpp @@ -82,7 +82,7 @@ DappLocation DappLoader::resolveAppUri(QString const& _uri) } string32 urlHintName = ZeroString32; - QByteArray utf8 = QString("UrlHint").toUtf8(); + QByteArray utf8 = QString("urlhint").toUtf8(); std::copy(utf8.data(), utf8.data() + utf8.size(), urlHintName.data()); Address urlHint = abiOut
(web3()->ethereum()->call(m_nameReg, abiIn("addr(bytes32)", urlHintName)).output); diff --git a/mix/qml/js/NetworkDeployment.js b/mix/qml/js/NetworkDeployment.js index fa85ddc54..9bbed2415 100644 --- a/mix/qml/js/NetworkDeployment.js +++ b/mix/qml/js/NetworkDeployment.js @@ -219,7 +219,9 @@ function finalizeDeployment(deploymentId, addresses) { function checkEthPath(dappUrl, callBack) { if (dappUrl.length === 1) - registerContentHash(deploymentDialog.eth, callBack); // we directly create a dapp under the root registrar. + reserve(deploymentDialog.eth, function() { + registerContentHash(deploymentDialog.eth, callBack); // we directly create a dapp under the root registrar. + }); else { // the first owned registrar must have been created to follow the path. @@ -310,7 +312,7 @@ function checkRegistration(dappUrl, addr, callBack) requests.push({ jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.currentAccount, "gas": 20000, "code": "0x600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317815561058990819061003990396000f3007c010000000000000000000000000000000000000000000000000000000060003504630198489281146100a757806302571be3146100d957806321f8a721146100e35780632dff6941146100ed5780633b3b57de1461010d5780635a3a05bd1461013d5780635fd4b08a1461017057806389a69c0e1461017c578063b5c645bd146101b0578063be99a9801461022c578063c3d014d614610264578063d93e75731461029857005b73ffffffffffffffffffffffffffffffffffffffff600435166000908152600160205260409020548060005260206000f35b6000808052602081f35b6000808052602081f35b600435600090815260026020819052604090912001548060005260206000f35b600435600090815260026020908152604082205473ffffffffffffffffffffffffffffffffffffffff1680835291f35b600435600090815260026020908152604082206001015473ffffffffffffffffffffffffffffffffffffffff1680835291f35b60008060005260206000f35b6000546102c89060043590602435903373ffffffffffffffffffffffffffffffffffffffff908116911614610451576104b1565b600435600090815260026020819052604090912080546001820154919092015473ffffffffffffffffffffffffffffffffffffffff9283169291909116908273ffffffffffffffffffffffffffffffffffffffff166000528173ffffffffffffffffffffffffffffffffffffffff166020528060405260606000f35b6000546102ce906004359060243590604435903373ffffffffffffffffffffffffffffffffffffffff9081169116146104b557610584565b6000546102d49060043590602435903373ffffffffffffffffffffffffffffffffffffffff9081169116146102e05761031d565b6000546102da90600435903373ffffffffffffffffffffffffffffffffffffffff9081169116146103215761044e565b60006000f35b60006000f35b60006000f35b60006000f35b600082815260026020819052604080832090910183905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b60008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff1683526001909152902054811461035e576103de565b6000818152600260205260408082205473ffffffffffffffffffffffffffffffffffffffff169183917ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85459190a360008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091528120555b600081815260026020819052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168255600182018054909116905590910182905582917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b50565b60008281526002602052604080822060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b600083815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016831790558061051c57827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc60006040a2610583565b73ffffffffffffffffffffffffffffffffffffffff8216837ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a854560006040a373ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090208390555b5b50505056" } ], + params: [ { "from": deploymentDialog.currentAccount, "gas": 20000, "code": "0x600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000163317815561058990819061003990396000f3007c010000000000000000000000000000000000000000000000000000000060003504630198489281146100a757806302571be3146100d957806321f8a721146100e35780632dff6941146100ed5780633b3b57de1461010d5780635a3a05bd1461013d5780635fd4b08a1461017057806389a69c0e1461017c578063b5c645bd146101b0578063be99a9801461022c578063c3d014d614610264578063d93e75731461029857005b73ffffffffffffffffffffffffffffffffffffffff600435166000908152600160205260409020548060005260206000f35b6000808052602081f35b6000808052602081f35b600435600090815260026020819052604090912001548060005260206000f35b600435600090815260026020908152604082205473ffffffffffffffffffffffffffffffffffffffff1680835291f35b600435600090815260026020908152604082206001015473ffffffffffffffffffffffffffffffffffffffff1680835291f35b60008060005260206000f35b6000546102c89060043590602435903373ffffffffffffffffffffffffffffffffffffffff90811691161461052557610585565b600435600090815260026020819052604090912080546001820154919092015473ffffffffffffffffffffffffffffffffffffffff9283169291909116908273ffffffffffffffffffffffffffffffffffffffff166000528173ffffffffffffffffffffffffffffffffffffffff166020528060405260606000f35b6000546102ce906004359060243590604435903373ffffffffffffffffffffffffffffffffffffffff9081169116146102e0576103af565b6000546102d49060043590602435903373ffffffffffffffffffffffffffffffffffffffff9081169116146103b4576103f1565b6000546102da90600435903373ffffffffffffffffffffffffffffffffffffffff9081169116146103f557610522565b60006000f35b60006000f35b60006000f35b60006000f35b600083815260026020526040902080547fffffffffffffffffffffffff000000000000000000000000000000000000000016831790558061034757827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc60006040a26103ae565b73ffffffffffffffffffffffffffffffffffffffff8216837ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a854560006040a373ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090208390555b5b505050565b600082815260026020819052604080832090910183905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b60008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091529020548114610432576104b2565b6000818152600260205260408082205473ffffffffffffffffffffffffffffffffffffffff169183917ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85459190a360008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091528120555b600081815260026020819052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168255600182018054909116905590910182905582917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b50565b60008281526002602052604080822060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b505056" } ], id: jsonRpcRequestId++ }); @@ -353,6 +355,26 @@ function trCountIncrementTimeOut() deploymentError(error); } +function reserve(registrar, callBack) +{ + var txt = qsTr("Making reservation in the root registrar..."); + deploymentStepChanged(txt); + console.log(txt); + var requests = []; + var paramTitle = clientModel.encodeStringParam(projectModel.projectTitle); + requests.push({ + //reserve() + jsonrpc: "2.0", + method: "eth_sendTransaction", + params: [ { "from": deploymentDialog.currentAccount, "gas": "0xfffff", "to": '0x' + registrar, "data": "0x432ced04" + paramTitle } ], + id: jsonRpcRequestId++ + }); + rpcCall(requests, function (httpRequest, response) { + callBack(); + }); +} + + function registerContentHash(registrar, callBack) { var txt = qsTr("Finalizing Dapp registration ..."); @@ -398,7 +420,7 @@ function registerToUrlHint() function urlHintAddress(callBack) { var requests = []; - var urlHint = clientModel.encodeStringParam("UrlHint"); + var urlHint = clientModel.encodeStringParam("urlhint"); requests.push({ //registrar: get UrlHint addr jsonrpc: "2.0", diff --git a/mix/qml/js/TransactionHelper.js b/mix/qml/js/TransactionHelper.js index f0b4991fc..be057917c 100644 --- a/mix/qml/js/TransactionHelper.js +++ b/mix/qml/js/TransactionHelper.js @@ -17,6 +17,7 @@ function rpcCall(requests, callBack) { var jsonRpcUrl = "http://localhost:8080"; var rpcRequest = JSON.stringify(requests); + console.log(rpcRequest); var httpRequest = new XMLHttpRequest(); httpRequest.open("POST", jsonRpcUrl, true); httpRequest.setRequestHeader("Content-type", "application/json"); @@ -31,7 +32,10 @@ function rpcCall(requests, callBack) deploymentError(errorText); } else + { + console.log(httpRequest.responseText); callBack(httpRequest.status, httpRequest.responseText) + } } } httpRequest.send(rpcRequest); From 2a9e2f663e46cb521f12abd981e505cfae48ecd0 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 30 Apr 2015 12:40:02 +0200 Subject: [PATCH 14/17] improved eth_add_resources --- cmake/EthUtils.cmake | 19 ++++++++++++++----- cmake/scripts/resources.cmake | 1 - 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake index d5da866ea..85d8c0dc4 100644 --- a/cmake/EthUtils.cmake +++ b/cmake/EthUtils.cmake @@ -63,12 +63,21 @@ macro(eth_add_test NAME) endmacro() # Creates C resources file from files -function(eth_add_resources TARGET RESOURCE_FILE) +function(eth_add_resources RESOURCE_FILE OUT_FILE) + include("${RESOURCE_FILE}") + set(OUTPUT "${ETH_RESOURCE_LOCATION}/${ETH_RESOURCE_NAME}.hpp") + set(${OUT_FILE} "${OUTPUT}" PARENT_SCOPE) - add_custom_target("${TARGET}.resources" - COMMAND ${CMAKE_COMMAND} -DETH_RES_FILE="${RESOURCE_FILE}" -P "${ETH_SCRIPTS_DIR}/resources.cmake" - ) + set(filenames "${RESOURCE_FILE}") + list(APPEND filenames "${ETH_SCRIPTS_DIR}/resources.cmake") + foreach(resource ${ETH_RESOURCES}) + list(APPEND filenames "${${resource}}") + endforeach(resource) - add_dependencies(${TARGET} "${TARGET}.resources") + message(STATUS "filenames; ${filenames}") + add_custom_command(OUTPUT ${OUTPUT} + COMMAND ${CMAKE_COMMAND} -DETH_RES_FILE="${RESOURCE_FILE}" -P "${ETH_SCRIPTS_DIR}/resources.cmake" + DEPENDS ${filenames} + ) endfunction() diff --git a/cmake/scripts/resources.cmake b/cmake/scripts/resources.cmake index 93326a257..b0cadbf6d 100644 --- a/cmake/scripts/resources.cmake +++ b/cmake/scripts/resources.cmake @@ -55,4 +55,3 @@ configure_file("${CMAKE_CURRENT_LIST_DIR}/resource.hpp.in" "${ETH_DST_NAME}.hpp. include("${CMAKE_CURRENT_LIST_DIR}/../EthUtils.cmake") replace_if_different("${ETH_DST_NAME}.hpp.tmp" "${ETH_DST_NAME}.hpp") - From 9dfabc79665e9420c297823daaa2bb5ee2055a5e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Thu, 30 Apr 2015 12:47:14 +0200 Subject: [PATCH 15/17] removed redundant log in cmake utils --- cmake/EthUtils.cmake | 2 -- 1 file changed, 2 deletions(-) diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake index 85d8c0dc4..a426b1218 100644 --- a/cmake/EthUtils.cmake +++ b/cmake/EthUtils.cmake @@ -74,8 +74,6 @@ function(eth_add_resources RESOURCE_FILE OUT_FILE) list(APPEND filenames "${${resource}}") endforeach(resource) - message(STATUS "filenames; ${filenames}") - add_custom_command(OUTPUT ${OUTPUT} COMMAND ${CMAKE_COMMAND} -DETH_RES_FILE="${RESOURCE_FILE}" -P "${ETH_SCRIPTS_DIR}/resources.cmake" DEPENDS ${filenames} From c4fb35d4190d6d1e996cb91869ad8793f559152c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 30 Apr 2015 14:06:44 +0100 Subject: [PATCH 16/17] Fix for #1766 --- libethereum/Client.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index cb51bcb87..bab8f9555 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -646,7 +646,7 @@ void Client::tick() m_bq.tick(m_bc); m_lastTick = chrono::system_clock::now(); if (m_report.ticks == 15) - cnote << activityReport(); + clog(ClientTrace) << activityReport(); } } From fd5ea37e5569b531ef6678b035e0a40b3c0e6c63 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 30 Apr 2015 14:07:29 +0100 Subject: [PATCH 17/17] Transaction nonce now "sorted". Fixes #1615 --- libdevcore/Common.h | 2 + libethcore/EthashAux.cpp | 6 +-- libethereum/ClientBase.cpp | 7 +++- libethereum/Transaction.h | 11 ++--- libethereum/TransactionQueue.cpp | 49 ++++++++++++++++++++--- libethereum/TransactionQueue.h | 7 +++- libweb3jsonrpc/WebThreeStubServerBase.cpp | 4 +- 7 files changed, 64 insertions(+), 22 deletions(-) diff --git a/libdevcore/Common.h b/libdevcore/Common.h index 49491d4cc..b2d48da98 100644 --- a/libdevcore/Common.h +++ b/libdevcore/Common.h @@ -52,6 +52,8 @@ using byte = uint8_t; #define DEV_QUOTED_HELPER(s) #s #define DEV_QUOTED(s) DEV_QUOTED_HELPER(s) +#define DEV_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} + namespace dev { diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp index 19a96f550..9cb4d9fad 100644 --- a/libethcore/EthashAux.cpp +++ b/libethcore/EthashAux.cpp @@ -40,8 +40,6 @@ using namespace chrono; using namespace dev; using namespace eth; -#define ETH_IGNORE_EXCEPTIONS(X) try { X; } catch (...) {} - EthashAux* dev::eth::EthashAux::s_this = nullptr; EthashAux::~EthashAux() @@ -171,8 +169,8 @@ EthashAux::FullType EthashAux::full(h256 const& _seedHash, bytesRef _dest, bool boost::filesystem::rename(oldMemoFile, memoFile); } - ETH_IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile)); - ETH_IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile + ".info")); + DEV_IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile)); + DEV_IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile + ".info")); ethash_params p = params(_seedHash); assert(!_dest || _dest.size() >= p.full_size); // must be big enough. diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 7c56bce4e..eba8dbc67 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -48,8 +48,11 @@ State ClientBase::asOf(BlockNumber _h) const void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) { prepareForTransaction(); - - u256 n = postMine().transactionsFrom(toAddress(_secret)); + + auto a = toAddress(_secret); + u256 n = postMine().transactionsFrom(a); + cdebug << "submitTx: " << a << "postMine=" << n << "; tq=" << m_tq.maxNonce(a); + n = max(n, m_tq.maxNonce(a)); Transaction t(_value, _gasPrice, _gas, _dest, _data, n, _secret); m_tq.import(t.rlp()); diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 7276493c2..09102e0ba 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -221,19 +221,14 @@ using Transactions = std::vector; /// Simple human-readable stream-shift operator. inline std::ostream& operator<<(std::ostream& _out, Transaction const& _t) { - _out << "{"; + _out << _t.sha3().abridged() << "{"; if (_t.receiveAddress()) _out << _t.receiveAddress().abridged(); else _out << "[CREATE]"; - _out << "/" << _t.nonce() << "$" << _t.value() << "+" << _t.gas() << "@" << _t.gasPrice(); - try - { - _out << "<-" << _t.sender().abridged(); - } - catch (...) {} - _out << " #" << _t.data().size() << "}"; + _out << "/" << _t.data().size() << "$" << _t.value() << "+" << _t.gas() << "@" << _t.gasPrice(); + _out << "<-" << _t.safeSender().abridged() << " #" << _t.nonce() << "}"; return _out; } diff --git a/libethereum/TransactionQueue.cpp b/libethereum/TransactionQueue.cpp index 40eec1ac5..57429d32c 100644 --- a/libethereum/TransactionQueue.cpp +++ b/libethereum/TransactionQueue.cpp @@ -53,7 +53,7 @@ ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallb UpgradeGuard ul(l); // If valid, append to blocks. - m_current[h] = t; + insertCurrent_WITH_LOCK(make_pair(h, t)); m_known.insert(h); if (_cb) m_callbacks[h] = _cb; @@ -74,13 +74,54 @@ ImportResult TransactionQueue::import(bytesConstRef _transactionRLP, ImportCallb return ImportResult::Success; } +u256 TransactionQueue::maxNonce(Address const& _a) const +{ + cdebug << "txQ::maxNonce" << _a; + ReadGuard l(m_lock); + u256 ret = 0; + auto r = m_senders.equal_range(_a); + for (auto it = r.first; it != r.second; ++it) + { + cdebug << it->first << "1+" << m_current.at(it->second).nonce(); + DEV_IGNORE_EXCEPTIONS(ret = max(ret, m_current.at(it->second).nonce() + 1)); + } + return ret; +} + +void TransactionQueue::insertCurrent_WITH_LOCK(std::pair const& _p) +{ + cdebug << "txQ::insertCurrent" << _p.first << _p.second.sender() << _p.second.nonce(); + m_senders.insert(make_pair(_p.second.sender(), _p.first)); + m_current.insert(_p); +} + +bool TransactionQueue::removeCurrent_WITH_LOCK(h256 const& _txHash) +{ + cdebug << "txQ::removeCurrent" << _txHash; + if (m_current.count(_txHash)) + { + auto r = m_senders.equal_range(m_current[_txHash].sender()); + for (auto it = r.first; it != r.second; ++it) + if (it->second == _txHash) + { + cdebug << "=> sender" << it->first; + m_senders.erase(it); + break; + } + cdebug << "=> nonce" << m_current[_txHash].nonce(); + m_current.erase(_txHash); + return true; + } + return false; +} + void TransactionQueue::setFuture(std::pair const& _t) { WriteGuard l(m_lock); if (m_current.count(_t.first)) { - m_current.erase(_t.first); m_unknown.insert(make_pair(_t.second.sender(), _t)); + m_current.erase(_t.first); } } @@ -104,9 +145,7 @@ void TransactionQueue::drop(h256 const& _txHash) m_dropped.insert(_txHash); m_known.erase(_txHash); - if (m_current.count(_txHash)) - m_current.erase(_txHash); - else + if (!removeCurrent_WITH_LOCK(_txHash)) { for (auto i = m_unknown.begin(); i != m_unknown.end(); ++i) if (i->second.first == _txHash) diff --git a/libethereum/TransactionQueue.h b/libethereum/TransactionQueue.h index 3858949cc..16bc34641 100644 --- a/libethereum/TransactionQueue.h +++ b/libethereum/TransactionQueue.h @@ -56,6 +56,7 @@ public: std::map transactions() const { ReadGuard l(m_lock); return m_current; } std::pair items() const { ReadGuard l(m_lock); return std::make_pair(m_current.size(), m_unknown.size()); } + u256 maxNonce(Address const& _a) const; void setFuture(std::pair const& _t); void noteGood(std::pair const& _t); @@ -64,12 +65,16 @@ public: template Handler onReady(T const& _t) { return m_onReady.add(_t); } private: - mutable SharedMutex m_lock; ///< General lock. + void insertCurrent_WITH_LOCK(std::pair const& _p); + bool removeCurrent_WITH_LOCK(h256 const& _txHash); + + mutable SharedMutex m_lock; ///< General lock. std::set m_known; ///< Hashes of transactions in both sets. std::map m_current; ///< Map of SHA3(tx) to tx. std::multimap> m_unknown; ///< For transactions that have a future nonce; we map their sender address to the tx stuff, and insert once the sender has a valid TX. std::map> m_callbacks; ///< Called once. std::set m_dropped; ///< Transactions that have previously been dropped. + std::multimap m_senders; ///< Mapping from the sender address to the transaction hash; useful for determining the nonce of a given sender. Signal m_onReady; ///< Called when a subsequent call to import transactions will return a non-empty container. Be nice and exit fast. }; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 208351fc6..2a1427b16 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -505,7 +505,7 @@ string WebThreeStubServerBase::eth_sendTransaction(Json::Value const& _json) if (!t.gasPrice) t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow. if (!t.gas) - t.gas = min(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); + t.gas = min(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice); if (m_accounts->isRealAccount(t.from)) authenticate(t, false); @@ -534,7 +534,7 @@ string WebThreeStubServerBase::eth_signTransaction(Json::Value const& _json) if (!t.gasPrice) t.gasPrice = 10 * dev::eth::szabo; // TODO: should be determined by user somehow. if (!t.gas) - t.gas = min(client()->gasLimitRemaining(), client()->balanceAt(t.from) / t.gasPrice); + t.gas = min(client()->gasLimitRemaining() / 5, client()->balanceAt(t.from) / t.gasPrice); if (m_accounts->isRealAccount(t.from)) authenticate(t, false);