From 3988121e2f1586064dded8d30a83f9f3e0616613 Mon Sep 17 00:00:00 2001 From: Iuri Matias Date: Mon, 23 Dec 2019 19:46:42 -0500 Subject: [PATCH] move dropdown executionContext and udapp related logic to blockchain model --- src/app/tabs/runTab/contractDropdown.js | 9 +- src/app/tabs/runTab/model/blockchain.js | 98 ++++++++++++++++++++++ src/app/tabs/runTab/model/dropdownlogic.js | 83 +----------------- src/app/udapp/run-tab.js | 6 +- 4 files changed, 108 insertions(+), 88 deletions(-) create mode 100644 src/app/tabs/runTab/model/blockchain.js diff --git a/src/app/tabs/runTab/contractDropdown.js b/src/app/tabs/runTab/contractDropdown.js index b6341144ba..fa727bbaed 100644 --- a/src/app/tabs/runTab/contractDropdown.js +++ b/src/app/tabs/runTab/contractDropdown.js @@ -8,7 +8,8 @@ var modalDialog = require('../../ui/modaldialog') var MultiParamManager = require('../../ui/multiParamManager') class ContractDropdownUI { - constructor (dropdownLogic, logCallback, runView) { + constructor (blockchain, dropdownLogic, logCallback, runView) { + this.blockchain = blockchain this.dropdownLogic = dropdownLogic this.logCallback = logCallback this.runView = runView @@ -192,7 +193,7 @@ class ContractDropdownUI { { label: 'Force Send', fn: () => { - this.dropdownLogic.deployContract(selectedContract, args, contractMetadata, compilerContracts, {continueCb, promptCb, statusCb, finalCb}, confirmationCb) + this.blockchain.deployContract(selectedContract, args, contractMetadata, compilerContracts, {continueCb, promptCb, statusCb, finalCb}, confirmationCb) }}, { label: 'Cancel', fn: () => { @@ -200,7 +201,7 @@ class ContractDropdownUI { } }) } - this.dropdownLogic.deployContract(selectedContract, args, contractMetadata, compilerContracts, {continueCb, promptCb, statusCb, finalCb}, confirmationCb) + this.blockchain.deployContract(selectedContract, args, contractMetadata, compilerContracts, {continueCb, promptCb, statusCb, finalCb}, confirmationCb) } getConfirmationCb (modalDialog, confirmDialog) { @@ -209,7 +210,7 @@ class ContractDropdownUI { return continueTxExecution(null) } const amount = this.dropdownLogic.fromWei(tx.value, true, 'ether') - const content = confirmDialog(tx, amount, gasEstimation, null, this.dropdownLogic.determineGasFees(tx), this.dropdownLogic.determineGasPrice) + const content = confirmDialog(tx, amount, gasEstimation, null, this.dropdownLogic.determineGasFees(tx), this.blockchain.determineGasPrice) modalDialog('Confirm transaction', content, { label: 'Confirm', diff --git a/src/app/tabs/runTab/model/blockchain.js b/src/app/tabs/runTab/model/blockchain.js new file mode 100644 index 0000000000..db5643136b --- /dev/null +++ b/src/app/tabs/runTab/model/blockchain.js @@ -0,0 +1,98 @@ +const remixLib = require('remix-lib') +const txFormat = remixLib.execution.txFormat +const txExecution = remixLib.execution.txExecution +const typeConversion = remixLib.execution.typeConversion +const Web3 = require('web3') + +class Blockchain { + + constructor (executionContext, udapp) { + this.executionContext = executionContext + this.udapp = udapp + } + + async deployContract (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) { + const { continueCb, promptCb, statusCb, finalCb } = callbacks + + var constructor = selectedContract.getConstructorInterface() + if (!contractMetadata || (contractMetadata && contractMetadata.autoDeployLib)) { + return txFormat.buildData(selectedContract.name, selectedContract.object, compilerContracts, true, constructor, args, (error, data) => { + if (error) return statusCb(`creation of ${selectedContract.name} errored: ` + error) + + statusCb(`creation of ${selectedContract.name} pending...`) + this.createContract(selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) + }, statusCb, (data, runTxCallback) => { + // called for libraries deployment + this.runTransaction(data, continueCb, promptCb, confirmationCb, runTxCallback) + }) + } + if (Object.keys(selectedContract.bytecodeLinkReferences).length) statusCb(`linking ${JSON.stringify(selectedContract.bytecodeLinkReferences, null, '\t')} using ${JSON.stringify(contractMetadata.linkReferences, null, '\t')}`) + txFormat.encodeConstructorCallAndLinkLibraries(selectedContract.object, args, constructor, contractMetadata.linkReferences, selectedContract.bytecodeLinkReferences, (error, data) => { + if (error) return statusCb(`creation of ${selectedContract.name} errored: ` + error) + + statusCb(`creation of ${selectedContract.name} pending...`) + this.createContract(selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) + }) + } + + runTransaction (data, continueCb, promptCb, confirmationCb, finalCb) { + this.udapp.runTx(data, confirmationCb, continueCb, promptCb, finalCb) + } + + createContract (selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) { + if (data) { + data.contractName = selectedContract.name + data.linkReferences = selectedContract.bytecodeLinkReferences + data.contractABI = selectedContract.abi + } + + this.udapp.createContract(data, confirmationCb, continueCb, promptCb, + (error, txResult) => { + if (error) { + return finalCb(`creation of ${selectedContract.name} errored: ${error}`) + } + var isVM = this.executionContext.isVM() + if (isVM) { + var vmError = txExecution.checkVMError(txResult) + if (vmError.error) { + return finalCb(vmError.message) + } + } + if (txResult.result.status && txResult.result.status === '0x0') { + return finalCb(`creation of ${selectedContract.name} errored: transaction execution failed`) + } + var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress + finalCb(null, selectedContract, address) + } + ) + } + + determineGasPrice (cb) { + this.getGasPrice((error, gasPrice) => { + var warnMessage = ' Please fix this issue before sending any transaction. ' + if (error) { + return cb('Unable to retrieve the current network gas price.' + warnMessage + error) + } + try { + var gasPriceValue = this.fromWei(gasPrice, false, 'gwei') + cb(null, gasPriceValue) + } catch (e) { + cb(warnMessage + e.message, null, false) + } + }) + } + + getGasPrice (cb) { + return this.executionContext.web3().eth.getGasPrice(cb) + } + + fromWei (value, doTypeConversion, unit) { + if (doTypeConversion) { + return Web3.utils.fromWei(typeConversion.toInt(value), unit || 'ether') + } + return Web3.utils.fromWei(value.toString(10), unit || 'ether') + } + +} + +module.exports = Blockchain diff --git a/src/app/tabs/runTab/model/dropdownlogic.js b/src/app/tabs/runTab/model/dropdownlogic.js index 524655b6be..573245d223 100644 --- a/src/app/tabs/runTab/model/dropdownlogic.js +++ b/src/app/tabs/runTab/model/dropdownlogic.js @@ -1,20 +1,16 @@ var ethJSUtil = require('ethereumjs-util') var remixLib = require('remix-lib') var txHelper = remixLib.execution.txHelper -var txFormat = remixLib.execution.txFormat var typeConversion = remixLib.execution.typeConversion -var txExecution = remixLib.execution.txExecution var CompilerAbstract = require('../../../compiler/compiler-abstract') var EventManager = remixLib.EventManager var Web3 = require('web3') class DropdownLogic { - constructor (executionContext, compilersArtefacts, config, editor, udapp, runView) { + constructor (compilersArtefacts, config, editor, runView) { this.compilersArtefacts = compilersArtefacts - this.executionContext = executionContext this.config = config this.editor = editor - this.udapp = udapp this.runView = runView this.event = new EventManager() @@ -115,40 +111,6 @@ class DropdownLogic { return Web3.utils.toBN(gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10), unit || 'gwei'))) } - getGasPrice (cb) { - return this.executionContext.web3().eth.getGasPrice(cb) - } - - // TODO: check if selectedContract and data can be joined - createContract (selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) { - if (data) { - data.contractName = selectedContract.name - data.linkReferences = selectedContract.bytecodeLinkReferences - data.contractABI = selectedContract.abi - } - - this.udapp.createContract(data, confirmationCb, continueCb, promptCb, - (error, txResult) => { - if (error) { - return finalCb(`creation of ${selectedContract.name} errored: ${error}`) - } - var isVM = this.executionContext.isVM() - if (isVM) { - var vmError = txExecution.checkVMError(txResult) - if (vmError.error) { - return finalCb(vmError.message) - } - } - if (txResult.result.status && txResult.result.status === '0x0') { - return finalCb(`creation of ${selectedContract.name} errored: transaction execution failed`) - } - var address = isVM ? txResult.result.createdAddress : txResult.result.contractAddress - finalCb(null, selectedContract, address) - } - ) - } - - // determineGasFees (gasPrice, cb) { determineGasFees (tx) { const determineGasFeesCb = (gasPrice, cb) => { let txFeeText, priceStatus @@ -168,53 +130,10 @@ class DropdownLogic { return determineGasFeesCb } - determineGasPrice (cb) { - this.getGasPrice((error, gasPrice) => { - var warnMessage = ' Please fix this issue before sending any transaction. ' - if (error) { - return cb('Unable to retrieve the current network gas price.' + warnMessage + error) - } - try { - var gasPriceValue = this.fromWei(gasPrice, false, 'gwei') - cb(null, gasPriceValue) - } catch (e) { - cb(warnMessage + e.message, null, false) - } - }) - } - - runTransaction (data, continueCb, promptCb, confirmationCb, finalCb) { - this.udapp.runTx(data, confirmationCb, continueCb, promptCb, finalCb) - } - getCompilerContracts () { return this.compilersArtefacts['__last'].getData().contracts } - async deployContract (selectedContract, args, contractMetadata, compilerContracts, callbacks, confirmationCb) { - const {continueCb, promptCb, statusCb, finalCb} = callbacks - - var constructor = selectedContract.getConstructorInterface() - if (!contractMetadata || (contractMetadata && contractMetadata.autoDeployLib)) { - return txFormat.buildData(selectedContract.name, selectedContract.object, compilerContracts, true, constructor, args, (error, data) => { - if (error) return statusCb(`creation of ${selectedContract.name} errored: ` + error) - - statusCb(`creation of ${selectedContract.name} pending...`) - this.createContract(selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) - }, statusCb, (data, runTxCallback) => { - // called for libraries deployment - this.runTransaction(data, continueCb, promptCb, confirmationCb, runTxCallback) - }) - } - if (Object.keys(selectedContract.bytecodeLinkReferences).length) statusCb(`linking ${JSON.stringify(selectedContract.bytecodeLinkReferences, null, '\t')} using ${JSON.stringify(contractMetadata.linkReferences, null, '\t')}`) - txFormat.encodeConstructorCallAndLinkLibraries(selectedContract.object, args, constructor, contractMetadata.linkReferences, selectedContract.bytecodeLinkReferences, (error, data) => { - if (error) return statusCb(`creation of ${selectedContract.name} errored: ` + error) - - statusCb(`creation of ${selectedContract.name} pending...`) - this.createContract(selectedContract, data, continueCb, promptCb, confirmationCb, finalCb) - }) - } - } module.exports = DropdownLogic diff --git a/src/app/udapp/run-tab.js b/src/app/udapp/run-tab.js index 97b20b8233..a9e33c7184 100644 --- a/src/app/udapp/run-tab.js +++ b/src/app/udapp/run-tab.js @@ -15,6 +15,7 @@ const Recorder = require('../tabs/runTab/model/recorder.js') const RecorderUI = require('../tabs/runTab/recorder.js') const DropdownLogic = require('../tabs/runTab/model/dropdownlogic.js') const ContractDropdownUI = require('../tabs/runTab/contractDropdown.js') +const Blockchain = require('../tabs/runTab/model/blockchain.js') const UniversalDAppUI = require('../ui/universal-dapp-ui') @@ -131,8 +132,9 @@ export class RunTab extends LibraryPlugin { } renderDropdown (udappUI, fileManager, compilersArtefacts, config, editor, udapp, filePanel, logCallback) { - const dropdownLogic = new DropdownLogic(this.executionContext, compilersArtefacts, config, editor, udapp, this) - this.contractDropdownUI = new ContractDropdownUI(dropdownLogic, logCallback, this) + const dropdownLogic = new DropdownLogic(compilersArtefacts, config, editor, this) + const blockchain = new Blockchain(this.executionContext, udapp) + this.contractDropdownUI = new ContractDropdownUI(blockchain, dropdownLogic, logCallback, this) fileManager.events.on('currentFileChanged', this.contractDropdownUI.changeCurrentFile.bind(this.contractDropdownUI))