diff --git a/src/app.js b/src/app.js
index 5dae940db5..6df7b03935 100644
--- a/src/app.js
+++ b/src/app.js
@@ -23,6 +23,8 @@ var toolTip = require('./app/ui/tooltip')
var CompilerMetadata = require('./app/files/compiler-metadata')
var CompilerImport = require('./app/compiler/compiler-imports')
+var executionContext = remixLib.execution.executionContext
+
const PluginManagerComponent = require('./app/components/plugin-manager-component')
const CompilersArtefacts = require('./app/compiler/compiler-artefacts')
@@ -222,15 +224,15 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
const fileManager = new FileManager(editor)
registry.put({api: fileManager, name: 'filemanager'})
// ----------------- compilation metadata generation servive ----------------------------
- const compilerMetadataGenerator = new CompilerMetadata(fileManager, registry.get('config').api)
+ const compilerMetadataGenerator = new CompilerMetadata(executionContext, fileManager, registry.get('config').api)
// ----------------- compilation result service (can keep track of compilation results) ----------------------------
const compilersArtefacts = new CompilersArtefacts() // store all the compilation results (key represent a compiler name)
registry.put({api: compilersArtefacts, name: 'compilersartefacts'})
// ----------------- universal dapp: run transaction, listen on transactions, decode events
- const udapp = new UniversalDApp(registry.get('config').api)
- const {eventsDecoder, txlistener} = makeUdapp(udapp, compilersArtefacts, (domEl) => mainview.getTerminal().logHtml(domEl))
+ const udapp = new UniversalDApp(registry.get('config').api, executionContext)
+ const {eventsDecoder, txlistener} = makeUdapp(udapp, executionContext, compilersArtefacts, (domEl) => mainview.getTerminal().logHtml(domEl))
// ----------------- network service (resolve network id / name) ----------------------------
- const networkModule = new NetworkModule()
+ const networkModule = new NetworkModule(executionContext)
// ----------------- convert offset to line/column service ----------------------------
var offsetToLineColumnConverter = new OffsetToLineColumnConverter()
registry.put({api: offsetToLineColumnConverter, name: 'offsettolinecolumnconverter'})
@@ -248,7 +250,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
// LAYOUT & SYSTEM VIEWS
const appPanel = new MainPanel()
- const mainview = new MainView(editor, appPanel, fileManager, appManager, txlistener, eventsDecoder)
+ const mainview = new MainView(editor, appPanel, fileManager, appManager, txlistener, eventsDecoder, executionContext)
registry.put({ api: mainview, name: 'mainview' })
appManager.register([
@@ -293,6 +295,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
)
const run = new RunTab(
udapp,
+ executionContext,
registry.get('config').api,
registry.get('filemanager').api,
registry.get('editor').api,
@@ -302,7 +305,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
mainview
)
const analysis = new AnalysisTab(registry)
- const debug = new DebuggerTab()
+ const debug = new DebuggerTab(executionContext)
const test = new TestTab(
registry.get('filemanager').api,
filePanel,
diff --git a/src/app/files/compiler-metadata.js b/src/app/files/compiler-metadata.js
index 69974afc58..1485455049 100644
--- a/src/app/files/compiler-metadata.js
+++ b/src/app/files/compiler-metadata.js
@@ -1,5 +1,4 @@
'use strict'
-var executionContext = require('../../execution-context')
var CompilerAbstract = require('../compiler/compiler-abstract')
import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../package.json'
@@ -12,9 +11,10 @@ const profile = {
}
class CompilerMetadata extends Plugin {
- constructor (fileManager, config) {
+ constructor (executionContext, fileManager, config) {
super(profile)
var self = this
+ self.executionContext = executionContext
self.fileManager = fileManager
self.config = config
self.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'görli:5', 'Custom']
@@ -97,7 +97,7 @@ class CompilerMetadata extends Plugin {
var provider = self.fileManager.currentFileProvider()
var path = self.fileManager.currentPath()
if (provider && path) {
- executionContext.detectNetwork((err, { id, name } = {}) => {
+ self.executionContext.detectNetwork((err, { id, name } = {}) => {
if (err) {
console.log(err)
} else {
diff --git a/src/app/panels/main-view.js b/src/app/panels/main-view.js
index 8437b7a41e..6d8f1bde65 100644
--- a/src/app/panels/main-view.js
+++ b/src/app/panels/main-view.js
@@ -20,7 +20,7 @@ var css = csjs`
`
export class MainView {
- constructor (editor, mainPanel, fileManager, appManager, txListener, eventsDecoder) {
+ constructor (editor, mainPanel, fileManager, appManager, txListener, eventsDecoder, executionContext) {
var self = this
self.event = new EventManager()
self._view = {}
@@ -31,6 +31,7 @@ export class MainView {
self.mainPanel = mainPanel
self.txListener = txListener
self.eventsDecoder = eventsDecoder
+ self.executionContext = executionContext
this.appManager = appManager
this.init()
}
@@ -99,7 +100,8 @@ export class MainView {
self._components.terminal = new Terminal({
appManager: this.appManager,
eventsDecoder: this.eventsDecoder,
- txListener: this.txListener
+ txListener: this.txListener,
+ executionContext: this.executionContext
},
{
getPosition: (event) => {
diff --git a/src/app/panels/terminal.js b/src/app/panels/terminal.js
index ade3113339..ea9d103cc6 100644
--- a/src/app/panels/terminal.js
+++ b/src/app/panels/terminal.js
@@ -10,7 +10,6 @@ var Web3 = require('web3')
var swarmgw = require('swarmgw')()
var CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI')
-var executionContext = require('../../execution-context')
var AutoCompletePopup = require('../ui/auto-complete-popup')
var TxLogger = require('../../app/ui/txLogger')
@@ -42,6 +41,7 @@ class Terminal extends Plugin {
super(profile)
var self = this
self.event = new EventManager()
+ self.executionContext = opts.executionContext
self._api = api
self._opts = opts
self.data = {
@@ -52,7 +52,7 @@ class Terminal extends Plugin {
}
self._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null }
self._components = {}
- self._components.cmdInterpreter = new CommandInterpreterAPI(this)
+ self._components.cmdInterpreter = new CommandInterpreterAPI(this, null, self.executionContext)
self._components.autoCompletePopup = new AutoCompletePopup(self._opts)
self._components.autoCompletePopup.event.register('handleSelect', function (input) {
let textList = self._view.input.innerText.split(' ')
@@ -437,7 +437,7 @@ class Terminal extends Plugin {
self._shell('remix.help()', self.commands, () => {})
self.commands.html(intro)
- self._components.txLogger = new TxLogger(self._opts.eventsDecoder, self._opts.txListener, this)
+ self._components.txLogger = new TxLogger(self._opts.eventsDecoder, self._opts.txListener, this, self.executionContext)
self._components.txLogger.event.register('debuggingRequested', (hash) => {
// TODO should probably be in the run module
if (!self._opts.appManager.isActive('debugger')) self._opts.appManager.activateOne('debugger')
@@ -668,7 +668,7 @@ class Terminal extends Plugin {
return done(null, 'This type of command has been deprecated and is not functionning anymore. Please run remix.help() to list available commands.')
}
var self = this
- var context = domTerminalFeatures(self, scopedCommands)
+ var context = domTerminalFeatures(self, scopedCommands, self.executionContext)
try {
var cmds = vm.createContext(Object.assign(self._jsSandboxContext, context, self._jsSandboxRegistered))
var result = vm.runInContext(script, cmds)
@@ -680,7 +680,7 @@ class Terminal extends Plugin {
}
}
-function domTerminalFeatures (self, scopedCommands) {
+function domTerminalFeatures (self, scopedCommands, executionContext) {
return {
swarmgw,
ethers,
diff --git a/src/app/tabs/debugger-tab.js b/src/app/tabs/debugger-tab.js
index 4d091524b0..d86db9aef5 100644
--- a/src/app/tabs/debugger-tab.js
+++ b/src/app/tabs/debugger-tab.js
@@ -21,9 +21,10 @@ const profile = {
class DebuggerTab extends ViewPlugin {
- constructor () {
+ constructor (executionContext) {
super(profile)
this.el = null
+ this.executionContext = executionContext
}
render () {
@@ -33,7 +34,7 @@ class DebuggerTab extends ViewPlugin {
Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails.
More info:
eip-170
@@ -184,7 +193,7 @@ class ContractDropdownUI {
{
label: 'Force Send',
fn: () => {
- this.dropdownLogic.forceSend(selectedContract, args, continueCb, promptCb, modalDialog, confirmDialog, statusCb, finalCb)
+ this.blockchain.deployContract(selectedContract, args, contractMetadata, compilerContracts, {continueCb, promptCb, statusCb, finalCb}, confirmationCb)
}}, {
label: 'Cancel',
fn: () => {
@@ -192,7 +201,38 @@ class ContractDropdownUI {
}
})
}
- this.dropdownLogic.forceSend(selectedContract, args, continueCb, promptCb, modalDialog, confirmDialog, statusCb, finalCb)
+ this.blockchain.deployContract(selectedContract, args, contractMetadata, compilerContracts, {continueCb, promptCb, statusCb, finalCb}, confirmationCb)
+ }
+
+ getConfirmationCb (modalDialog, confirmDialog) {
+ const confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => {
+ if (network.name !== 'Main') {
+ return continueTxExecution(null)
+ }
+ const amount = this.dropdownLogic.fromWei(tx.value, true, 'ether')
+ const content = confirmDialog(tx, amount, gasEstimation, null, this.dropdownLogic.determineGasFees(tx), this.blockchain.determineGasPrice)
+
+ modalDialog('Confirm transaction', content,
+ { label: 'Confirm',
+ fn: () => {
+ this.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked)
+ // TODO: check if this is check is still valid given the refactor
+ if (!content.gasPriceStatus) {
+ cancelCb('Given gas price is not correct')
+ } else {
+ var gasPrice = this.dropdownLogic.toWei(content.querySelector('#gasprice').value, 'gwei')
+ continueTxExecution(gasPrice)
+ }
+ }}, {
+ label: 'Cancel',
+ fn: () => {
+ return cancelCb('Transaction canceled by user.')
+ }
+ }
+ )
+ }
+
+ return confirmationCb
}
loadFromAddress () {
@@ -215,7 +255,6 @@ class ContractDropdownUI {
}
)
}
-
}
module.exports = ContractDropdownUI
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 a5c603d6fe..573245d223 100644
--- a/src/app/tabs/runTab/model/dropdownlogic.js
+++ b/src/app/tabs/runTab/model/dropdownlogic.js
@@ -1,30 +1,21 @@
var ethJSUtil = require('ethereumjs-util')
var remixLib = require('remix-lib')
var txHelper = remixLib.execution.txHelper
-var txFormat = remixLib.execution.txFormat
-var executionContext = remixLib.execution.executionContext
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 (fileManager, compilersArtefacts, config, editor, udapp, filePanel, runView) {
+ constructor (compilersArtefacts, config, editor, runView) {
this.compilersArtefacts = compilersArtefacts
this.config = config
this.editor = editor
- this.udapp = udapp
this.runView = runView
- this.filePanel = filePanel
this.event = new EventManager()
this.listenToCompilationEvents()
-
- fileManager.events.on('currentFileChanged', (currentFile) => {
- this.event.trigger('currentFileChanged', [currentFile])
- })
}
// TODO: can be moved up; the event in contractDropdown will have to refactored a method instead
@@ -120,185 +111,27 @@ class DropdownLogic {
return Web3.utils.toBN(gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10), unit || 'gwei')))
}
- getGasPrice (cb) {
- return executionContext.web3().eth.getGasPrice(cb)
- }
-
- isVM () {
- return executionContext.isVM()
- }
-
- // TODO: check if selectedContract and data can be joined
- createContract (selectedContract, data, continueCb, promptCb, modalDialog, confirmDialog, finalCb) {
- if (data) {
- data.contractName = selectedContract.name
- data.linkReferences = selectedContract.bytecodeLinkReferences
- data.contractABI = selectedContract.abi
- }
-
- var confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => {
- if (network.name !== 'Main') {
- return continueTxExecution(null)
+ determineGasFees (tx) {
+ const determineGasFeesCb = (gasPrice, cb) => {
+ let txFeeText, priceStatus
+ // TODO: this try catch feels like an anti pattern, can/should be
+ // removed, but for now keeping the original logic
+ try {
+ var fee = this.calculateFee(tx.gas, gasPrice)
+ txFeeText = ' ' + this.fromWei(fee, false, 'ether') + ' Ether'
+ priceStatus = true
+ } catch (e) {
+ txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
+ priceStatus = false
}
- var amount = Web3.utils.fromWei(typeConversion.toInt(tx.value), 'ether')
-
- // TODO: there is still a UI dependency to remove here, it's still too coupled at this point to remove easily
- var content = confirmDialog(tx, amount, gasEstimation, this.recorder,
- (gasPrice, cb) => {
- let txFeeText, priceStatus
- // TODO: this try catch feels like an anti pattern, can/should be
- // removed, but for now keeping the original logic
- try {
- var fee = Web3.utils.toBN(tx.gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10), 'gwei')))
- txFeeText = ' ' + Web3.utils.fromWei(fee.toString(10), 'ether') + ' Ether'
- priceStatus = true
- } catch (e) {
- txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
- priceStatus = false
- }
- cb(txFeeText, priceStatus)
- },
- (cb) => {
- executionContext.web3().eth.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 = Web3.utils.fromWei(gasPrice.toString(10), 'gwei')
- cb(null, gasPriceValue)
- } catch (e) {
- cb(warnMessage + e.message, null, false)
- }
- })
- }
- )
- modalDialog('Confirm transaction', content,
- { label: 'Confirm',
- fn: () => {
- this.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked)
- // TODO: check if this is check is still valid given the refactor
- if (!content.gasPriceStatus) {
- cancelCb('Given gas price is not correct')
- } else {
- var gasPrice = Web3.utils.toWei(content.querySelector('#gasprice').value, 'gwei')
- continueTxExecution(gasPrice)
- }
- }}, {
- label: 'Cancel',
- fn: () => {
- return cancelCb('Transaction canceled by user.')
- }
- })
+ cb(txFeeText, priceStatus)
}
- this.udapp.createContract(data, confirmationCb, continueCb, promptCb,
- (error, txResult) => {
- if (error) {
- return finalCb(`creation of ${selectedContract.name} errored: ${error}`)
- }
- var isVM = 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)
- }
- )
- }
-
- runTransaction (data, continueCb, promptCb, modalDialog, confirmDialog, finalCb) {
- var confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => {
- if (network.name !== 'Main') {
- return continueTxExecution(null)
- }
- var amount = this.fromWei(tx.value, true, 'ether')
- var content = confirmDialog(tx, amount, gasEstimation, null,
- (gasPrice, cb) => {
- let txFeeText, priceStatus
- // TODO: this try catch feels like an anti pattern, can/should be
- // removed, but for now keeping the original logic
- try {
- var fee = this.calculateFee(tx.gas, gasPrice)
- txFeeText = ' ' + this.fromWei(fee, false, 'ether') + ' Ether'
- priceStatus = true
- } catch (e) {
- txFeeText = ' Please fix this issue before sending any transaction. ' + e.message
- priceStatus = false
- }
- cb(txFeeText, priceStatus)
- },
- (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)
- }
- })
- }
- )
- modalDialog('Confirm transaction', content,
- { label: 'Confirm',
- fn: () => {
- this.config.setUnpersistedProperty('doNotShowTransactionConfirmationAgain', content.querySelector('input#confirmsetting').checked)
- // TODO: check if this is check is still valid given the refactor
- if (!content.gasPriceStatus) {
- cancelCb('Given gas price is not correct')
- } else {
- var gasPrice = this.toWei(content.querySelector('#gasprice').value, 'gwei')
- continueTxExecution(gasPrice)
- }
- }}, {
- label: 'Cancel',
- fn: () => {
- return cancelCb('Transaction canceled by user.')
- }
- }
- )
- }
-
- this.udapp.runTx(data, confirmationCb, continueCb, promptCb, finalCb)
+ return determineGasFeesCb
}
- async forceSend (selectedContract, args, continueCb, promptCb, modalDialog, confirmDialog, statusCb, cb) {
- var constructor = selectedContract.getConstructorInterface()
- // TODO: deployMetadataOf can be moved here
- let contractMetadata
- try {
- contractMetadata = await this.runView.call('compilerMetadata', 'deployMetadataOf', selectedContract.name)
- } catch (error) {
- return statusCb(`creation of ${selectedContract.name} errored: ` + error)
- }
- if (!contractMetadata || (contractMetadata && contractMetadata.autoDeployLib)) {
- return txFormat.buildData(selectedContract.name, selectedContract.object, this.compilersArtefacts['__last'].getData().contracts, 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, modalDialog, confirmDialog, cb)
- }, statusCb, (data, runTxCallback) => {
- // called for libraries deployment
- this.runTransaction(data, continueCb, promptCb, modalDialog, confirmDialog, 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, modalDialog, confirmDialog, cb)
- })
+ getCompilerContracts () {
+ return this.compilersArtefacts['__last'].getData().contracts
}
}
diff --git a/src/app/tabs/runTab/model/recorder.js b/src/app/tabs/runTab/model/recorder.js
index c6c68f4d94..b25070aac2 100644
--- a/src/app/tabs/runTab/model/recorder.js
+++ b/src/app/tabs/runTab/model/recorder.js
@@ -2,7 +2,6 @@ var async = require('async')
var ethutil = require('ethereumjs-util')
var remixLib = require('remix-lib')
var EventManager = remixLib.EventManager
-var executionContext = remixLib.execution.executionContext
var format = remixLib.execution.txFormat
var txHelper = remixLib.execution.txHelper
var typeConversion = remixLib.execution.typeConversion
@@ -15,9 +14,10 @@ var Web3 = require('web3')
*
*/
class Recorder {
- constructor (udapp, fileManager, config) {
+ constructor (executionContext, udapp, fileManager, config) {
var self = this
self.event = new EventManager()
+ self.executionContext = executionContext
self.data = { _listen: true, _replay: false, journal: [], _createdContracts: {}, _createdContractsReverse: {}, _usedAccounts: {}, _abis: {}, _contractABIReferences: {}, _linkReferences: {} }
this.udapp = udapp
this.fileManager = fileManager
@@ -74,7 +74,7 @@ class Recorder {
if (error) return console.log(error)
if (call) return
- const rawAddress = executionContext.isVM() ? txResult.result.createdAddress : txResult.result.contractAddress
+ const rawAddress = this.executionContext.isVM() ? txResult.result.createdAddress : txResult.result.contractAddress
if (!rawAddress) return // not a contract creation
const stringAddress = this.addressToString(rawAddress)
const address = ethutil.toChecksumAddress(stringAddress)
@@ -82,7 +82,7 @@ class Recorder {
this.data._createdContracts[address] = timestamp
this.data._createdContractsReverse[timestamp] = address
})
- executionContext.event.register('contextChanged', this.clearAll.bind(this))
+ this.executionContext.event.register('contextChanged', this.clearAll.bind(this))
this.event.register('newTxRecorded', (count) => {
this.event.trigger('recorderCountChange', [count])
})
@@ -261,7 +261,7 @@ class Recorder {
console.error(err)
logCallBack(err + '. Execution failed at ' + index)
} else {
- const rawAddress = executionContext.isVM() ? txResult.result.createdAddress : txResult.result.contractAddress
+ const rawAddress = self.executionContext.isVM() ? txResult.result.createdAddress : txResult.result.contractAddress
if (rawAddress) {
const stringAddress = self.addressToString(rawAddress)
const address = ethutil.toChecksumAddress(stringAddress)
@@ -335,7 +335,7 @@ class Recorder {
cb(txFeeText, priceStatus)
},
(cb) => {
- executionContext.web3().eth.getGasPrice((error, gasPrice) => {
+ this.executionContext.web3().eth.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)
diff --git a/src/app/tabs/runTab/model/settings.js b/src/app/tabs/runTab/model/settings.js
index 3d514487d2..e126e583f0 100644
--- a/src/app/tabs/runTab/model/settings.js
+++ b/src/app/tabs/runTab/model/settings.js
@@ -4,11 +4,11 @@ var remixLib = require('remix-lib')
var Web3 = require('web3')
const addTooltip = require('../../../ui/tooltip')
var EventManager = remixLib.EventManager
-var executionContext = remixLib.execution.executionContext
class Settings {
- constructor (udapp) {
+ constructor (executionContext, udapp) {
+ this.executionContext = executionContext
this.udapp = udapp
this.event = new EventManager()
@@ -16,15 +16,15 @@ class Settings {
this.event.trigger('transactionExecuted', [error, from, to, data, lookupOnly, txResult])
})
- executionContext.event.register('contextChanged', (context, silent) => {
+ this.executionContext.event.register('contextChanged', (context, silent) => {
this.event.trigger('contextChanged', [context, silent])
})
- executionContext.event.register('addProvider', (network) => {
+ this.executionContext.event.register('addProvider', (network) => {
this.event.trigger('addProvider', [network])
})
- executionContext.event.register('removeProvider', (name) => {
+ this.executionContext.event.register('removeProvider', (name) => {
this.event.trigger('removeProvider', [name])
})
@@ -32,15 +32,15 @@ class Settings {
}
changeExecutionContext (context, confirmCb, infoCb, cb) {
- return executionContext.executionContextChange(context, null, confirmCb, infoCb, cb)
+ return this.executionContext.executionContextChange(context, null, confirmCb, infoCb, cb)
}
setProviderFromEndpoint (target, context, cb) {
- return executionContext.setProviderFromEndpoint(target, context, cb)
+ return this.executionContext.setProviderFromEndpoint(target, context, cb)
}
getProvider () {
- return executionContext.getProvider()
+ return this.executionContext.getProvider()
}
getAccountBalanceForAddress (address, cb) {
@@ -50,7 +50,7 @@ class Settings {
updateNetwork (cb) {
this.networkcallid++
((callid) => {
- executionContext.detectNetwork((err, { id, name } = {}) => {
+ this.executionContext.detectNetwork((err, { id, name } = {}) => {
if (this.networkcallid > callid) return
this.networkcallid++
if (err) {
@@ -70,18 +70,18 @@ class Settings {
}
isWeb3Provider () {
- var isVM = executionContext.isVM()
- var isInjected = executionContext.getProvider() === 'injected'
+ var isVM = this.executionContext.isVM()
+ var isInjected = this.executionContext.getProvider() === 'injected'
return (!isVM && !isInjected)
}
isInjectedWeb3 () {
- return executionContext.getProvider() === 'injected'
+ return this.executionContext.getProvider() === 'injected'
}
signMessage (message, account, passphrase, cb) {
- var isVM = executionContext.isVM()
- var isInjected = executionContext.getProvider() === 'injected'
+ var isVM = this.executionContext.isVM()
+ var isInjected = this.executionContext.getProvider() === 'injected'
if (isVM) {
const personalMsg = ethJSUtil.hashPersonalMessage(Buffer.from(message))
@@ -99,7 +99,7 @@ class Settings {
const hashedMsg = Web3.utils.sha3(message)
try {
addTooltip('Please check your provider to approve')
- executionContext.web3().eth.sign(account, hashedMsg, (error, signedData) => {
+ this.executionContext.web3().eth.sign(account, hashedMsg, (error, signedData) => {
cb(error.message, hashedMsg, signedData)
})
} catch (e) {
@@ -110,7 +110,7 @@ class Settings {
const hashedMsg = Web3.utils.sha3(message)
try {
- var personal = new Personal(executionContext.web3().currentProvider)
+ var personal = new Personal(this.executionContext.web3().currentProvider)
personal.sign(hashedMsg, account, passphrase, (error, signedData) => {
cb(error.message, hashedMsg, signedData)
})
diff --git a/src/app/tabs/runTab/settings.js b/src/app/tabs/runTab/settings.js
index 61f657fbe1..76032c4650 100644
--- a/src/app/tabs/runTab/settings.js
+++ b/src/app/tabs/runTab/settings.js
@@ -320,7 +320,7 @@ class SettingsUI {
this.netUI.innerHTML = 'can\'t detect network '
return
}
- let network = this._components.networkModule.getNetworkProvider
+ let network = this._components.networkModule.getNetworkProvider.bind(this._components.networkModule)
this.netUI.innerHTML = (network() !== 'vm') ? `${name} (${id || '-'}) network` : ''
})
this.fillAccountsList()
diff --git a/src/app/udapp/make-udapp.js b/src/app/udapp/make-udapp.js
index 202315228d..04f32fef74 100644
--- a/src/app/udapp/make-udapp.js
+++ b/src/app/udapp/make-udapp.js
@@ -1,12 +1,11 @@
var registry = require('../../global/registry')
var remixLib = require('remix-lib')
var yo = require('yo-yo')
-var executionContext = remixLib.execution.executionContext
var Txlistener = remixLib.execution.txListener
var EventsDecoder = remixLib.execution.EventsDecoder
var TransactionReceiptResolver = require('../../lib/transactionReceiptResolver')
-export function makeUdapp (udapp, compilersArtefacts, logHtmlCallback) {
+export function makeUdapp (udapp, executionContext, compilersArtefacts, logHtmlCallback) {
// ----------------- UniversalDApp -----------------
// TODO: to remove when possible
udapp.event.register('transactionBroadcasted', (txhash, networkName) => {
@@ -15,7 +14,7 @@ export function makeUdapp (udapp, compilersArtefacts, logHtmlCallback) {
})
// ----------------- Tx listener -----------------
- const transactionReceiptResolver = new TransactionReceiptResolver()
+ const transactionReceiptResolver = new TransactionReceiptResolver(executionContext)
const txlistener = new Txlistener({
api: {
@@ -29,7 +28,7 @@ export function makeUdapp (udapp, compilersArtefacts, logHtmlCallback) {
},
event: {
udapp: udapp.event
- }})
+ }}, executionContext)
registry.put({api: txlistener, name: 'txlistener'})
udapp.startListening(txlistener)
diff --git a/src/app/udapp/run-tab.js b/src/app/udapp/run-tab.js
index 01f9b3e322..a9e33c7184 100644
--- a/src/app/udapp/run-tab.js
+++ b/src/app/udapp/run-tab.js
@@ -15,9 +15,9 @@ 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')
-const executionContext = require('../../execution-context')
const profile = {
name: 'udapp',
@@ -35,11 +35,12 @@ const profile = {
export class RunTab extends LibraryPlugin {
- constructor (udapp, config, fileManager, editor, filePanel, compilersArtefacts, networkModule, mainView) {
+ constructor (udapp, executionContext, config, fileManager, editor, filePanel, compilersArtefacts, networkModule, mainView) {
super(udapp, profile)
this.event = new EventManager()
this.config = config
this.udapp = udapp
+ this.executionContext = executionContext
this.fileManager = fileManager
this.editor = editor
this.logCallback = (msg) => { mainView.getTerminal().logHtml(msg) }
@@ -49,7 +50,7 @@ export class RunTab extends LibraryPlugin {
}
onActivationInternal () {
- this.udappUI = new UniversalDAppUI(this.udapp, this.logCallback)
+ this.udappUI = new UniversalDAppUI(this.udapp, this.logCallback, this.executionContext)
this.udapp.resetAPI({
getAddress: (cb) => {
cb(null, $('#txorigin').val())
@@ -122,7 +123,7 @@ export class RunTab extends LibraryPlugin {
}
renderSettings (udapp) {
- var settings = new Settings(udapp)
+ var settings = new Settings(this.executionContext, udapp)
this.settingsUI = new SettingsUI(settings, this.networkModule)
this.settingsUI.event.register('clearInstance', () => {
@@ -131,8 +132,11 @@ export class RunTab extends LibraryPlugin {
}
renderDropdown (udappUI, fileManager, compilersArtefacts, config, editor, udapp, filePanel, logCallback) {
- const dropdownLogic = new DropdownLogic(fileManager, compilersArtefacts, config, editor, udapp, filePanel, this)
- this.contractDropdownUI = new ContractDropdownUI(dropdownLogic, logCallback)
+ 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))
this.contractDropdownUI.event.register('clearInstance', () => {
const noInstancesText = this.noInstancesText
@@ -149,7 +153,7 @@ export class RunTab extends LibraryPlugin {
renderRecorder (udapp, udappUI, fileManager, config, logCallback) {
this.recorderCount = yo`
0`
- const recorder = new Recorder(udapp, fileManager, config)
+ const recorder = new Recorder(this.executionContext, udapp, fileManager, config)
recorder.event.register('recorderCountChange', (count) => {
this.recorderCount.innerText = count
})
@@ -200,9 +204,9 @@ export class RunTab extends LibraryPlugin {
render () {
this.onActivationInternal()
- executionContext.init(this.config)
- executionContext.stopListenOnLastBlock()
- executionContext.listenOnLastBlock()
+ this.executionContext.init(this.config)
+ this.executionContext.stopListenOnLastBlock()
+ this.executionContext.listenOnLastBlock()
this.udapp.resetEnvironment()
this.renderInstanceContainer()
this.renderSettings(this.udapp)
diff --git a/src/app/ui/txLogger.js b/src/app/ui/txLogger.js
index 0d694b2295..010a277715 100644
--- a/src/app/ui/txLogger.js
+++ b/src/app/ui/txLogger.js
@@ -8,7 +8,6 @@ var remixLib = require('remix-lib')
var EventManager = require('../../lib/events')
var helper = require('../../lib/helper')
-var executionContext = require('../../execution-context')
var modalDialog = require('./modal-dialog-custom')
var typeConversion = remixLib.execution.typeConversion
var globlalRegistry = require('../../global/registry')
@@ -117,7 +116,7 @@ var css = csjs`
*
*/
class TxLogger {
- constructor (eventsDecoder, txListener, terminal) {
+ constructor (eventsDecoder, txListener, terminal, executionContext) {
this.event = new EventManager()
this.seen = {}
function filterTx (value, query) {
@@ -140,7 +139,7 @@ class TxLogger {
if (data.tx.isCall) {
el = renderCall(this, data)
} else {
- el = renderKnownTransaction(this, data)
+ el = renderKnownTransaction(this, data, executionContext)
}
this.seen[data.tx.hash] = el
append(el)
@@ -149,7 +148,7 @@ class TxLogger {
this.logUnknownTX = this.terminal.registerCommand('unknownTransaction', (args, cmds, append) => {
// triggered for transaction AND call
var data = args[0]
- var el = renderUnknownTransaction(this, data)
+ var el = renderUnknownTransaction(this, data, executionContext)
append(el)
}, { activate: false, filterFn: filterTx })
@@ -205,7 +204,7 @@ function log (self, tx, receipt) {
}
}
-function renderKnownTransaction (self, data) {
+function renderKnownTransaction (self, data, executionContext) {
var from = data.tx.from
var to = data.resolvedData.contractName + '.' + data.resolvedData.fn
var obj = {from, to}
@@ -214,7 +213,7 @@ function renderKnownTransaction (self, data) {
txDetails(e, tx, data, obj)}>
${checkTxStatus(data.receipt, txType)}
- ${context(self, {from, to, data})}
+ ${context(self, {from, to, data}, executionContext)}
@@ -251,7 +250,7 @@ function renderCall (self, data) {
return tx
}
-function renderUnknownTransaction (self, data) {
+function renderUnknownTransaction (self, data, executionContext) {
var from = data.tx.from
var to = data.tx.to
var obj = {from, to}
@@ -260,7 +259,7 @@ function renderUnknownTransaction (self, data) {
txDetails(e, tx, data, obj)}>
${checkTxStatus(data.receipt || data.tx, txType)}
- ${context(self, {from, to, data})}
+ ${context(self, {from, to, data}, executionContext)}
@@ -291,7 +290,7 @@ function checkTxStatus (tx, type) {
}
}
-function context (self, opts) {
+function context (self, opts, executionContext) {
var data = opts.data || ''
var from = opts.from ? helper.shortenHexData(opts.from) : ''
var to = opts.to
diff --git a/src/app/ui/universal-dapp-ui.js b/src/app/ui/universal-dapp-ui.js
index cc9a8c3e44..a02e616280 100644
--- a/src/app/ui/universal-dapp-ui.js
+++ b/src/app/ui/universal-dapp-ui.js
@@ -15,17 +15,16 @@ var typeConversion = remixLib.execution.typeConversion
var txExecution = remixLib.execution.txExecution
var txFormat = remixLib.execution.txFormat
-var executionContext = require('../../execution-context')
-
var confirmDialog = require('./confirmDialog')
var modalCustom = require('./modal-dialog-custom')
var modalDialog = require('./modaldialog')
var TreeView = require('./TreeView')
-function UniversalDAppUI (udapp, logCallback) {
+function UniversalDAppUI (udapp, logCallback, executionContext) {
this.udapp = udapp
this.logCallback = logCallback
this.compilerData = {contractsDetails: {}}
+ this.executionContext = executionContext
}
function decodeResponseToTreeView (response, fnabi) {
@@ -181,7 +180,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) {
cb(txFeeText, priceStatus)
},
(cb) => {
- executionContext.web3().eth.getGasPrice((error, gasPrice) => {
+ self.executionContext.web3().eth.getGasPrice((error, gasPrice) => {
const warnMessage = ' Please fix this issue before sending any transaction. '
if (error) {
return cb('Unable to retrieve the current network gas price.' + warnMessage + error)
@@ -263,7 +262,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) {
if (args.funABI.type === 'fallback') data.dataHex = value
self.udapp.callFunction(args.address, data, args.funABI, confirmationCb, continueCb, promptCb, (error, txResult) => {
if (!error) {
- var isVM = executionContext.isVM()
+ var isVM = self.executionContext.isVM()
if (isVM) {
var vmError = txExecution.checkVMError(txResult)
if (vmError.error) {
@@ -272,7 +271,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) {
}
}
if (lookupOnly) {
- const decoded = decodeResponseToTreeView(executionContext.isVM() ? txResult.result.execResult.returnValue : ethJSUtil.toBuffer(txResult.result), args.funABI)
+ const decoded = decodeResponseToTreeView(self.executionContext.isVM() ? txResult.result.execResult.returnValue : ethJSUtil.toBuffer(txResult.result), args.funABI)
outputCb(decoded)
}
} else {
diff --git a/src/execution-context.js b/src/execution-context.js
deleted file mode 100644
index eafad31e9d..0000000000
--- a/src/execution-context.js
+++ /dev/null
@@ -1,4 +0,0 @@
-var remixLib = require('remix-lib')
-var executionContext = remixLib.execution.executionContext
-
-module.exports = executionContext
diff --git a/src/lib/cmdInterpreterAPI.js b/src/lib/cmdInterpreterAPI.js
index 2494e3b7fe..fffeb24f59 100644
--- a/src/lib/cmdInterpreterAPI.js
+++ b/src/lib/cmdInterpreterAPI.js
@@ -5,7 +5,6 @@ var remixLib = require('remix-lib')
var EventManager = require('../lib/events')
var CompilerImport = require('../app/compiler/compiler-imports')
-var executionContext = require('../execution-context')
var toolTip = require('../app/ui/tooltip')
var globalRegistry = require('../global/registry')
var SourceHighlighter = require('../app/editor/sourceHighlighter')
@@ -15,9 +14,10 @@ var solidityTypeFormatter = require('../app/tabs/debugger/debuggerUI/vmDebugger/
var GistHandler = require('./gist-handler')
class CmdInterpreterAPI {
- constructor (terminal, localRegistry) {
+ constructor (terminal, localRegistry, executionContext) {
const self = this
self.event = new EventManager()
+ self.executionContext = executionContext
self._components = {}
self._components.registry = localRegistry || globalRegistry
self._components.terminal = terminal
@@ -62,14 +62,14 @@ class CmdInterpreterAPI {
debug (hash, cb) {
var self = this
delete self.d
- executionContext.web3().eth.getTransaction(hash, (error, tx) => {
+ self.executionContext.web3().eth.getTransaction(hash, (error, tx) => {
if (error) return cb(error)
var debugSession = new RemixDebug({
compilationResult: () => {
return self._deps.compilersArtefacts['__last'].getData()
}
})
- debugSession.addProvider('web3', executionContext.web3())
+ debugSession.addProvider('web3', self.executionContext.web3())
debugSession.switchProvider('web3')
debugSession.debug(tx)
self.d = debugSession
@@ -180,7 +180,7 @@ class CmdInterpreterAPI {
})
}
setproviderurl (url, cb) {
- executionContext.setProviderFromEndpoint(url, 'web3', (error) => {
+ this.executionContext.setProviderFromEndpoint(url, 'web3', (error) => {
if (error) toolTip(error)
if (cb) cb()
})
diff --git a/src/lib/transactionReceiptResolver.js b/src/lib/transactionReceiptResolver.js
index e498779c53..78608eff31 100644
--- a/src/lib/transactionReceiptResolver.js
+++ b/src/lib/transactionReceiptResolver.js
@@ -1,16 +1,16 @@
'use strict'
-var executionContext = require('../execution-context')
module.exports = class TransactionReceiptResolver {
- constructor () {
+ constructor (executionContext) {
this._transactionReceipts = {}
+ this.executionContext = executionContext
}
resolve (tx, cb) {
if (this._transactionReceipts[tx.hash]) {
return cb(null, this._transactionReceipts[tx.hash])
}
- executionContext.web3().eth.getTransactionReceipt(tx.hash, (error, receipt) => {
+ this.executionContext.web3().eth.getTransactionReceipt(tx.hash, (error, receipt) => {
if (!error) {
this._transactionReceipts[tx.hash] = receipt
cb(null, receipt)