diff --git a/mix/QBigInt.h b/mix/QBigInt.h index 700c817e5..a2dac8cf9 100644 --- a/mix/QBigInt.h +++ b/mix/QBigInt.h @@ -82,6 +82,8 @@ public: BigIntVariant internalValue() const { return m_internalValue; } /// @returns a string representation of the big integer used. Invokable from QML. Q_INVOKABLE QString value() const; + /// hex value. + Q_INVOKABLE QString hexValue() const { return QString::fromStdString(dev::toHex(dev::u256(value().toStdString()))); } /// Set the value of the BigInteger used. Will use u256 type. Invokable from QML. Q_INVOKABLE void setValue(QString const& _value) { m_internalValue = dev::jsToU256(_value.toStdString()); } Q_INVOKABLE void setBigInt(QString const& _value) { m_internalValue = bigint(_value.toStdString()); } diff --git a/mix/QFunctionDefinition.h b/mix/QFunctionDefinition.h index a9c45ffcd..5a056fa75 100644 --- a/mix/QFunctionDefinition.h +++ b/mix/QFunctionDefinition.h @@ -55,6 +55,8 @@ public: FixedHash<4> hash() const { return m_hash; } /// Get the full hash of this function declaration on the contract ABI. FixedHash<32> fullHash() const { return m_fullHash; } + /// Get the hash of this function declaration on the contract ABI. returns QString + Q_INVOKABLE QString qhash() const { return QString::fromStdString(m_hash.hex()); } private: int m_index; diff --git a/mix/qml/Block.qml b/mix/qml/Block.qml index 732166628..383cb85e8 100644 --- a/mix/qml/Block.qml +++ b/mix/qml/Block.qml @@ -105,6 +105,7 @@ ColumnLayout anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 14 + visible: false MouseArea { anchors.fill: parent diff --git a/mix/qml/BlockChain.qml b/mix/qml/BlockChain.qml index 1b1b68862..960d95ebf 100644 --- a/mix/qml/BlockChain.qml +++ b/mix/qml/BlockChain.qml @@ -117,47 +117,7 @@ ColumnLayout { RowLayout { - id: header - spacing: 0 - Layout.preferredHeight: 24 - Rectangle - { - Layout.preferredWidth: statusWidth - Layout.preferredHeight: parent.height - color: "transparent" - Image { - id: debugImage - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - source: "qrc:/qml/img/recycleicon@2x.png" - width: statusWidth + 10 - fillMode: Image.PreserveAspectFit - } - } - Rectangle - { - anchors.verticalCenter: parent.verticalCenter - Layout.preferredWidth: fromWidth - Label - { - anchors.verticalCenter: parent.verticalCenter - text: "From" - anchors.left: parent.left - anchors.leftMargin: horizontalMargin - } - } - Label - { - text: "To" - anchors.verticalCenter: parent.verticalCenter - Layout.preferredWidth: toWidth + cellSpacing - } - Label - { - text: "" - anchors.verticalCenter: parent.verticalCenter - Layout.preferredWidth: debugActionWidth - } + Layout.preferredHeight: 10 } Rectangle @@ -178,18 +138,6 @@ ColumnLayout { width: parent.width spacing: 20 - Block - { - scenario: blockChainPanel.model - Layout.preferredWidth: blockChainScrollView.width - Layout.preferredHeight: 60 - blockIndex: -1 - transactions: [] - status: "" - number: -2 - trHeight: 60 - } - Repeater // List of blocks { id: blockChainRepeater diff --git a/mix/qml/DeployContractStep.qml b/mix/qml/DeployContractStep.qml index 10f879ab7..01f06e4f2 100644 --- a/mix/qml/DeployContractStep.qml +++ b/mix/qml/DeployContractStep.qml @@ -12,12 +12,15 @@ Rectangle { property variant paramsModel: [] property variant worker property variant gas: [] + property alias gasPrice: gasPriceInput color: "#E3E3E3E3" + signal deployed anchors.fill: parent id: root property int labelWidth: 150 + function show() { visible = true @@ -25,12 +28,13 @@ Rectangle { contractList.change() accountsModel.clear() for (var k in worker.accounts) - { accountsModel.append(worker.accounts[k]) - } - if (worker.accounts.length > 0) + if (worker.currentAccount === "" && worker.accounts.length > 0) + { worker.currentAccount = worker.accounts[0].id + accountsList.currentIndex = 0 + } if (projectModel.deployBlockNumber !== -1) { @@ -45,13 +49,28 @@ Rectangle { function updateVerification(blockNumber, trLost) { - verificationLabel.text = blockNumber - projectModel.deployBlockNumber - if (trLost.length > 0) + var nb = parseInt(blockNumber - projectModel.deployBlockNumber) + verificationTextArea.visible = false + verificationLabel.visible = true + if (nb >= 10) { - verificationLabel.text += "\n" + qsTr("Transactions lost") + "\n" - for (var k in trLost) + verificationLabel.text = qsTr("contracts deployment verified") + verificationLabel.color = "green" + } + else + { + verificationLabel.text = nb + if (trLost.length > 0) { - verificationLabel.text += trLost[k] + "\n" + verificationTextArea.visible = true + verificationLabel.visible = false + deploymentStepChanged("following transactions are invalidated:") + verificationTextArea.text += "\n" + qsTr("Transactions lost") + "\n" + for (var k in trLost) + { + deploymentStepChanged(trLost[k]) + verificationTextArea.text += trLost[k] + "\n" + } } } } @@ -250,7 +269,6 @@ Rectangle { { worker.currentAccount = currentText accountBalance.text = worker.balance(currentText).format() - console.log(worker.balance(currentText).format()) } } @@ -280,6 +298,11 @@ Rectangle { displayUnitSelection: true displayFormattedValue: true edit: true + + function toHexWei() + { + return "0x" + gasPriceInput.value.toWei().hexValue() + } } Connections @@ -329,9 +352,7 @@ Rectangle { root.gas = gas cost = 0 for (var k in gas) - { cost += gas[k] - } setCost() } }); @@ -349,7 +370,7 @@ Rectangle { width: labelWidth Label { - text: qsTr("Cost Estimate") + text: qsTr("Deployment Cost") anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter } @@ -365,92 +386,87 @@ Rectangle { } } - RowLayout + Rectangle { - id: deployedRow + border.color: "#cccccc" + border.width: 2 Layout.fillWidth: true - Rectangle + Layout.preferredHeight: parent.height + 25 + color: "transparent" + id: rectDeploymentVariable + ScrollView { - width: labelWidth - Label + anchors.fill: parent + anchors.topMargin: 4 + anchors.bottomMargin: 4 + ColumnLayout { - id: labelAddresses - text: qsTr("Deployed Contracts") - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter - } - } - - ColumnLayout - { - anchors.top: parent.top - anchors.topMargin: 1 - ListModel - { - id: deployedAddrModel - } - - Repeater - { - id: deployedAddresses - model: deployedAddrModel - function refresh() + RowLayout { - deployedAddrModel.clear() - deployedRow.visible = Object.keys(projectModel.deploymentAddresses).length > 0 - for (var k in projectModel.deploymentAddresses) + id: deployedRow + Layout.fillWidth: true + Rectangle { - if (k.indexOf("-") !== -1) // this is an contract instance. ctr without - are the last deployed (to support old project) - deployedAddrModel.append({ id: k, value: projectModel.deploymentAddresses[k]}) + width: labelWidth + Label + { + id: labelAddresses + text: qsTr("Deployed Contracts") + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + } + } + + ColumnLayout + { + anchors.top: parent.top + anchors.topMargin: 1 + width: parent.width + id: deployedAddresses + function refresh() + { + textAddresses.text = "" + deployedRow.visible = Object.keys(projectModel.deploymentAddresses).length > 0 + textAddresses.text = JSON.stringify(projectModel.deploymentAddresses, null, ' ') + } + TextArea + { + anchors.fill: parent + id: textAddresses + } } } - Rectangle + RowLayout { - Layout.preferredHeight: 20 - Layout.preferredWidth: 235 - color: "transparent" - Label + id: verificationRow + Layout.fillWidth: true + visible: Object.keys(projectModel.deploymentAddresses).length > 0 + Rectangle { - id: labelContract - width: 112 - elide: Text.ElideRight - text: index > -1 ? deployedAddrModel.get(index).id : "" + width: labelWidth + Label + { + text: qsTr("Verifications") + anchors.right: parent.right + anchors.verticalCenter: parent.verticalCenter + } } - TextField + TextArea { - width: 123 - anchors.verticalCenter: parent.verticalCenter - anchors.left: labelContract.right - text: index > - 1 ? deployedAddrModel.get(index).value : "" + id: verificationTextArea + visible: false } - } - } - } - } - RowLayout - { - id: verificationRow - Layout.fillWidth: true - visible: Object.keys(projectModel.deploymentAddresses).length > 0 - Rectangle - { - width: labelWidth - Label - { - text: qsTr("Verifications") - anchors.right: parent.right - anchors.verticalCenter: parent.verticalCenter + Label + { + id: verificationLabel + visible: true + } + } } } - - Label - { - id: verificationLabel - maximumLineCount: 20 - } } } @@ -460,12 +476,31 @@ Rectangle { Layout.alignment: Qt.BottomEdge Button { + Layout.preferredHeight: 22 + anchors.right: deployBtn.left + text: qsTr("Reset") + action: clearDeployAction + } + + Action { + id: clearDeployAction + onTriggered: { + worker.forceStopPooling() + fileIo.deleteDir(projectModel.deploymentDir) + projectModel.cleanDeploymentStatus() + deploymentDialog.steps.reset() + } + } + + Button + { + id: deployBtn anchors.right: parent.right text: qsTr("Deploy Contracts") onClicked: { projectModel.deployedScenarioIndex = contractList.currentIndex - NetworkDeploymentCode.deployContracts(root.gas, function(addresses, trHashes) + NetworkDeploymentCode.deployContracts(root.gas, gasPriceInput.toHexWei(), function(addresses, trHashes) { projectModel.deploymentTrHashes = trHashes worker.verifyHashes(trHashes, function (nb, trLost) @@ -473,6 +508,7 @@ Rectangle { projectModel.deployBlockNumber = nb projectModel.saveProject() root.updateVerification(nb, trLost) + root.deployed() }) projectModel.deploymentAddresses = addresses projectModel.saveProject() diff --git a/mix/qml/DeploymentDialog.qml b/mix/qml/DeploymentDialog.qml index 39022def2..280ce0d07 100644 --- a/mix/qml/DeploymentDialog.qml +++ b/mix/qml/DeploymentDialog.qml @@ -22,6 +22,7 @@ Dialog { property alias packageStep: packageStep property alias registerStep: registerStep property alias worker: worker + property alias steps: steps function close() { @@ -52,15 +53,31 @@ Dialog { anchors.fill: parent anchors.margins: 10 - RowLayout + Rectangle { id: explanation Layout.preferredWidth: parent.width - 50 Layout.preferredHeight: 50 + color: "transparent" Label { + id: info anchors.centerIn: parent - text: qsTr("Putting your dapp live is a multi step process. You can read more about it on the 'guide to uploading'.") + text: qsTr("Putting your dapp live is a multi step process. You can read more about it on the") + } + + Text { + anchors.left: info.right + anchors.leftMargin: 7 + id: linkText + text: 'guide to uploading' + onLinkActivated: Qt.openUrlExternally("https://github.com/ethereum/wiki/wiki/Mix:-The-DApp-IDE#deployment-to-network") + anchors.verticalCenter: parent.verticalCenter + MouseArea + { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + } } } diff --git a/mix/qml/DeploymentDialogSteps.qml b/mix/qml/DeploymentDialogSteps.qml index 5ebd81dea..5874d54a8 100644 --- a/mix/qml/DeploymentDialogSteps.qml +++ b/mix/qml/DeploymentDialogSteps.qml @@ -26,13 +26,55 @@ Rectangle { selected(step) } + function reset() + { + for (var k in deployLogs.logs) + { + deployLogs.logs[k] = "" + } + deployLogs.switchLogs() + refreshCurrent() + } + border.color: "#cccccc" border.width: 1 + + Connections + { + id: deployStatus + target: deploymentDialog.deployStep + onDeployed: + { + console.log("deployed") + } + } + + Connections + { + id: packagedStatus + target: deploymentDialog.packageStep + onPackaged: + { + console.log("packaged") + } + } + + Connections + { + id: registerStatus + target: deploymentDialog.registerStep + onRegistered: + { + console.log("registered") + } + } + ColumnLayout { anchors.fill: parent anchors.margins: 1 + spacing: 0 Repeater { id: menu @@ -45,7 +87,7 @@ Rectangle { { step: 2, type:"package", - label: qsTr("Package files") + label: qsTr("Package Dapp") }, { step: 3, @@ -70,6 +112,7 @@ Rectangle { labelContainer.state = "selected" sel = index itemClicked(menu.model[index].type) + deployLogs.switchLogs() } function unselect() @@ -136,62 +179,60 @@ Rectangle { } Connections { - target: projectModel - onDeploymentStarted: log.text = log.text + qsTr("Running deployment...") + "\n" - onDeploymentError: log.text = log.text + error + "\n" - onDeploymentComplete: log.text = log.text + qsTr("Deployment complete") + "\n" - onDeploymentStepChanged: log.text = log.text + message + "\n" - } + property var logs: ({}) + id: deployLogs - Rectangle - { - Layout.fillWidth: true - Layout.preferredHeight: 1 - color: "#cccccc" - } + function switchLogs() + { + if (root.sel) + { + if (!logs[root.sel]) + logs[root.sel] = "" + log.text = logs[root.sel] + } + } - RowLayout - { - anchors.horizontalCenter: parent.horizontalCenter - Layout.preferredHeight: 20 - anchors.left: parent.left - anchors.leftMargin: 2 - Button + target: projectModel + onDeploymentStarted: { - Layout.preferredHeight: 22 - Layout.preferredWidth: 22 - action: clearAction - iconSource: "qrc:/qml/img/cleariconactive.png" + if (!logs[root.sel]) + logs[root.sel] = "" + logs[root.sel] = logs[root.sel] + qsTr("Running deployment...") + "\n" + log.text = logs[root.sel] } - Action { - id: clearAction - enabled: log.text !== "" - tooltip: qsTr("Clear") - onTriggered: { - log.text = "" - } + onDeploymentError: + { + if (!logs[root.sel]) + logs[root.sel] = "" + logs[root.sel] = logs[root.sel] + error + "\n" + log.text = logs[root.sel] } - Button + onDeploymentComplete: { - Layout.preferredHeight: 22 - text: qsTr("Clear Deployment") - action: clearDeployAction + if (!logs[root.sel]) + logs[root.sel] = "" + logs[root.sel] = logs[root.sel] + qsTr("Deployment complete") + "\n" + log.text = logs[root.sel] } - Action { - id: clearDeployAction - onTriggered: { - worker.forceStopPooling() - fileIo.deleteDir(projectModel.deploymentDir) - projectModel.cleanDeploymentStatus() - root.refreshCurrent() - log.text = "" - } + onDeploymentStepChanged: + { + if (!logs[root.sel]) + logs[root.sel] = "" + logs[root.sel] = logs[root.sel] + message + "\n" + log.text = logs[root.sel] } } + Rectangle + { + Layout.fillWidth: true + Layout.preferredHeight: 2 + color: "#cccccc" + } + ScrollView { Layout.fillHeight: true @@ -205,6 +246,47 @@ Rectangle { id: log } } + + Rectangle + { + Layout.preferredHeight: 20 + Layout.fillWidth: true + color: "#cccccc" + LogsPaneStyle + { + id: style + } + + Label + { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + text: qsTr("Logs") + font.italic: true + font.pointSize: style.absoluteSize(-1) + } + + Button + { + height: 20 + width: 20 + anchors.right: parent.right + action: clearAction + iconSource: "qrc:/qml/img/cleariconactive.png" + tooltip: qsTr("Clear Messages") + } + + Action { + id: clearAction + enabled: log.text !== "" + tooltip: qsTr("Clear") + onTriggered: { + deployLogs.logs[root.sel] = "" + log.text = deployLogs.logs[root.sel] + } + } + } + } } diff --git a/mix/qml/DeploymentWorker.qml b/mix/qml/DeploymentWorker.qml index 9aef45112..c7532c840 100644 --- a/mix/qml/DeploymentWorker.qml +++ b/mix/qml/DeploymentWorker.qml @@ -38,6 +38,7 @@ Item var ids = JSON.parse(arg2)[0].result; requests = []; + accounts = [] for (var k in ids) { requests.push({ @@ -52,6 +53,7 @@ Item TransactionHelper.rpcCall(requests, function (request, response){ var balanceRet = JSON.parse(response); + balances = {} for (var k in balanceRet) { var ether = QEtherHelper.createEther(balanceRet[k].result, QEther.Wei); @@ -206,7 +208,7 @@ Item property var callBack property int elapsed property string hash - interval: 500 + interval: 2000 running: false repeat: true onTriggered: { @@ -227,7 +229,7 @@ Item stop(); callBack(1, receipt); } - else if (elapsed > 250000) + else if (elapsed > 2500000) { stop(); callBack(-1, null); diff --git a/mix/qml/KeyValuePanel.qml b/mix/qml/KeyValuePanel.qml index 056384b9e..d19f4d3fa 100644 --- a/mix/qml/KeyValuePanel.qml +++ b/mix/qml/KeyValuePanel.qml @@ -82,45 +82,44 @@ ColumnLayout { clip: true ColumnLayout { - anchors.margins: 10 + spacing: 0 + id: colValue + anchors.top: parent.top + anchors.topMargin: 5 Repeater { id: repeaterKeyValue model: modelKeyValue - RowLayout + Row { - Layout.fillWidth: true Layout.preferredHeight: 30 - spacing: 0 - Rectangle + spacing: 5 + anchors.left: colValue.left + anchors.leftMargin: 5 + Label { - Layout.preferredWidth: columnValues.width / 2 - Label - { - anchors.left: parent.left - anchors.leftMargin: 10 - text: { - if (index >= 0 && repeaterKeyValue.model.get(index).key !== undefined) - return repeaterKeyValue.model.get(index).key - else - return "" - } + maximumLineCount: 1 + text: { + if (index >= 0 && repeaterKeyValue.model.get(index).key !== undefined) + return repeaterKeyValue.model.get(index).key + else + return "" } } - Rectangle + Label { - Layout.preferredWidth: columnValues.width / 2 - 10 - Label - { - anchors.right: parent.right - anchors.rightMargin: 10 - text: { - if (index >= 0 && repeaterKeyValue.model.get(index).value !== undefined) - return repeaterKeyValue.model.get(index).value - else - return "" - } + text: "=" + } + + Label + { + maximumLineCount: 1 + text: { + if (index >= 0 && repeaterKeyValue.model.get(index).value !== undefined) + return repeaterKeyValue.model.get(index).value + else + return "" } } } diff --git a/mix/qml/PackagingStep.qml b/mix/qml/PackagingStep.qml index 424732869..6f7ed3f11 100644 --- a/mix/qml/PackagingStep.qml +++ b/mix/qml/PackagingStep.qml @@ -20,6 +20,7 @@ Rectangle { property alias lastDeployDate: lastDeployLabel.text property string deploymentId property string packageDir + signal packaged function show() { @@ -107,6 +108,7 @@ Rectangle { { NetworkDeploymentCode.packageDapp(projectModel.deploymentAddresses); projectModel.saveProject() + root.packaged() } } diff --git a/mix/qml/ProjectModel.qml b/mix/qml/ProjectModel.qml index 5ec833da6..14cc4ec39 100644 --- a/mix/qml/ProjectModel.qml +++ b/mix/qml/ProjectModel.qml @@ -80,20 +80,14 @@ Item { function getDocumentIndex(documentId) { return ProjectModelCode.getDocumentIndex(documentId); } function addExistingFiles(paths) { ProjectModelCode.doAddExistingFiles(paths); } function deployProject() { NetworkDeploymentCode.deployProject(false); } - function registerToUrlHint(url, callback) { NetworkDeploymentCode.registerToUrlHint(url, callback); } + function registerToUrlHint(url, gasPrice, callback) { NetworkDeploymentCode.registerToUrlHint(url, gasPrice, callback); } function formatAppUrl() { NetworkDeploymentCode.formatAppUrl(url); } function cleanDeploymentStatus() { deployedScenarioIndex = 0 - applicationUrlEth = "" - applicationUrlHttp = "" deployBlockNumber = "" deploymentTrHashes = {} - registerContentHashTrHash = "" - registerUrlTrHash = "" - registerContentHashBlockNumber = -1 - registerUrlBlockNumber = -1 deploymentAddresses = {} deploymentDir = "" deploymentDialog.packageStep.packageHash = "" @@ -102,6 +96,18 @@ Item { deploymentDialog.packageStep.lastDeployDate = "" deploymentDialog.packageStep.localPackageUrl = "" saveProject() + cleanRegisteringStatus() + } + + function cleanRegisteringStatus() + { + applicationUrlEth = "" + applicationUrlHttp = "" + registerContentHashTrHash = "" + registerUrlTrHash = "" + registerContentHashBlockNumber = -1 + registerUrlBlockNumber = -1 + saveProject() } Connections { diff --git a/mix/qml/RegisteringStep.qml b/mix/qml/RegisteringStep.qml index 648e04f16..e275e1434 100644 --- a/mix/qml/RegisteringStep.qml +++ b/mix/qml/RegisteringStep.qml @@ -19,42 +19,58 @@ Rectangle { id: root color: "#E3E3E3E3" anchors.fill: parent + signal registered function show() { ctrRegisterLabel.calculateRegisterGas() - applicationUrlEthCtrl.text = projectModel.applicationUrlEth - applicationUrlHttpCtrl.text = projectModel.applicationUrlHttp + if (applicationUrlHttpCtrl.text === "") + applicationUrlHttpCtrl.text = projectModel.applicationUrlHttp + + if (applicationUrlEthCtrl.text === "") + applicationUrlEthCtrl.text = projectModel.applicationUrlEth + visible = true verificationEthUrl.text = "" - if (projectModel.registerContentHashTrHash !== "") + if (projectModel.registerContentHashTrHash !== "" && projectModel.registerContentHashBlockNumber !== -1) { worker.verifyHash("registerHash", projectModel.registerContentHashTrHash, function(bn, trLost) { - updateVerification(projectModel.registerContentHashBlockNumber, bn, trLost, verificationEthUrl) + updateVerification(projectModel.registerContentHashBlockNumber, bn, trLost, verificationEthUrl, "registerHash") }); } + else if (projectModel.registerContentHashTrHash !== "" && projectModel.registerContentHashBlockNumber === -1) + verificationEthUrl.text = qsTr("waiting verifications") verificationUrl.text = "" - if (projectModel.registerUrlTrHash !== "") + if (projectModel.registerUrlTrHash !== "" && projectModel.registerUrlBlockNumber !== -1) { worker.verifyHash("registerUrl", projectModel.registerUrlTrHash, function(bn, trLost) { - updateVerification(projectModel.registerUrlBlockNumber, bn, trLost, verificationUrl) + updateVerification(projectModel.registerUrlBlockNumber, bn, trLost, verificationUrl, "registerUrl") }); } + else if (projectModel.registerUrlTrHash !== "" && projectModel.registerUrlBlockNumber === -1) + verificationUrl.text = qsTr("waiting verifications") } - function updateVerification(originbn, bn, trLost, ctrl) + function updateVerification(originbn, bn, trLost, ctrl, trContext) { if (trLost.length === 0) { ctrl.text = bn - originbn - ctrl.text += qsTr(" verifications") + if (parseInt(bn - originbn) >= 10) + { + ctrl.color= "green" + ctrl.text= qsTr("verified") + } + else + ctrl.text += qsTr(" verifications") } else { + deploymentStepChanged(trContext + qsTr(" has been invalidated.") + trLost[0] + " " + qsTr("no longer present") ) ctrl.text = qsTr("invalidated") } } @@ -124,6 +140,7 @@ Rectangle { { id: verificationUrl anchors.verticalCenter: parent.verticalCenter + font.italic: true } } @@ -136,7 +153,7 @@ Rectangle { Layout.preferredWidth: col.width / 2 Label { - text: qsTr("Gas to use for dapp registration") + text: qsTr("Registration Cost") anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter id: ctrRegisterLabel @@ -148,9 +165,12 @@ Rectangle { NetworkDeploymentCode.checkPathCreationCost(applicationUrlEthCtrl.text, function(pathCreationCost) { var ether = QEtherHelper.createBigInt(pathCreationCost); - var gasTotal = ether.multiply(worker.gasPriceInt); - gasToUseDeployInput.value = QEtherHelper.createEther(gasTotal.value(), QEther.Wei, parent); - gasToUseDeployInput.update(); + if (deploymentDialog.deployStep.gasPrice.value) + { + var gasTotal = ether.multiply(deploymentDialog.deployStep.gasPrice.value.toWei()); + gasToUseDeployInput.value = QEtherHelper.createEther(gasTotal.value(), QEther.Wei, parent); + gasToUseDeployInput.update(); + } }); } } @@ -159,9 +179,9 @@ Rectangle { Ether { id: gasToUseDeployInput - displayUnitSelection: true + displayUnitSelection: false displayFormattedValue: true - edit: true + edit: false Layout.preferredWidth: 235 } } @@ -224,6 +244,10 @@ Rectangle { Label { id: verificationEthUrl + anchors.verticalCenter: parent.verticalCenter; + anchors.topMargin: 10 + font.italic: true + font.pointSize: appStyle.absoluteSize(-1) } } } @@ -234,7 +258,7 @@ Rectangle { anchors.bottomMargin: 10 width: parent.width - function registerHash(callback) + function registerHash(gasPrice, callback) { var inError = []; var ethUrl = NetworkDeploymentCode.formatAppUrl(applicationUrlEthCtrl.text); @@ -244,10 +268,11 @@ Rectangle { inError.push(qsTr("Member too long: " + ethUrl[k]) + "\n"); } if (!worker.stopForInputError(inError)) - { - NetworkDeploymentCode.registerDapp(ethUrl, function(){ + { + NetworkDeploymentCode.registerDapp(ethUrl, gasPrice, function(){ projectModel.applicationUrlEth = applicationUrlEthCtrl.text projectModel.saveProject() + verificationEthUrl.text = qsTr("waiting verifications") worker.waitForTrReceipt(projectModel.registerContentHashTrHash, function(status, receipt) { worker.verifyHash("registerHash", projectModel.registerContentHashTrHash, function(bn, trLost) @@ -262,7 +287,7 @@ Rectangle { } } - function registerUrl() + function registerUrl(gasPrice, callback) { if (applicationUrlHttp.text === "" || deploymentDialog.packageHash === "") { @@ -276,9 +301,10 @@ Rectangle { inError.push(qsTr(applicationUrlHttpCtrl.text)); if (!worker.stopForInputError(inError)) { - registerToUrlHint(applicationUrlHttpCtrl.text, function(){ + registerToUrlHint(applicationUrlHttpCtrl.text, gasPrice, function(){ projectModel.applicationUrlHttp = applicationUrlHttpCtrl.text projectModel.saveProject() + verificationUrl.text = qsTr("waiting verifications") worker.waitForTrReceipt(projectModel.registerUrlTrHash, function(status, receipt) { worker.verifyHash("registerUrl", projectModel.registerUrlTrHash, function(bn, trLost) @@ -286,6 +312,8 @@ Rectangle { projectModel.registerUrlBlockNumber = bn projectModel.saveProject() root.updateVerification(bn, bn, trLost, verificationUrl) + root.registered() + callback() }); }) }) @@ -300,8 +328,12 @@ Rectangle { width: 30 onClicked: { - parent.registerHash(function(){ - parent.registerUrl() + verificationEthUrl.text = "" + verificationUrl.text = "" + projectModel.cleanRegisteringStatus() + var gasPrice = deploymentDialog.deployStep.gasPrice.toHexWei() + parent.registerHash(gasPrice, function(){ + parent.registerUrl(gasPrice, function(){}) }) } } diff --git a/mix/qml/ScenarioLoader.qml b/mix/qml/ScenarioLoader.qml index 0de779135..8b6886c93 100644 --- a/mix/qml/ScenarioLoader.qml +++ b/mix/qml/ScenarioLoader.qml @@ -35,7 +35,7 @@ ColumnLayout { Layout.preferredWidth: 560 anchors.horizontalCenter: parent.horizontalCenter - Layout.preferredHeight: 60 + Layout.preferredHeight: 75 spacing: 0 anchors.top: parent.top anchors.topMargin: 10 @@ -88,7 +88,7 @@ ColumnLayout color: "#cccccc" id: deleteImg anchors.top: parent.top - anchors.topMargin: 6 + anchors.topMargin: 7 visible: projectModel.stateListModel.count > 1 MouseArea { diff --git a/mix/qml/StatusPane.qml b/mix/qml/StatusPane.qml index a8750fc7c..23a39d126 100644 --- a/mix/qml/StatusPane.qml +++ b/mix/qml/StatusPane.qml @@ -179,7 +179,7 @@ Rectangle { function updateWidth() { - if (text.length > 80) + if (text.length > 100) width = parent.width - 10 else width = undefined diff --git a/mix/qml/WebPreview.qml b/mix/qml/WebPreview.qml index 5d0f208af..1b3b1dc40 100644 --- a/mix/qml/WebPreview.qml +++ b/mix/qml/WebPreview.qml @@ -272,7 +272,8 @@ Item { Button { - height: 28 + height: 22 + width: 22 anchors.verticalCenter: parent.verticalCenter action: expressionAction iconSource: "qrc:/qml/img/console.png" diff --git a/mix/qml/js/NetworkDeployment.js b/mix/qml/js/NetworkDeployment.js index 42cbf5207..2e8c8c885 100644 --- a/mix/qml/js/NetworkDeployment.js +++ b/mix/qml/js/NetworkDeployment.js @@ -32,11 +32,10 @@ function deployProject(force) { deploymentDialog.open(); } -function deployContracts(gas, callback) +function deployContracts(gas, gasPrice, callback) { deploymentGas = gas; - var jsonRpcUrl = "http://127.0.0.1:8080"; - console.log("Deploying to " + jsonRpcUrl); + deploymentGasPrice = gasPrice deploymentStarted(); var ctrAddresses = {}; @@ -79,10 +78,7 @@ function checkPathCreationCost(ethUrl, callBack) } } else - { - deploymentStepChanged(qsTr("Your Dapp can be registered here.")); callBack((dappUrl.length - 1) * (deploymentDialog.registerStep.ownedRegistrarDeployGas + deploymentDialog.registerStep.ownedRegistrarSetSubRegistrarGas) + deploymentDialog.registerStep.ownedRegistrarSetContentHashGas); - } }); } @@ -140,6 +136,7 @@ function getFunction(ctrName, functionId) } var deploymentGas +var deploymentGasPrice var trRealIndex = -1 function executeTr(blockIndex, trIndex, state, ctrAddresses, trHashes, callBack) { @@ -153,14 +150,14 @@ function executeTr(blockIndex, trIndex, state, ctrAddresses, trHashes, callBack) else { var gasCost = clientModel.toHex(deploymentGas[trRealIndex]); - var rpcParams = { "from": deploymentDialog.worker.currentAccount, "gas": "0x" + gasCost }; + var rpcParams = { "from": deploymentDialog.worker.currentAccount, "gas": "0x" + gasCost, "gasPrice": deploymentGasPrice }; var params = replaceParamToken(func.parameters, tr.parameters, ctrAddresses); var encodedParams = clientModel.encodeParams(params, contractFromToken(tr.contractId), tr.functionId); if (tr.contractId === tr.functionId) rpcParams.code = codeModel.contracts[tr.contractId].codeHex + encodedParams.join(""); else - rpcParams.data = func.hash + encodedParams.join(""); + rpcParams.data = "0x" + func.qhash() + encodedParams.join(""); var requests = [{ jsonrpc: "2.0", @@ -214,13 +211,9 @@ function executeTrNextStep(blockIndex, trIndex, state, ctrAddresses, trHashes, c { blockIndex++ if (blockIndex < state.blocks.count) - { executeTr(blockIndex, 0, state, ctrAddresses, trHashes, callBack); - } else - { callBack(); - } } } @@ -298,16 +291,17 @@ function packageDapp(addresses) deploymentDialog.packageStep.packageBase64 = packageRet[1]; deploymentDialog.packageStep.localPackageUrl = packageRet[2] + "?hash=" + packageRet[0]; deploymentDialog.packageStep.lastDeployDate = date - deploymentComplete() + deploymentStepChanged(qsTr("Dapp is Packaged")) } -function registerDapp(url, callback) +function registerDapp(url, gasPrice, callback) { + deploymentGasPrice = gasPrice deploymentStepChanged(qsTr("Registering application on the Ethereum network ...")); checkEthPath(url, false, function (success) { if (!success) return; - deploymentComplete(); + deploymentStepChanged(qsTr("Dapp has been registered. Please wait for verifications.")); if (callback) callback() }); @@ -446,7 +440,7 @@ function continueRegistration(dappUrl, addr, callBack, checkOnly) requests.push({ jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.worker.currentAccount, "gas": "0x" + gasCost, "code": "0x600080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331781556105cd90819061003990396000f3007c010000000000000000000000000000000000000000000000000000000060003504630198489281146100b257806321f8a721146100e45780632dff6941146100ee5780633b3b57de1461010e5780635a3a05bd1461013e5780635fd4b08a146101715780637dd564111461017d57806389a69c0e14610187578063b387ef92146101bb578063b5c645bd146101f4578063be99a98014610270578063c3d014d6146102a8578063d93e7573146102dc57005b73ffffffffffffffffffffffffffffffffffffffff600435166000908152600160205260409020548060005260206000f35b6000808052602081f35b600435600090815260026020819052604090912001548060005260206000f35b600435600090815260026020908152604082205473ffffffffffffffffffffffffffffffffffffffff1680835291f35b600435600090815260026020908152604082206001015473ffffffffffffffffffffffffffffffffffffffff1680835291f35b60008060005260206000f35b6000808052602081f35b60005461030c9060043590602435903373ffffffffffffffffffffffffffffffffffffffff908116911614610569576105c9565b60005473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b600435600090815260026020819052604090912080546001820154919092015473ffffffffffffffffffffffffffffffffffffffff9283169291909116908273ffffffffffffffffffffffffffffffffffffffff166000528173ffffffffffffffffffffffffffffffffffffffff166020528060405260606000f35b600054610312906004359060243590604435903373ffffffffffffffffffffffffffffffffffffffff90811691161461045457610523565b6000546103189060043590602435903373ffffffffffffffffffffffffffffffffffffffff90811691161461052857610565565b60005461031e90600435903373ffffffffffffffffffffffffffffffffffffffff90811691161461032457610451565b60006000f35b60006000f35b60006000f35b60006000f35b60008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091529020548114610361576103e1565b6000818152600260205260408082205473ffffffffffffffffffffffffffffffffffffffff169183917ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85459190a360008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091528120555b600081815260026020819052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168255600182018054909116905590910182905582917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b50565b600083815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001683179055806104bb57827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc60006040a2610522565b73ffffffffffffffffffffffffffffffffffffffff8216837ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a854560006040a373ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090208390555b5b505050565b600082815260026020819052604080832090910183905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b60008281526002602052604080822060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b505056" } ], + params: [ { "from": deploymentDialog.worker.currentAccount, "gasPrice": deploymentGasPrice, "gas": "0x" + gasCost, "code": "0x600080547fffffffffffffffffffffffff000000000000000000000000000000000000000016331781556105cd90819061003990396000f3007c010000000000000000000000000000000000000000000000000000000060003504630198489281146100b257806321f8a721146100e45780632dff6941146100ee5780633b3b57de1461010e5780635a3a05bd1461013e5780635fd4b08a146101715780637dd564111461017d57806389a69c0e14610187578063b387ef92146101bb578063b5c645bd146101f4578063be99a98014610270578063c3d014d6146102a8578063d93e7573146102dc57005b73ffffffffffffffffffffffffffffffffffffffff600435166000908152600160205260409020548060005260206000f35b6000808052602081f35b600435600090815260026020819052604090912001548060005260206000f35b600435600090815260026020908152604082205473ffffffffffffffffffffffffffffffffffffffff1680835291f35b600435600090815260026020908152604082206001015473ffffffffffffffffffffffffffffffffffffffff1680835291f35b60008060005260206000f35b6000808052602081f35b60005461030c9060043590602435903373ffffffffffffffffffffffffffffffffffffffff908116911614610569576105c9565b60005473ffffffffffffffffffffffffffffffffffffffff168073ffffffffffffffffffffffffffffffffffffffff1660005260206000f35b600435600090815260026020819052604090912080546001820154919092015473ffffffffffffffffffffffffffffffffffffffff9283169291909116908273ffffffffffffffffffffffffffffffffffffffff166000528173ffffffffffffffffffffffffffffffffffffffff166020528060405260606000f35b600054610312906004359060243590604435903373ffffffffffffffffffffffffffffffffffffffff90811691161461045457610523565b6000546103189060043590602435903373ffffffffffffffffffffffffffffffffffffffff90811691161461052857610565565b60005461031e90600435903373ffffffffffffffffffffffffffffffffffffffff90811691161461032457610451565b60006000f35b60006000f35b60006000f35b60006000f35b60008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091529020548114610361576103e1565b6000818152600260205260408082205473ffffffffffffffffffffffffffffffffffffffff169183917ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a85459190a360008181526002602090815260408083205473ffffffffffffffffffffffffffffffffffffffff16835260019091528120555b600081815260026020819052604080832080547fffffffffffffffffffffffff00000000000000000000000000000000000000009081168255600182018054909116905590910182905582917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b50565b600083815260026020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001683179055806104bb57827fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc60006040a2610522565b73ffffffffffffffffffffffffffffffffffffffff8216837ff63780e752c6a54a94fc52715dbc5518a3b4c3c2833d301a204226548a2a854560006040a373ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090208390555b5b505050565b600082815260026020819052604080832090910183905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b5050565b60008281526002602052604080822060010180547fffffffffffffffffffffffff0000000000000000000000000000000000000000168417905583917fa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc91a25b505056" } ], id: jsonRpcRequestId++ }); @@ -468,7 +462,7 @@ function continueRegistration(dappUrl, addr, callBack, checkOnly) //setRegister() jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.worker.currentAccount, "gas": "0x" + gasCost, "to": '0x' + addr, "data": "0x89a69c0e" + crLevel + newCtrAddress } ], + params: [ { "from": deploymentDialog.worker.currentAccount, "gasPrice": deploymentGasPrice, "gas": "0x" + gasCost, "to": '0x' + addr, "data": "0x89a69c0e" + crLevel + newCtrAddress } ], id: jsonRpcRequestId++ }); @@ -501,7 +495,7 @@ function reserve(registrar, callBack) //reserve() jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.worker.currentAccount, "gas": "0xfffff", "to": '0x' + registrar, "data": "0x432ced04" + paramTitle } ], + params: [ { "from": deploymentDialog.worker.currentAccount, "gasPrice": deploymentGasPrice, "gas": "0xfffff", "to": '0x' + registrar, "data": "0x432ced04" + paramTitle } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -524,7 +518,7 @@ function registerContentHash(registrar, callBack) //setContent() jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "from": deploymentDialog.worker.currentAccount, "gas": "0x" + gasCost, "to": '0x' + registrar, "data": "0xc3d014d6" + paramTitle + deploymentDialog.packageStep.packageHash } ], + params: [ { "from": deploymentDialog.worker.currentAccount, "gasPrice": deploymentGasPrice, "gas": "0x" + gasCost, "to": '0x' + registrar, "data": "0xc3d014d6" + paramTitle + deploymentDialog.packageStep.packageHash } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { @@ -533,9 +527,10 @@ function registerContentHash(registrar, callBack) }); } -function registerToUrlHint(url, callback) +function registerToUrlHint(url, gasPrice, callback) { console.log("register url " + deploymentDialog.packageStep.packageHash + " " + url) + deploymentGasPrice = gasPrice deploymentStepChanged(qsTr("Registering application Resources...")) urlHintAddress(function(urlHint){ var requests = []; @@ -545,13 +540,13 @@ function registerToUrlHint(url, callback) //urlHint => suggestUrl jsonrpc: "2.0", method: "eth_sendTransaction", - params: [ { "to": '0x' + urlHint, "from": deploymentDialog.worker.currentAccount, "gas": "0x" + gasCost, "data": "0x584e86ad" + deploymentDialog.packageStep.packageHash + paramUrlHttp } ], + params: [ { "to": '0x' + urlHint, "gasPrice": deploymentGasPrice, "from": deploymentDialog.worker.currentAccount, "gas": "0x" + gasCost, "data": "0x584e86ad" + deploymentDialog.packageStep.packageHash + paramUrlHttp } ], id: jsonRpcRequestId++ }); rpcCall(requests, function (httpRequest, response) { projectModel.registerUrlTrHash = JSON.parse(response)[0].result - deploymentComplete(); + deploymentStepChanged(qsTr("Dapp resources has been registered. Please wait for verifications.")); if (callback) callback() }); diff --git a/mix/qml/js/TransactionHelper.js b/mix/qml/js/TransactionHelper.js index 33dadab9d..11cf80b11 100644 --- a/mix/qml/js/TransactionHelper.js +++ b/mix/qml/js/TransactionHelper.js @@ -33,7 +33,8 @@ function rpcCall(requests, callBack, error) { var errorText = qsTr("Unable to initiate request to the live network. Please verify your ethereum node is up.") + qsTr(" Error status: ") + httpRequest.status; console.log(errorText); - error(errorText); + if (error) + error(errorText); } else {