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 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 contractList.currentIndex = 0 contractList.change() accountsModel.clear() for (var k in worker.accounts) { accountsModel.append(worker.accounts[k]) } if (worker.accounts.length > 0) worker.currentAccount = worker.accounts[0].id if (projectModel.deployBlockNumber) { worker.verifyHashes(projectModel.deploymentTrHashes, function (bn, trLost) { root.updateVerification(bn, trLost) }); } deployedAddresses.refresh() worker.renewCtx() } function updateVerification(blockNumber, trLost) { verificationLabel.text = blockNumber - projectModel.deployBlockNumber if (trLost.length > 0) { verificationLabel.text += "\n" + qsTr("Transactions lost") + "\n" for (var k in trLost) { verificationLabel.text += trLost[k] + "\n" } } } RowLayout { anchors.fill: parent anchors.margins: 10 ColumnLayout { anchors.top: parent.top Layout.preferredWidth: parent.width * 0.40 - 20 Layout.fillHeight: true id: scenarioList Label { Layout.fillWidth: true text: qsTr("Pick Scenario to deploy") } ComboBox { id: contractList Layout.preferredWidth: parent.width - 20 model: projectModel.stateListModel textRole: "title" onCurrentIndexChanged: { if (root.visible) change() } function change() { trListModel.clear() if (currentIndex > -1) { for (var k = 0; k < projectModel.stateListModel.get(currentIndex).blocks.count; k++) { for (var j = 0; j < projectModel.stateListModel.get(currentIndex).blocks.get(k).transactions.count; j++) { trListModel.append(projectModel.stateListModel.get(currentIndex).blocks.get(k).transactions.get(j)); } } for (var k = 0; k < trListModel.count; k++) { trList.itemAt(k).init() } ctrDeployCtrLabel.calculateContractDeployGas(); } } } Rectangle { Layout.fillHeight: true Layout.preferredWidth: parent.width - 20 id: trContainer color: "white" border.color: "#cccccc" border.width: 1 ScrollView { anchors.fill: parent ColumnLayout { spacing: 0 ListModel { id: trListModel } Repeater { id: trList model: trListModel ColumnLayout { Layout.fillWidth: true spacing: 5 Layout.preferredHeight: { if (index > -1) return 20 + trListModel.get(index)["parameters"].count * 20 else return 20 } function init() { paramList.clear() if (trListModel.get(index).parameters) { for (var k in trListModel.get(index).parameters) { paramList.append({ "name": k, "value": trListModel.get(index).parameters[k] }) } } } Label { id: trLabel Layout.preferredHeight: 20 anchors.left: parent.left anchors.top: parent.top anchors.topMargin: 5 anchors.leftMargin: 10 text: { if (index > -1) return trListModel.get(index).label else return "" } } ListModel { id: paramList } Repeater { Layout.preferredHeight: { if (index > -1) return trListModel.get(index)["parameters"].count * 20 else return 0 } model: paramList Label { Layout.preferredHeight: 20 anchors.left: parent.left anchors.leftMargin: 20 text: name + "=" + value font.italic: true } } } } } } } } ColumnLayout { anchors.top: parent.top Layout.preferredHeight: parent.height - 25 ColumnLayout { anchors.top: parent.top Layout.preferredWidth: parent.width * 0.60 Layout.fillHeight: true id: deploymentOption spacing: 8 Label { anchors.left: parent.left anchors.leftMargin: 105 text: qsTr("Deployment options") } ListModel { id: accountsModel } RowLayout { Layout.fillWidth: true Rectangle { width: labelWidth Label { text: qsTr("Account") anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter } } ComboBox { id: accountsList textRole: "id" model: accountsModel Layout.preferredWidth: 235 onCurrentTextChanged: { worker.currentAccount = currentText accountBalance.text = worker.balance(currentText).format() console.log(worker.balance(currentText).format()) } } Label { id: accountBalance } } RowLayout { Layout.fillWidth: true Rectangle { width: labelWidth Label { text: qsTr("Gas Price") anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter } } Ether { id: gasPriceInput displayUnitSelection: true displayFormattedValue: true edit: true } Connections { target: gasPriceInput onValueChanged: { ctrDeployCtrLabel.calculateContractDeployGas() } onAmountChanged: { ctrDeployCtrLabel.setCost() } onUnitChanged: { ctrDeployCtrLabel.setCost() } } Connections { target: worker id: gasPriceLoad property bool loaded: false onGasPriceLoaded: { gasPriceInput.value = QEtherHelper.createEther(worker.gasPriceInt.value(), QEther.Wei) gasPriceLoad.loaded = true ctrDeployCtrLabel.calculateContractDeployGas() } } } RowLayout { id: ctrDeployCtrLabel Layout.fillWidth: true property int cost function calculateContractDeployGas() { if (!root.visible) return; var sce = projectModel.stateListModel.getState(contractList.currentIndex) worker.estimateGas(sce, function(gas) { if (gasPriceLoad.loaded) { root.gas = gas cost = 0 for (var k in gas) { cost += gas[k] } setCost() } }); } function setCost() { var ether = QEtherHelper.createBigInt(cost); var gasTotal = ether.multiply(gasPriceInput.value); gasToUseInput.value = QEtherHelper.createEther(gasTotal.value(), QEther.Wei, parent); } Rectangle { width: labelWidth Label { text: qsTr("Cost Estimate") anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter } } Ether { id: gasToUseInput displayUnitSelection: false displayFormattedValue: true edit: false Layout.preferredWidth: 350 } } RowLayout { id: deployedRow Layout.fillWidth: true Rectangle { 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 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) { 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]}) } } Rectangle { Layout.preferredHeight: 20 Layout.preferredWidth: 235 color: "transparent" Label { id: labelContract width: 112 elide: Text.ElideRight text: index > -1 ? deployedAddrModel.get(index).id : "" } TextField { width: 123 anchors.verticalCenter: parent.verticalCenter anchors.left: labelContract.right text: index > - 1 ? deployedAddrModel.get(index).value : "" } } } } } 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 maximumLineCount: 20 } } } Rectangle { Layout.preferredWidth: parent.width Layout.alignment: Qt.BottomEdge Button { anchors.right: parent.right text: qsTr("Deploy Contracts") onClicked: { projectModel.deployedScenarioIndex = contractList.currentIndex NetworkDeploymentCode.deployContracts(root.gas, function(addresses, trHashes) { projectModel.deploymentTrHashes = trHashes worker.verifyHashes(trHashes, function (nb, trLost) { projectModel.deployBlockNumber = nb projectModel.saveProject() root.updateVerification(nb, trLost) }) projectModel.deploymentAddresses = addresses projectModel.saveProject() deployedAddresses.refresh() }); } } } } } }