diff --git a/mix/qml/DeployContractStep.qml b/mix/qml/DeployContractStep.qml index 4d675a639..3f796d590 100644 --- a/mix/qml/DeployContractStep.qml +++ b/mix/qml/DeployContractStep.qml @@ -2,6 +2,7 @@ import QtQuick 2.0 import QtQuick.Layouts 1.0 import QtQuick.Controls 1.1 import QtQuick.Controls.Styles 1.3 +import Qt.labs.settings 1.0 import "js/TransactionHelper.js" as TransactionHelper import "js/NetworkDeployment.js" as NetworkDeploymentCode import "js/QEtherHelper.js" as QEtherHelper @@ -10,10 +11,13 @@ import org.ethereum.qml.QEther 1.0 Rectangle { property variant paramsModel: [] property variant worker + property variant gas: [] color: "#E3E3E3E3" anchors.fill: parent id: root + property int labelWidth: 150 + function show() { visible = true @@ -26,6 +30,7 @@ Rectangle { } if (worker.accounts.length > 0) worker.currentAccount = worker.accounts[0].id + deployedAddresses.refresh() } RowLayout @@ -201,7 +206,7 @@ Rectangle { Layout.fillWidth: true Rectangle { - width: 100 + width: labelWidth Label { text: qsTr("Account") @@ -228,7 +233,7 @@ Rectangle { Layout.fillWidth: true Rectangle { - width: 100 + width: labelWidth Label { text: qsTr("Gas Price") @@ -289,6 +294,7 @@ Rectangle { worker.estimateGas(sce, function(gas) { if (gasPriceLoad.loaded) { + root.gas = gas cost = 0 for (var k in gas) { @@ -308,7 +314,7 @@ Rectangle { Rectangle { - width: 100 + width: labelWidth Label { text: qsTr("Cost Estimate") @@ -327,7 +333,66 @@ Rectangle { } } + RowLayout + { + id: deployedRow + Layout.fillWidth: true + Rectangle + { + width: labelWidth + Label + { + id: labelAddresses + text: qsTr("Deployed Addresses") + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + } + } + + ColumnLayout + { + + ListModel + { + id: deployedAddrModel + } + Repeater + { + id: deployedAddresses + model: deployedAddrModel + function refresh() + { + deployedAddrModel.clear() + deployedRow.visible = Object.keys(projectModel.deploymentAddresses).length > 0 + for (var k in projectModel.deploymentAddresses) + { + deployedAddrModel.append({ id: k, value: projectModel.deploymentAddresses[k]}) + } + } + + Rectangle + { + Layout.preferredHeight: 20 + Layout.preferredWidth: 235 + color: "transparent" + Label + { + id: labelContract + width: 110 + elide: Text.ElideRight + text: index > -1 ? deployedAddrModel.get(index).id : "" + } + + TextField + { + anchors.left: labelContract.right + text: index > - 1 ? deployedAddrModel.get(index).value : "" + } + } + } + } + } } Rectangle @@ -341,7 +406,10 @@ Rectangle { onClicked: { projectModel.deployedScenarioIndex = contractList.currentIndex - NetworkDeploymentCode.deployContracts(); + NetworkDeploymentCode.deployContracts(root.gas, function(addresses) + { + deployedAddresses.refresh() + }); } } } diff --git a/mix/qml/DeploymentDialog.qml b/mix/qml/DeploymentDialog.qml index ad946cd3e..f2fdc32a2 100644 --- a/mix/qml/DeploymentDialog.qml +++ b/mix/qml/DeploymentDialog.qml @@ -14,7 +14,7 @@ import "." Dialog { id: modalDeploymentDialog modality: Qt.ApplicationModal - width: 800 + width: 850 height: 450 visible: false diff --git a/mix/qml/DeploymentWorker.qml b/mix/qml/DeploymentWorker.qml index 054d5a90c..ea6af5dab 100644 --- a/mix/qml/DeploymentWorker.qml +++ b/mix/qml/DeploymentWorker.qml @@ -61,7 +61,6 @@ Item NetworkDeploymentCode.gasPrice(function(price) { gasPrice = price; gasPriceInt.setValue(price); - console.log("fjdsfkjds hfkdsf " + price) gasPriceLoaded() }, function(){}); } diff --git a/mix/qml/PackagingStep.qml b/mix/qml/PackagingStep.qml index 24453a24b..bd76b1d9e 100644 --- a/mix/qml/PackagingStep.qml +++ b/mix/qml/PackagingStep.qml @@ -13,18 +13,14 @@ Rectangle { property variant worker color: "#E3E3E3E3" anchors.fill: parent - + id: root property string packageHash property string packageBase64 property alias localPackageUrl: localPackageUrl.text + property alias lastDeployDate: lastDeployLabel.text property string deploymentId property string packageDir - Settings { - property alias localUrl: localPackageUrl.text - } - - function show() { visible = true @@ -100,16 +96,35 @@ Rectangle { Rectangle { Layout.fillWidth: true - Layout.preferredHeight: 20 + Layout.preferredHeight: 40 color: "transparent" Button { + id: generatePackageBtn Layout.preferredWidth: 200 anchors.horizontalCenter: parent.horizontalCenter text: qsTr("Generate Package") onClicked: { - NetworkDeploymentCode.packageDapp(projectModel.deploymentAddresses) + NetworkDeploymentCode.packageDapp(projectModel.deploymentAddresses); + } + } + + RowLayout + { + anchors.top: generatePackageBtn.bottom + anchors.topMargin: 10 + visible: root.lastDeployDate !== "" + anchors.horizontalCenter: parent.horizontalCenter + Label + { + id: lastPackage + text: qsTr("Last Package") + } + + Label + { + id: lastDeployLabel } } } diff --git a/mix/qml/RegisteringStep.qml b/mix/qml/RegisteringStep.qml index 79ea17d0d..08dfa8c14 100644 --- a/mix/qml/RegisteringStep.qml +++ b/mix/qml/RegisteringStep.qml @@ -11,8 +11,8 @@ import "." Rectangle { property variant worker - property alias applicationUrlEth: applicationUrlEth.text - property alias applicationUrlHttp: applicationUrlHttp.text + property string applicationUrlEth + property string applicationUrlHttp property string eth: registrarAddr.text property int ownedRegistrarDeployGas: 1179075 // TODO: Use sol library to calculate gas requirement for each tr. property int ownedRegistrarSetSubRegistrarGas: 50000 @@ -25,16 +25,11 @@ Rectangle { function show() { ctrRegisterLabel.calculateRegisterGas() + applicationUrlEthCtrl.text = applicationUrlEth + applicationUrlHttp.text = applicationUrlHttp visible = true } - Settings - { - id: settings - property alias ethUrl: applicationUrlEth.text - property string httpUrl: applicationUrlHttp.text - } - ColumnLayout { anchors.top: parent.top @@ -69,7 +64,7 @@ Rectangle { DefaultTextField { id: registrarAddr - text: "bb9af5b8f19fb2bc1765ca36e697fa30e3386b71" //"c6d9d2cd449a754c494264e1809c50e34d64562b" + text: "31e316dace244c1efb93c565eb1974ff8efbdefe" //"c6d9d2cd449a754c494264e1809c50e34d64562b" visible: true Layout.preferredWidth: 235 } @@ -92,8 +87,7 @@ Rectangle { DefaultTextField { - id: applicationUrlHttp - enabled: rowRegister.isOkToRegister() + id: applicationUrlHttpCtrl Layout.preferredWidth: 235 } } @@ -160,7 +154,7 @@ Rectangle { DefaultTextField { width: 235 - id: applicationUrlEth + id: applicationUrlEthCtrl onTextChanged: { ctrRegisterLabel.calculateRegisterGas(); } @@ -194,34 +188,44 @@ Rectangle { width: 30 onClicked: { - var inError = []; - var ethUrl = NetworkDeploymentCode.formatAppUrl(applicationUrlEth.text); - for (var k in ethUrl) + if (applicationUrlEthCtrl.text !== applicationUrlEth) { - if (ethUrl[k].length > 32) - inError.push(qsTr("Member too long: " + ethUrl[k]) + "\n"); + var inError = []; + var ethUrl = NetworkDeploymentCode.formatAppUrl(applicationUrlEth.text); + for (var k in ethUrl) + { + if (ethUrl[k].length > 32) + inError.push(qsTr("Member too long: " + ethUrl[k]) + "\n"); + } + if (!worker.stopForInputError(inError)) + { + NetworkDeploymentCode.registerDapp(function(){ + }) + } } - if (!worker.stopForInputError(inError)) + + + if (applicationUrlHttpCtrl.text !== applicationUrlHttp) { - NetworkDeploymentCode.registerDapp(function(){ - applicationUrlEth.text = ethUrl - if (applicationUrlHttp.text === "" || deploymentDialog.packageHash === "") - { - deployDialog.title = text; - deployDialog.text = qsTr("Please provide the link where the resources are stored and ensure the package is aleary built using the deployment step.") - deployDialog.open(); - return; - } - var inError = []; - if (applicationUrlHttp.text.length > 32) - inError.push(qsTr(applicationUrlHttp.text)); - if (!worker.stopForInputError(inError)) - { - /*registerToUrlHint(function(){ - settings.httpUrl = applicationUrlHttp.text - })*/ - } - }) + if (!(ethUrl.length === 1 && ethUrl[0] === projectModel.projectTitle)) + { + applicationUrlEth.text = ethUrl.join('/') + } + if (applicationUrlHttp.text === "" || deploymentDialog.packageHash === "") + { + deployDialog.title = text; + deployDialog.text = qsTr("Please provide the link where the resources are stored and ensure the package is aleary built using the deployment step.") + deployDialog.open(); + return; + } + var inError = []; + if (applicationUrlHttp.text.length > 32) + inError.push(qsTr(applicationUrlHttp.text)); + if (!worker.stopForInputError(inError)) + { + registerToUrlHint(function(){ + }) + } } } } diff --git a/mix/qml/TransactionDialog.qml b/mix/qml/TransactionDialog.qml index 9960afca7..e47bd9ed2 100644 --- a/mix/qml/TransactionDialog.qml +++ b/mix/qml/TransactionDialog.qml @@ -127,7 +127,7 @@ Dialog { if (functionComboBox.currentIndex >= 0 && functionComboBox.currentIndex < functionsModel.count) { var contract = codeModel.contracts[TransactionHelper.contractFromToken(contractCreationComboBox.currentValue())]; if (contract) { - var func = contract.contract.functions[functionComboBox.currentIndex /*+ 1*/]; + var func = getFunction(functionComboBox.currentText, contract); if (func) { var parameters = func.parameters; for (var p = 0; p < parameters.length; p++) @@ -138,6 +138,18 @@ Dialog { initTypeLoader(); } + function getFunction(name, contract) + { + for (var k in contract.contract.functions) + { + if (contract.contract.functions[k].name === name) + { + return contract.contract.functions[k] + } + } + return null + } + function initTypeLoader() { paramScroll.value = {} diff --git a/mix/qml/js/NetworkDeployment.js b/mix/qml/js/NetworkDeployment.js index 24be9eb3e..e159108bf 100644 --- a/mix/qml/js/NetworkDeployment.js +++ b/mix/qml/js/NetworkDeployment.js @@ -32,8 +32,9 @@ function deployProject(force) { deploymentDialog.open(); } -function deployContracts() +function deployContracts(gas, callback) { + deploymentGas = gas; var jsonRpcUrl = "http://127.0.0.1:8080"; console.log("Deploying to " + jsonRpcUrl); deploymentStarted(); @@ -50,6 +51,8 @@ function deployContracts() executeTr(0, 0, state, ctrAddresses, function(){ projectModel.deploymentAddresses = ctrAddresses; deploymentStepChanged(qsTr("Scenario deployed. Please wait for verifications")) + if (callback) + callback(ctrAddresses) }); } @@ -135,16 +138,18 @@ function getFunction(ctrName, functionId) } } +var deploymentGas +var trRealIndex = -1 function executeTr(blockIndex, trIndex, state, ctrAddresses, callBack) { + trRealIndex++; var tr = state.blocks.get(blockIndex).transactions.get(trIndex); var func = getFunction(tr.contractId, tr.functionId); - console.log(func + " " + tr.contractId + " " + tr.functionId + " ") if (!func) executeTrNextStep(blockIndex, trIndex, state, ctrAddresses, callBack); else { - var gasCost = clientModel.toHex(clientModel.gasCosts[trIndex]); + var gasCost = clientModel.toHex(deploymentGas[trRealIndex]); var rpcParams = { "from": deploymentDialog.worker.currentAccount, "gas": "0x" + gasCost }; var params = replaceParamToken(func.parameters, tr.parameters, ctrAddresses); var encodedParams = clientModel.encodeParams(params, contractFromToken(tr.contractId), tr.functionId); @@ -223,6 +228,15 @@ function packageDapp(addresses) deploymentStepChanged(qsTr("Packaging application ...")); var deploymentDir = projectPath + deploymentId + "/"; + + if (deploymentDialog.packageStep.packageDir !== "") + deploymentDir = deploymentDialog.packageStep.packageDir + else + { + deploymentDir = projectPath + "package/" + fileIo.makeDir(deploymentDir); + } + projectModel.deploymentDir = deploymentDir; fileIo.makeDir(deploymentDir); for (var i = 0; i < projectListModel.count; i++) { @@ -263,24 +277,18 @@ function packageDapp(addresses) deploymentAddresses = addresses; saveProject(); - if (deploymentDialog.packageStep.packageDir !== "") - deploymentDir = deploymentDialog.packageStep.packageDir - else - { - deploymentDir = projectPath + "package/" - fileIo.makeDir(deploymentDir); - } - var packageRet = fileIo.makePackage(deploymentDir); deploymentDialog.packageStep.packageHash = packageRet[0]; deploymentDialog.packageStep.packageBase64 = packageRet[1]; deploymentDialog.packageStep.localPackageUrl = packageRet[2] + "?hash=" + packageRet[0]; + deploymentDialog.packageStep.lastDeployDate = date deploymentComplete() } function registerDapp(callback) { var applicationUrlEth = deploymentDialog.registerStep.applicationUrlEth; + projectModel.deploymentEthUrl = applicationUrlEth applicationUrlEth = formatAppUrl(applicationUrlEth); deploymentStepChanged(qsTr("Registering application on the Ethereum network ...")); checkEthPath(applicationUrlEth, false, function (success) { @@ -512,7 +520,7 @@ function registerContentHash(registrar, callBack) function registerToUrlHint(callback) { deploymentStepChanged(qsTr("Registering application Resources (" + deploymentDialog.registerStep.applicationUrlHttp) + ") ..."); - + projectModel.deploymentHttpUrl = deploymentDialog.registerStep.applicationUrlHttp urlHintAddress(function(urlHint){ var requests = []; var paramUrlHttp = clientModel.encodeStringParam(deploymentDialog.registerStep.applicationUrlHttp); diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js index a3f6372e0..a203ef8fd 100644 --- a/mix/qml/js/ProjectModel.js +++ b/mix/qml/js/ProjectModel.js @@ -74,11 +74,12 @@ function saveProjectFile() files: [], title: projectTitle, deploymentAddresses: deploymentAddresses, - applicationUrlEth: deploymentDialog.applicationUrlEth, - applicationUrlHttp: deploymentDialog.applicationUrlHttp, - packageHash: deploymentDialog.packageHash, - packageBase64: deploymentDialog.packageBase64, - deploymentDir: projectModel.deploymentDir + applicationUrlEth: deploymentDialog.registerStep.applicationUrlEth, + applicationUrlHttp: deploymentDialog.registerStep.applicationUrlHttp, + packageHash: deploymentDialog.packageStep.packageHash, + packageBase64: deploymentDialog.packageStep.packageBase64, + deploymentDir: deploymentDialog.packageStep.packageDir, + lastPackageDate: deploymentDialog.packageStep.lastDeployDate }; for (var i = 0; i < projectListModel.count; i++) projectData.files.push({ @@ -114,11 +115,13 @@ function loadProject(path) { deploymentDialog.registerStep.applicationUrlEth = projectData.applicationUrlEth if (projectData.applicationUrlHttp) deploymentDialog.registerStep.applicationUrlHttp = projectData.applicationUrlHttp + if (projectData.lastPackageDate) + deploymentDialog.packageStep.lastDeployDate = projectData.lastPackageDate if (!projectData.title) { var parts = path.split("/"); projectData.title = parts[parts.length - 2]; } - deploymentAddresses = projectData.deploymentAddresses ? projectData.deploymentAddresses : []; + deploymentAddresses = projectData.deploymentAddresses ? projectData.deploymentAddresses : {}; projectTitle = projectData.title; projectPath = path; if (!projectData.files)