Unverified Commit 00aea1d2 authored by Iuri Matias's avatar Iuri Matias Committed by GitHub

Merge pull request #2506 from ethereum/refactor_logic1

Refactor dropdown logic
parents c7986d2d 3988121e
...@@ -23,6 +23,8 @@ var toolTip = require('./app/ui/tooltip') ...@@ -23,6 +23,8 @@ var toolTip = require('./app/ui/tooltip')
var CompilerMetadata = require('./app/files/compiler-metadata') var CompilerMetadata = require('./app/files/compiler-metadata')
var CompilerImport = require('./app/compiler/compiler-imports') var CompilerImport = require('./app/compiler/compiler-imports')
var executionContext = remixLib.execution.executionContext
const PluginManagerComponent = require('./app/components/plugin-manager-component') const PluginManagerComponent = require('./app/components/plugin-manager-component')
const CompilersArtefacts = require('./app/compiler/compiler-artefacts') 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 ...@@ -222,15 +224,15 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
const fileManager = new FileManager(editor) const fileManager = new FileManager(editor)
registry.put({api: fileManager, name: 'filemanager'}) registry.put({api: fileManager, name: 'filemanager'})
// ----------------- compilation metadata generation servive ---------------------------- // ----------------- 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) ---------------------------- // ----------------- compilation result service (can keep track of compilation results) ----------------------------
const compilersArtefacts = new CompilersArtefacts() // store all the compilation results (key represent a compiler name) const compilersArtefacts = new CompilersArtefacts() // store all the compilation results (key represent a compiler name)
registry.put({api: compilersArtefacts, name: 'compilersartefacts'}) registry.put({api: compilersArtefacts, name: 'compilersartefacts'})
// ----------------- universal dapp: run transaction, listen on transactions, decode events // ----------------- universal dapp: run transaction, listen on transactions, decode events
const udapp = new UniversalDApp(registry.get('config').api) const udapp = new UniversalDApp(registry.get('config').api, executionContext)
const {eventsDecoder, txlistener} = makeUdapp(udapp, compilersArtefacts, (domEl) => mainview.getTerminal().logHtml(domEl)) const {eventsDecoder, txlistener} = makeUdapp(udapp, executionContext, compilersArtefacts, (domEl) => mainview.getTerminal().logHtml(domEl))
// ----------------- network service (resolve network id / name) ---------------------------- // ----------------- network service (resolve network id / name) ----------------------------
const networkModule = new NetworkModule() const networkModule = new NetworkModule(executionContext)
// ----------------- convert offset to line/column service ---------------------------- // ----------------- convert offset to line/column service ----------------------------
var offsetToLineColumnConverter = new OffsetToLineColumnConverter() var offsetToLineColumnConverter = new OffsetToLineColumnConverter()
registry.put({api: offsetToLineColumnConverter, name: '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 ...@@ -248,7 +250,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
// LAYOUT & SYSTEM VIEWS // LAYOUT & SYSTEM VIEWS
const appPanel = new MainPanel() 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' }) registry.put({ api: mainview, name: 'mainview' })
appManager.register([ appManager.register([
...@@ -293,6 +295,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org ...@@ -293,6 +295,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
) )
const run = new RunTab( const run = new RunTab(
udapp, udapp,
executionContext,
registry.get('config').api, registry.get('config').api,
registry.get('filemanager').api, registry.get('filemanager').api,
registry.get('editor').api, registry.get('editor').api,
...@@ -302,7 +305,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org ...@@ -302,7 +305,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
mainview mainview
) )
const analysis = new AnalysisTab(registry) const analysis = new AnalysisTab(registry)
const debug = new DebuggerTab() const debug = new DebuggerTab(executionContext)
const test = new TestTab( const test = new TestTab(
registry.get('filemanager').api, registry.get('filemanager').api,
filePanel, filePanel,
......
'use strict' 'use strict'
var executionContext = require('../../execution-context')
var CompilerAbstract = require('../compiler/compiler-abstract') var CompilerAbstract = require('../compiler/compiler-abstract')
import { Plugin } from '@remixproject/engine' import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../package.json' import * as packageJson from '../../../package.json'
...@@ -12,9 +11,10 @@ const profile = { ...@@ -12,9 +11,10 @@ const profile = {
} }
class CompilerMetadata extends Plugin { class CompilerMetadata extends Plugin {
constructor (fileManager, config) { constructor (executionContext, fileManager, config) {
super(profile) super(profile)
var self = this var self = this
self.executionContext = executionContext
self.fileManager = fileManager self.fileManager = fileManager
self.config = config self.config = config
self.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'görli:5', 'Custom'] self.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'görli:5', 'Custom']
...@@ -97,7 +97,7 @@ class CompilerMetadata extends Plugin { ...@@ -97,7 +97,7 @@ class CompilerMetadata extends Plugin {
var provider = self.fileManager.currentFileProvider() var provider = self.fileManager.currentFileProvider()
var path = self.fileManager.currentPath() var path = self.fileManager.currentPath()
if (provider && path) { if (provider && path) {
executionContext.detectNetwork((err, { id, name } = {}) => { self.executionContext.detectNetwork((err, { id, name } = {}) => {
if (err) { if (err) {
console.log(err) console.log(err)
} else { } else {
......
...@@ -20,7 +20,7 @@ var css = csjs` ...@@ -20,7 +20,7 @@ var css = csjs`
` `
export class MainView { export class MainView {
constructor (editor, mainPanel, fileManager, appManager, txListener, eventsDecoder) { constructor (editor, mainPanel, fileManager, appManager, txListener, eventsDecoder, executionContext) {
var self = this var self = this
self.event = new EventManager() self.event = new EventManager()
self._view = {} self._view = {}
...@@ -31,6 +31,7 @@ export class MainView { ...@@ -31,6 +31,7 @@ export class MainView {
self.mainPanel = mainPanel self.mainPanel = mainPanel
self.txListener = txListener self.txListener = txListener
self.eventsDecoder = eventsDecoder self.eventsDecoder = eventsDecoder
self.executionContext = executionContext
this.appManager = appManager this.appManager = appManager
this.init() this.init()
} }
...@@ -99,7 +100,8 @@ export class MainView { ...@@ -99,7 +100,8 @@ export class MainView {
self._components.terminal = new Terminal({ self._components.terminal = new Terminal({
appManager: this.appManager, appManager: this.appManager,
eventsDecoder: this.eventsDecoder, eventsDecoder: this.eventsDecoder,
txListener: this.txListener txListener: this.txListener,
executionContext: this.executionContext
}, },
{ {
getPosition: (event) => { getPosition: (event) => {
......
...@@ -10,7 +10,6 @@ var Web3 = require('web3') ...@@ -10,7 +10,6 @@ var Web3 = require('web3')
var swarmgw = require('swarmgw')() var swarmgw = require('swarmgw')()
var CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI') var CommandInterpreterAPI = require('../../lib/cmdInterpreterAPI')
var executionContext = require('../../execution-context')
var AutoCompletePopup = require('../ui/auto-complete-popup') var AutoCompletePopup = require('../ui/auto-complete-popup')
var TxLogger = require('../../app/ui/txLogger') var TxLogger = require('../../app/ui/txLogger')
...@@ -42,6 +41,7 @@ class Terminal extends Plugin { ...@@ -42,6 +41,7 @@ class Terminal extends Plugin {
super(profile) super(profile)
var self = this var self = this
self.event = new EventManager() self.event = new EventManager()
self.executionContext = opts.executionContext
self._api = api self._api = api
self._opts = opts self._opts = opts
self.data = { self.data = {
...@@ -52,7 +52,7 @@ class Terminal extends Plugin { ...@@ -52,7 +52,7 @@ class Terminal extends Plugin {
} }
self._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null } self._view = { el: null, bar: null, input: null, term: null, journal: null, cli: null }
self._components = {} 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 = new AutoCompletePopup(self._opts)
self._components.autoCompletePopup.event.register('handleSelect', function (input) { self._components.autoCompletePopup.event.register('handleSelect', function (input) {
let textList = self._view.input.innerText.split(' ') let textList = self._view.input.innerText.split(' ')
...@@ -437,7 +437,7 @@ class Terminal extends Plugin { ...@@ -437,7 +437,7 @@ class Terminal extends Plugin {
self._shell('remix.help()', self.commands, () => {}) self._shell('remix.help()', self.commands, () => {})
self.commands.html(intro) 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) => { self._components.txLogger.event.register('debuggingRequested', (hash) => {
// TODO should probably be in the run module // TODO should probably be in the run module
if (!self._opts.appManager.isActive('debugger')) self._opts.appManager.activateOne('debugger') if (!self._opts.appManager.isActive('debugger')) self._opts.appManager.activateOne('debugger')
...@@ -668,7 +668,7 @@ class Terminal extends Plugin { ...@@ -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.') 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 self = this
var context = domTerminalFeatures(self, scopedCommands) var context = domTerminalFeatures(self, scopedCommands, self.executionContext)
try { try {
var cmds = vm.createContext(Object.assign(self._jsSandboxContext, context, self._jsSandboxRegistered)) var cmds = vm.createContext(Object.assign(self._jsSandboxContext, context, self._jsSandboxRegistered))
var result = vm.runInContext(script, cmds) var result = vm.runInContext(script, cmds)
...@@ -680,7 +680,7 @@ class Terminal extends Plugin { ...@@ -680,7 +680,7 @@ class Terminal extends Plugin {
} }
} }
function domTerminalFeatures (self, scopedCommands) { function domTerminalFeatures (self, scopedCommands, executionContext) {
return { return {
swarmgw, swarmgw,
ethers, ethers,
......
...@@ -21,9 +21,10 @@ const profile = { ...@@ -21,9 +21,10 @@ const profile = {
class DebuggerTab extends ViewPlugin { class DebuggerTab extends ViewPlugin {
constructor () { constructor (executionContext) {
super(profile) super(profile)
this.el = null this.el = null
this.executionContext = executionContext
} }
render () { render () {
...@@ -33,7 +34,7 @@ class DebuggerTab extends ViewPlugin { ...@@ -33,7 +34,7 @@ class DebuggerTab extends ViewPlugin {
<div class="${css.debuggerTabView}" id="debugView"> <div class="${css.debuggerTabView}" id="debugView">
<div id="debugger" class="${css.debugger}"></div> <div id="debugger" class="${css.debugger}"></div>
</div>` </div>`
this.debuggerUI = new DebuggerUI(this.el.querySelector('#debugger')) this.debuggerUI = new DebuggerUI(this.el.querySelector('#debugger'), this.executionContext)
return this.el return this.el
} }
......
...@@ -9,7 +9,6 @@ var SourceHighlighter = require('../../editor/sourceHighlighter') ...@@ -9,7 +9,6 @@ var SourceHighlighter = require('../../editor/sourceHighlighter')
var EventManager = require('../../../lib/events') var EventManager = require('../../../lib/events')
var executionContext = require('../../../execution-context')
var globalRegistry = require('../../../global/registry') var globalRegistry = require('../../../global/registry')
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
...@@ -31,8 +30,9 @@ var css = csjs` ...@@ -31,8 +30,9 @@ var css = csjs`
class DebuggerUI { class DebuggerUI {
constructor (container) { constructor (container, executionContext) {
this.registry = globalRegistry this.registry = globalRegistry
this.executionContext = executionContext
this.event = new EventManager() this.event = new EventManager()
this.isActive = false this.isActive = false
...@@ -105,13 +105,13 @@ class DebuggerUI { ...@@ -105,13 +105,13 @@ class DebuggerUI {
getDebugWeb3 () { getDebugWeb3 () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
executionContext.detectNetwork((error, network) => { this.executionContext.detectNetwork((error, network) => {
let web3 let web3
if (error || !network) { if (error || !network) {
web3 = init.web3DebugNode(executionContext.web3()) web3 = init.web3DebugNode(this.executionContext.web3())
} else { } else {
const webDebugNode = init.web3DebugNode(network.name) const webDebugNode = init.web3DebugNode(network.name)
web3 = !webDebugNode ? executionContext.web3() : webDebugNode web3 = !webDebugNode ? this.executionContext.web3() : webDebugNode
} }
init.extendWeb3(web3) init.extendWeb3(web3)
resolve(web3) resolve(web3)
......
const executionContext = require('../../execution-context')
import { Plugin } from '@remixproject/engine' import { Plugin } from '@remixproject/engine'
import * as packageJson from '../../../package.json' import * as packageJson from '../../../package.json'
...@@ -15,10 +14,11 @@ export const profile = { ...@@ -15,10 +14,11 @@ export const profile = {
// - methods: ['getNetworkProvider', 'getEndpoint', 'detectNetwork', 'addNetwork', 'removeNetwork'] // - methods: ['getNetworkProvider', 'getEndpoint', 'detectNetwork', 'addNetwork', 'removeNetwork']
export class NetworkModule extends Plugin { export class NetworkModule extends Plugin {
constructor () { constructor (executionContext) {
super(profile) super(profile)
this.executionContext = executionContext
// TODO: See with remix-lib to make sementic coherent // TODO: See with remix-lib to make sementic coherent
executionContext.event.register('contextChanged', (provider) => { this.executionContext.event.register('contextChanged', (provider) => {
this.emit('providerChanged', provider) this.emit('providerChanged', provider)
}) })
/* /*
...@@ -37,13 +37,13 @@ export class NetworkModule extends Plugin { ...@@ -37,13 +37,13 @@ export class NetworkModule extends Plugin {
/** Return the current network provider (web3, vm, injected) */ /** Return the current network provider (web3, vm, injected) */
getNetworkProvider () { getNetworkProvider () {
return executionContext.getProvider() return this.executionContext.getProvider()
} }
/** Return the current network */ /** Return the current network */
detectNetwork () { detectNetwork () {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
executionContext.detectNetwork((error, network) => { this.executionContext.detectNetwork((error, network) => {
error ? reject(error) : resolve(network) error ? reject(error) : resolve(network)
}) })
}) })
...@@ -51,20 +51,20 @@ export class NetworkModule extends Plugin { ...@@ -51,20 +51,20 @@ export class NetworkModule extends Plugin {
/** Return the url only if network provider is 'web3' */ /** Return the url only if network provider is 'web3' */
getEndpoint () { getEndpoint () {
const provider = executionContext.getProvider() const provider = this.executionContext.getProvider()
if (provider !== 'web3') { if (provider !== 'web3') {
throw new Error('no endpoint: current provider is either injected or vm') throw new Error('no endpoint: current provider is either injected or vm')
} }
return executionContext.web3().currentProvider.host return this.executionContext.web3().currentProvider.host
} }
/** Add a custom network to the list of available networks */ /** Add a custom network to the list of available networks */
addNetwork (customNetwork) { addNetwork (customNetwork) {
executionContext.addProvider(customNetwork) this.executionContext.addProvider(customNetwork)
} }
/** Remove a network to the list of availble networks */ /** Remove a network to the list of availble networks */
removeNetwork (name) { removeNetwork (name) {
executionContext.removeProvider(name) this.executionContext.removeProvider(name)
} }
} }
...@@ -8,9 +8,11 @@ var modalDialog = require('../../ui/modaldialog') ...@@ -8,9 +8,11 @@ var modalDialog = require('../../ui/modaldialog')
var MultiParamManager = require('../../ui/multiParamManager') var MultiParamManager = require('../../ui/multiParamManager')
class ContractDropdownUI { class ContractDropdownUI {
constructor (dropdownLogic, logCallback) { constructor (blockchain, dropdownLogic, logCallback, runView) {
this.blockchain = blockchain
this.dropdownLogic = dropdownLogic this.dropdownLogic = dropdownLogic
this.logCallback = logCallback this.logCallback = logCallback
this.runView = runView
this.event = new EventManager() this.event = new EventManager()
this.listenToEvents() this.listenToEvents()
...@@ -39,8 +41,6 @@ class ContractDropdownUI { ...@@ -39,8 +41,6 @@ class ContractDropdownUI {
document.querySelector(`.${css.contractNames}`).classList.add(css.contractNamesError) document.querySelector(`.${css.contractNames}`).classList.add(css.contractNamesError)
} }
}) })
this.dropdownLogic.event.register('currentFileChanged', this.changeCurrentFile.bind(this))
} }
render () { render () {
...@@ -108,8 +108,9 @@ class ContractDropdownUI { ...@@ -108,8 +108,9 @@ class ContractDropdownUI {
} }
const selectedContract = this.getSelectedContract() const selectedContract = this.getSelectedContract()
const clickCallback = (valArray, inputsValues) => { const clickCallback = async (valArray, inputsValues) => {
this.createInstance(inputsValues) var selectedContract = this.getSelectedContract()
this.createInstance(selectedContract, inputsValues)
} }
const createConstructorInstance = new MultiParamManager( const createConstructorInstance = new MultiParamManager(
0, 0,
...@@ -130,9 +131,7 @@ class ContractDropdownUI { ...@@ -130,9 +131,7 @@ class ContractDropdownUI {
return this.dropdownLogic.getSelectedContract(contractName, compilerAtributeName) return this.dropdownLogic.getSelectedContract(contractName, compilerAtributeName)
} }
createInstance (args) { async createInstance (selectedContract, args) {
var selectedContract = this.getSelectedContract()
if (selectedContract.bytecodeObject.length === 0) { if (selectedContract.bytecodeObject.length === 0) {
return modalDialogCustom.alert('This contract may be abstract, not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.') return modalDialogCustom.alert('This contract may be abstract, not implement an abstract parent\'s methods completely or not invoke an inherited contract\'s constructor correctly.')
} }
...@@ -177,6 +176,16 @@ class ContractDropdownUI { ...@@ -177,6 +176,16 @@ class ContractDropdownUI {
this.event.trigger('newContractInstanceAdded', [contractObject, address, contractObject.name]) this.event.trigger('newContractInstanceAdded', [contractObject, address, contractObject.name])
} }
let contractMetadata
try {
contractMetadata = await this.runView.call('compilerMetadata', 'deployMetadataOf', selectedContract.name)
} catch (error) {
return statusCb(`creation of ${selectedContract.name} errored: ` + error)
}
const compilerContracts = this.dropdownLogic.getCompilerContracts()
const confirmationCb = this.getConfirmationCb(modalDialog, confirmDialog)
if (selectedContract.isOverSizeLimit()) { if (selectedContract.isOverSizeLimit()) {
return modalDialog('Contract code size over limit', yo`<div>Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails. <br> return modalDialog('Contract code size over limit', yo`<div>Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails. <br>
More info: <a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-170.md" target="_blank">eip-170</a> More info: <a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-170.md" target="_blank">eip-170</a>
...@@ -184,7 +193,7 @@ class ContractDropdownUI { ...@@ -184,7 +193,7 @@ class ContractDropdownUI {
{ {
label: 'Force Send', label: 'Force Send',
fn: () => { 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', label: 'Cancel',
fn: () => { fn: () => {
...@@ -192,7 +201,38 @@ class ContractDropdownUI { ...@@ -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 () { loadFromAddress () {
...@@ -215,7 +255,6 @@ class ContractDropdownUI { ...@@ -215,7 +255,6 @@ class ContractDropdownUI {
} }
) )
} }
} }
module.exports = ContractDropdownUI module.exports = ContractDropdownUI
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
var ethJSUtil = require('ethereumjs-util') var ethJSUtil = require('ethereumjs-util')
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
var txHelper = remixLib.execution.txHelper var txHelper = remixLib.execution.txHelper
var txFormat = remixLib.execution.txFormat
var executionContext = remixLib.execution.executionContext
var typeConversion = remixLib.execution.typeConversion var typeConversion = remixLib.execution.typeConversion
var txExecution = remixLib.execution.txExecution
var CompilerAbstract = require('../../../compiler/compiler-abstract') var CompilerAbstract = require('../../../compiler/compiler-abstract')
var EventManager = remixLib.EventManager var EventManager = remixLib.EventManager
var Web3 = require('web3') var Web3 = require('web3')
class DropdownLogic { class DropdownLogic {
constructor (fileManager, compilersArtefacts, config, editor, udapp, filePanel, runView) { constructor (compilersArtefacts, config, editor, runView) {
this.compilersArtefacts = compilersArtefacts this.compilersArtefacts = compilersArtefacts
this.config = config this.config = config
this.editor = editor this.editor = editor
this.udapp = udapp
this.runView = runView this.runView = runView
this.filePanel = filePanel
this.event = new EventManager() this.event = new EventManager()
this.listenToCompilationEvents() 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 // TODO: can be moved up; the event in contractDropdown will have to refactored a method instead
...@@ -120,107 +111,8 @@ class DropdownLogic { ...@@ -120,107 +111,8 @@ class DropdownLogic {
return Web3.utils.toBN(gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10), unit || 'gwei'))) return Web3.utils.toBN(gas).mul(Web3.utils.toBN(Web3.utils.toWei(gasPrice.toString(10), unit || 'gwei')))
} }
getGasPrice (cb) { determineGasFees (tx) {
return executionContext.web3().eth.getGasPrice(cb) const determineGasFeesCb = (gasPrice, 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)
}
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.')
}
})
}
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 let txFeeText, priceStatus
// TODO: this try catch feels like an anti pattern, can/should be // TODO: this try catch feels like an anti pattern, can/should be
// removed, but for now keeping the original logic // removed, but for now keeping the original logic
...@@ -233,72 +125,13 @@ class DropdownLogic { ...@@ -233,72 +125,13 @@ class DropdownLogic {
priceStatus = false priceStatus = false
} }
cb(txFeeText, priceStatus) 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) { getCompilerContracts () {
var constructor = selectedContract.getConstructorInterface() return this.compilersArtefacts['__last'].getData().contracts
// 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)
})
} }
} }
......
...@@ -2,7 +2,6 @@ var async = require('async') ...@@ -2,7 +2,6 @@ var async = require('async')
var ethutil = require('ethereumjs-util') var ethutil = require('ethereumjs-util')
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
var EventManager = remixLib.EventManager var EventManager = remixLib.EventManager
var executionContext = remixLib.execution.executionContext
var format = remixLib.execution.txFormat var format = remixLib.execution.txFormat
var txHelper = remixLib.execution.txHelper var txHelper = remixLib.execution.txHelper
var typeConversion = remixLib.execution.typeConversion var typeConversion = remixLib.execution.typeConversion
...@@ -15,9 +14,10 @@ var Web3 = require('web3') ...@@ -15,9 +14,10 @@ var Web3 = require('web3')
* *
*/ */
class Recorder { class Recorder {
constructor (udapp, fileManager, config) { constructor (executionContext, udapp, fileManager, config) {
var self = this var self = this
self.event = new EventManager() self.event = new EventManager()
self.executionContext = executionContext
self.data = { _listen: true, _replay: false, journal: [], _createdContracts: {}, _createdContractsReverse: {}, _usedAccounts: {}, _abis: {}, _contractABIReferences: {}, _linkReferences: {} } self.data = { _listen: true, _replay: false, journal: [], _createdContracts: {}, _createdContractsReverse: {}, _usedAccounts: {}, _abis: {}, _contractABIReferences: {}, _linkReferences: {} }
this.udapp = udapp this.udapp = udapp
this.fileManager = fileManager this.fileManager = fileManager
...@@ -74,7 +74,7 @@ class Recorder { ...@@ -74,7 +74,7 @@ class Recorder {
if (error) return console.log(error) if (error) return console.log(error)
if (call) return 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 if (!rawAddress) return // not a contract creation
const stringAddress = this.addressToString(rawAddress) const stringAddress = this.addressToString(rawAddress)
const address = ethutil.toChecksumAddress(stringAddress) const address = ethutil.toChecksumAddress(stringAddress)
...@@ -82,7 +82,7 @@ class Recorder { ...@@ -82,7 +82,7 @@ class Recorder {
this.data._createdContracts[address] = timestamp this.data._createdContracts[address] = timestamp
this.data._createdContractsReverse[timestamp] = address 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.register('newTxRecorded', (count) => {
this.event.trigger('recorderCountChange', [count]) this.event.trigger('recorderCountChange', [count])
}) })
...@@ -261,7 +261,7 @@ class Recorder { ...@@ -261,7 +261,7 @@ class Recorder {
console.error(err) console.error(err)
logCallBack(err + '. Execution failed at ' + index) logCallBack(err + '. Execution failed at ' + index)
} else { } else {
const rawAddress = executionContext.isVM() ? txResult.result.createdAddress : txResult.result.contractAddress const rawAddress = self.executionContext.isVM() ? txResult.result.createdAddress : txResult.result.contractAddress
if (rawAddress) { if (rawAddress) {
const stringAddress = self.addressToString(rawAddress) const stringAddress = self.addressToString(rawAddress)
const address = ethutil.toChecksumAddress(stringAddress) const address = ethutil.toChecksumAddress(stringAddress)
...@@ -335,7 +335,7 @@ class Recorder { ...@@ -335,7 +335,7 @@ class Recorder {
cb(txFeeText, priceStatus) cb(txFeeText, priceStatus)
}, },
(cb) => { (cb) => {
executionContext.web3().eth.getGasPrice((error, gasPrice) => { this.executionContext.web3().eth.getGasPrice((error, gasPrice) => {
var warnMessage = ' Please fix this issue before sending any transaction. ' var warnMessage = ' Please fix this issue before sending any transaction. '
if (error) { if (error) {
return cb('Unable to retrieve the current network gas price.' + warnMessage + error) return cb('Unable to retrieve the current network gas price.' + warnMessage + error)
......
...@@ -4,11 +4,11 @@ var remixLib = require('remix-lib') ...@@ -4,11 +4,11 @@ var remixLib = require('remix-lib')
var Web3 = require('web3') var Web3 = require('web3')
const addTooltip = require('../../../ui/tooltip') const addTooltip = require('../../../ui/tooltip')
var EventManager = remixLib.EventManager var EventManager = remixLib.EventManager
var executionContext = remixLib.execution.executionContext
class Settings { class Settings {
constructor (udapp) { constructor (executionContext, udapp) {
this.executionContext = executionContext
this.udapp = udapp this.udapp = udapp
this.event = new EventManager() this.event = new EventManager()
...@@ -16,15 +16,15 @@ class Settings { ...@@ -16,15 +16,15 @@ class Settings {
this.event.trigger('transactionExecuted', [error, from, to, data, lookupOnly, txResult]) 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]) this.event.trigger('contextChanged', [context, silent])
}) })
executionContext.event.register('addProvider', (network) => { this.executionContext.event.register('addProvider', (network) => {
this.event.trigger('addProvider', [network]) this.event.trigger('addProvider', [network])
}) })
executionContext.event.register('removeProvider', (name) => { this.executionContext.event.register('removeProvider', (name) => {
this.event.trigger('removeProvider', [name]) this.event.trigger('removeProvider', [name])
}) })
...@@ -32,15 +32,15 @@ class Settings { ...@@ -32,15 +32,15 @@ class Settings {
} }
changeExecutionContext (context, confirmCb, infoCb, cb) { 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) { setProviderFromEndpoint (target, context, cb) {
return executionContext.setProviderFromEndpoint(target, context, cb) return this.executionContext.setProviderFromEndpoint(target, context, cb)
} }
getProvider () { getProvider () {
return executionContext.getProvider() return this.executionContext.getProvider()
} }
getAccountBalanceForAddress (address, cb) { getAccountBalanceForAddress (address, cb) {
...@@ -50,7 +50,7 @@ class Settings { ...@@ -50,7 +50,7 @@ class Settings {
updateNetwork (cb) { updateNetwork (cb) {
this.networkcallid++ this.networkcallid++
((callid) => { ((callid) => {
executionContext.detectNetwork((err, { id, name } = {}) => { this.executionContext.detectNetwork((err, { id, name } = {}) => {
if (this.networkcallid > callid) return if (this.networkcallid > callid) return
this.networkcallid++ this.networkcallid++
if (err) { if (err) {
...@@ -70,18 +70,18 @@ class Settings { ...@@ -70,18 +70,18 @@ class Settings {
} }
isWeb3Provider () { isWeb3Provider () {
var isVM = executionContext.isVM() var isVM = this.executionContext.isVM()
var isInjected = executionContext.getProvider() === 'injected' var isInjected = this.executionContext.getProvider() === 'injected'
return (!isVM && !isInjected) return (!isVM && !isInjected)
} }
isInjectedWeb3 () { isInjectedWeb3 () {
return executionContext.getProvider() === 'injected' return this.executionContext.getProvider() === 'injected'
} }
signMessage (message, account, passphrase, cb) { signMessage (message, account, passphrase, cb) {
var isVM = executionContext.isVM() var isVM = this.executionContext.isVM()
var isInjected = executionContext.getProvider() === 'injected' var isInjected = this.executionContext.getProvider() === 'injected'
if (isVM) { if (isVM) {
const personalMsg = ethJSUtil.hashPersonalMessage(Buffer.from(message)) const personalMsg = ethJSUtil.hashPersonalMessage(Buffer.from(message))
...@@ -99,7 +99,7 @@ class Settings { ...@@ -99,7 +99,7 @@ class Settings {
const hashedMsg = Web3.utils.sha3(message) const hashedMsg = Web3.utils.sha3(message)
try { try {
addTooltip('Please check your provider to approve') 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) cb(error.message, hashedMsg, signedData)
}) })
} catch (e) { } catch (e) {
...@@ -110,7 +110,7 @@ class Settings { ...@@ -110,7 +110,7 @@ class Settings {
const hashedMsg = Web3.utils.sha3(message) const hashedMsg = Web3.utils.sha3(message)
try { try {
var personal = new Personal(executionContext.web3().currentProvider) var personal = new Personal(this.executionContext.web3().currentProvider)
personal.sign(hashedMsg, account, passphrase, (error, signedData) => { personal.sign(hashedMsg, account, passphrase, (error, signedData) => {
cb(error.message, hashedMsg, signedData) cb(error.message, hashedMsg, signedData)
}) })
......
...@@ -320,7 +320,7 @@ class SettingsUI { ...@@ -320,7 +320,7 @@ class SettingsUI {
this.netUI.innerHTML = 'can\'t detect network ' this.netUI.innerHTML = 'can\'t detect network '
return 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.netUI.innerHTML = (network() !== 'vm') ? `${name} (${id || '-'}) network` : ''
}) })
this.fillAccountsList() this.fillAccountsList()
......
var registry = require('../../global/registry') var registry = require('../../global/registry')
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
var yo = require('yo-yo') var yo = require('yo-yo')
var executionContext = remixLib.execution.executionContext
var Txlistener = remixLib.execution.txListener var Txlistener = remixLib.execution.txListener
var EventsDecoder = remixLib.execution.EventsDecoder var EventsDecoder = remixLib.execution.EventsDecoder
var TransactionReceiptResolver = require('../../lib/transactionReceiptResolver') var TransactionReceiptResolver = require('../../lib/transactionReceiptResolver')
export function makeUdapp (udapp, compilersArtefacts, logHtmlCallback) { export function makeUdapp (udapp, executionContext, compilersArtefacts, logHtmlCallback) {
// ----------------- UniversalDApp ----------------- // ----------------- UniversalDApp -----------------
// TODO: to remove when possible // TODO: to remove when possible
udapp.event.register('transactionBroadcasted', (txhash, networkName) => { udapp.event.register('transactionBroadcasted', (txhash, networkName) => {
...@@ -15,7 +14,7 @@ export function makeUdapp (udapp, compilersArtefacts, logHtmlCallback) { ...@@ -15,7 +14,7 @@ export function makeUdapp (udapp, compilersArtefacts, logHtmlCallback) {
}) })
// ----------------- Tx listener ----------------- // ----------------- Tx listener -----------------
const transactionReceiptResolver = new TransactionReceiptResolver() const transactionReceiptResolver = new TransactionReceiptResolver(executionContext)
const txlistener = new Txlistener({ const txlistener = new Txlistener({
api: { api: {
...@@ -29,7 +28,7 @@ export function makeUdapp (udapp, compilersArtefacts, logHtmlCallback) { ...@@ -29,7 +28,7 @@ export function makeUdapp (udapp, compilersArtefacts, logHtmlCallback) {
}, },
event: { event: {
udapp: udapp.event udapp: udapp.event
}}) }}, executionContext)
registry.put({api: txlistener, name: 'txlistener'}) registry.put({api: txlistener, name: 'txlistener'})
udapp.startListening(txlistener) udapp.startListening(txlistener)
......
...@@ -15,9 +15,9 @@ const Recorder = require('../tabs/runTab/model/recorder.js') ...@@ -15,9 +15,9 @@ const Recorder = require('../tabs/runTab/model/recorder.js')
const RecorderUI = require('../tabs/runTab/recorder.js') const RecorderUI = require('../tabs/runTab/recorder.js')
const DropdownLogic = require('../tabs/runTab/model/dropdownlogic.js') const DropdownLogic = require('../tabs/runTab/model/dropdownlogic.js')
const ContractDropdownUI = require('../tabs/runTab/contractDropdown.js') const ContractDropdownUI = require('../tabs/runTab/contractDropdown.js')
const Blockchain = require('../tabs/runTab/model/blockchain.js')
const UniversalDAppUI = require('../ui/universal-dapp-ui') const UniversalDAppUI = require('../ui/universal-dapp-ui')
const executionContext = require('../../execution-context')
const profile = { const profile = {
name: 'udapp', name: 'udapp',
...@@ -35,11 +35,12 @@ const profile = { ...@@ -35,11 +35,12 @@ const profile = {
export class RunTab extends LibraryPlugin { 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) super(udapp, profile)
this.event = new EventManager() this.event = new EventManager()
this.config = config this.config = config
this.udapp = udapp this.udapp = udapp
this.executionContext = executionContext
this.fileManager = fileManager this.fileManager = fileManager
this.editor = editor this.editor = editor
this.logCallback = (msg) => { mainView.getTerminal().logHtml(msg) } this.logCallback = (msg) => { mainView.getTerminal().logHtml(msg) }
...@@ -49,7 +50,7 @@ export class RunTab extends LibraryPlugin { ...@@ -49,7 +50,7 @@ export class RunTab extends LibraryPlugin {
} }
onActivationInternal () { onActivationInternal () {
this.udappUI = new UniversalDAppUI(this.udapp, this.logCallback) this.udappUI = new UniversalDAppUI(this.udapp, this.logCallback, this.executionContext)
this.udapp.resetAPI({ this.udapp.resetAPI({
getAddress: (cb) => { getAddress: (cb) => {
cb(null, $('#txorigin').val()) cb(null, $('#txorigin').val())
...@@ -122,7 +123,7 @@ export class RunTab extends LibraryPlugin { ...@@ -122,7 +123,7 @@ export class RunTab extends LibraryPlugin {
} }
renderSettings (udapp) { renderSettings (udapp) {
var settings = new Settings(udapp) var settings = new Settings(this.executionContext, udapp)
this.settingsUI = new SettingsUI(settings, this.networkModule) this.settingsUI = new SettingsUI(settings, this.networkModule)
this.settingsUI.event.register('clearInstance', () => { this.settingsUI.event.register('clearInstance', () => {
...@@ -131,8 +132,11 @@ export class RunTab extends LibraryPlugin { ...@@ -131,8 +132,11 @@ export class RunTab extends LibraryPlugin {
} }
renderDropdown (udappUI, fileManager, compilersArtefacts, config, editor, udapp, filePanel, logCallback) { renderDropdown (udappUI, fileManager, compilersArtefacts, config, editor, udapp, filePanel, logCallback) {
const dropdownLogic = new DropdownLogic(fileManager, compilersArtefacts, config, editor, udapp, filePanel, this) const dropdownLogic = new DropdownLogic(compilersArtefacts, config, editor, this)
this.contractDropdownUI = new ContractDropdownUI(dropdownLogic, logCallback) 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', () => { this.contractDropdownUI.event.register('clearInstance', () => {
const noInstancesText = this.noInstancesText const noInstancesText = this.noInstancesText
...@@ -149,7 +153,7 @@ export class RunTab extends LibraryPlugin { ...@@ -149,7 +153,7 @@ export class RunTab extends LibraryPlugin {
renderRecorder (udapp, udappUI, fileManager, config, logCallback) { renderRecorder (udapp, udappUI, fileManager, config, logCallback) {
this.recorderCount = yo`<span>0</span>` this.recorderCount = yo`<span>0</span>`
const recorder = new Recorder(udapp, fileManager, config) const recorder = new Recorder(this.executionContext, udapp, fileManager, config)
recorder.event.register('recorderCountChange', (count) => { recorder.event.register('recorderCountChange', (count) => {
this.recorderCount.innerText = count this.recorderCount.innerText = count
}) })
...@@ -200,9 +204,9 @@ export class RunTab extends LibraryPlugin { ...@@ -200,9 +204,9 @@ export class RunTab extends LibraryPlugin {
render () { render () {
this.onActivationInternal() this.onActivationInternal()
executionContext.init(this.config) this.executionContext.init(this.config)
executionContext.stopListenOnLastBlock() this.executionContext.stopListenOnLastBlock()
executionContext.listenOnLastBlock() this.executionContext.listenOnLastBlock()
this.udapp.resetEnvironment() this.udapp.resetEnvironment()
this.renderInstanceContainer() this.renderInstanceContainer()
this.renderSettings(this.udapp) this.renderSettings(this.udapp)
......
...@@ -8,7 +8,6 @@ var remixLib = require('remix-lib') ...@@ -8,7 +8,6 @@ var remixLib = require('remix-lib')
var EventManager = require('../../lib/events') var EventManager = require('../../lib/events')
var helper = require('../../lib/helper') var helper = require('../../lib/helper')
var executionContext = require('../../execution-context')
var modalDialog = require('./modal-dialog-custom') var modalDialog = require('./modal-dialog-custom')
var typeConversion = remixLib.execution.typeConversion var typeConversion = remixLib.execution.typeConversion
var globlalRegistry = require('../../global/registry') var globlalRegistry = require('../../global/registry')
...@@ -117,7 +116,7 @@ var css = csjs` ...@@ -117,7 +116,7 @@ var css = csjs`
* *
*/ */
class TxLogger { class TxLogger {
constructor (eventsDecoder, txListener, terminal) { constructor (eventsDecoder, txListener, terminal, executionContext) {
this.event = new EventManager() this.event = new EventManager()
this.seen = {} this.seen = {}
function filterTx (value, query) { function filterTx (value, query) {
...@@ -140,7 +139,7 @@ class TxLogger { ...@@ -140,7 +139,7 @@ class TxLogger {
if (data.tx.isCall) { if (data.tx.isCall) {
el = renderCall(this, data) el = renderCall(this, data)
} else { } else {
el = renderKnownTransaction(this, data) el = renderKnownTransaction(this, data, executionContext)
} }
this.seen[data.tx.hash] = el this.seen[data.tx.hash] = el
append(el) append(el)
...@@ -149,7 +148,7 @@ class TxLogger { ...@@ -149,7 +148,7 @@ class TxLogger {
this.logUnknownTX = this.terminal.registerCommand('unknownTransaction', (args, cmds, append) => { this.logUnknownTX = this.terminal.registerCommand('unknownTransaction', (args, cmds, append) => {
// triggered for transaction AND call // triggered for transaction AND call
var data = args[0] var data = args[0]
var el = renderUnknownTransaction(this, data) var el = renderUnknownTransaction(this, data, executionContext)
append(el) append(el)
}, { activate: false, filterFn: filterTx }) }, { activate: false, filterFn: filterTx })
...@@ -205,7 +204,7 @@ function log (self, tx, receipt) { ...@@ -205,7 +204,7 @@ function log (self, tx, receipt) {
} }
} }
function renderKnownTransaction (self, data) { function renderKnownTransaction (self, data, executionContext) {
var from = data.tx.from var from = data.tx.from
var to = data.resolvedData.contractName + '.' + data.resolvedData.fn var to = data.resolvedData.contractName + '.' + data.resolvedData.fn
var obj = {from, to} var obj = {from, to}
...@@ -214,7 +213,7 @@ function renderKnownTransaction (self, data) { ...@@ -214,7 +213,7 @@ function renderKnownTransaction (self, data) {
<span id="tx${data.tx.hash}"> <span id="tx${data.tx.hash}">
<div class="${css.log}" onclick=${e => txDetails(e, tx, data, obj)}> <div class="${css.log}" onclick=${e => txDetails(e, tx, data, obj)}>
${checkTxStatus(data.receipt, txType)} ${checkTxStatus(data.receipt, txType)}
${context(self, {from, to, data})} ${context(self, {from, to, data}, executionContext)}
<div class=${css.buttons}> <div class=${css.buttons}>
<button class="${css.debug} btn btn-primary btn-sm" onclick=${(e) => debug(e, data, self)}>Debug</div> <button class="${css.debug} btn btn-primary btn-sm" onclick=${(e) => debug(e, data, self)}>Debug</div>
</div> </div>
...@@ -251,7 +250,7 @@ function renderCall (self, data) { ...@@ -251,7 +250,7 @@ function renderCall (self, data) {
return tx return tx
} }
function renderUnknownTransaction (self, data) { function renderUnknownTransaction (self, data, executionContext) {
var from = data.tx.from var from = data.tx.from
var to = data.tx.to var to = data.tx.to
var obj = {from, to} var obj = {from, to}
...@@ -260,7 +259,7 @@ function renderUnknownTransaction (self, data) { ...@@ -260,7 +259,7 @@ function renderUnknownTransaction (self, data) {
<span id="tx${data.tx.hash}"> <span id="tx${data.tx.hash}">
<div class="${css.log}" onclick=${e => txDetails(e, tx, data, obj)}> <div class="${css.log}" onclick=${e => txDetails(e, tx, data, obj)}>
${checkTxStatus(data.receipt || data.tx, txType)} ${checkTxStatus(data.receipt || data.tx, txType)}
${context(self, {from, to, data})} ${context(self, {from, to, data}, executionContext)}
<div class=${css.buttons}> <div class=${css.buttons}>
<div class="${css.debug} btn btn-primary btn-sm" onclick=${(e) => debug(e, data, self)}>Debug</div> <div class="${css.debug} btn btn-primary btn-sm" onclick=${(e) => debug(e, data, self)}>Debug</div>
</div> </div>
...@@ -291,7 +290,7 @@ function checkTxStatus (tx, type) { ...@@ -291,7 +290,7 @@ function checkTxStatus (tx, type) {
} }
} }
function context (self, opts) { function context (self, opts, executionContext) {
var data = opts.data || '' var data = opts.data || ''
var from = opts.from ? helper.shortenHexData(opts.from) : '' var from = opts.from ? helper.shortenHexData(opts.from) : ''
var to = opts.to var to = opts.to
......
...@@ -15,17 +15,16 @@ var typeConversion = remixLib.execution.typeConversion ...@@ -15,17 +15,16 @@ var typeConversion = remixLib.execution.typeConversion
var txExecution = remixLib.execution.txExecution var txExecution = remixLib.execution.txExecution
var txFormat = remixLib.execution.txFormat var txFormat = remixLib.execution.txFormat
var executionContext = require('../../execution-context')
var confirmDialog = require('./confirmDialog') var confirmDialog = require('./confirmDialog')
var modalCustom = require('./modal-dialog-custom') var modalCustom = require('./modal-dialog-custom')
var modalDialog = require('./modaldialog') var modalDialog = require('./modaldialog')
var TreeView = require('./TreeView') var TreeView = require('./TreeView')
function UniversalDAppUI (udapp, logCallback) { function UniversalDAppUI (udapp, logCallback, executionContext) {
this.udapp = udapp this.udapp = udapp
this.logCallback = logCallback this.logCallback = logCallback
this.compilerData = {contractsDetails: {}} this.compilerData = {contractsDetails: {}}
this.executionContext = executionContext
} }
function decodeResponseToTreeView (response, fnabi) { function decodeResponseToTreeView (response, fnabi) {
...@@ -181,7 +180,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) { ...@@ -181,7 +180,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) {
cb(txFeeText, priceStatus) cb(txFeeText, priceStatus)
}, },
(cb) => { (cb) => {
executionContext.web3().eth.getGasPrice((error, gasPrice) => { self.executionContext.web3().eth.getGasPrice((error, gasPrice) => {
const warnMessage = ' Please fix this issue before sending any transaction. ' const warnMessage = ' Please fix this issue before sending any transaction. '
if (error) { if (error) {
return cb('Unable to retrieve the current network gas price.' + warnMessage + error) return cb('Unable to retrieve the current network gas price.' + warnMessage + error)
...@@ -263,7 +262,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) { ...@@ -263,7 +262,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) {
if (args.funABI.type === 'fallback') data.dataHex = value if (args.funABI.type === 'fallback') data.dataHex = value
self.udapp.callFunction(args.address, data, args.funABI, confirmationCb, continueCb, promptCb, (error, txResult) => { self.udapp.callFunction(args.address, data, args.funABI, confirmationCb, continueCb, promptCb, (error, txResult) => {
if (!error) { if (!error) {
var isVM = executionContext.isVM() var isVM = self.executionContext.isVM()
if (isVM) { if (isVM) {
var vmError = txExecution.checkVMError(txResult) var vmError = txExecution.checkVMError(txResult)
if (vmError.error) { if (vmError.error) {
...@@ -272,7 +271,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) { ...@@ -272,7 +271,7 @@ UniversalDAppUI.prototype.getCallButton = function (args) {
} }
} }
if (lookupOnly) { 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) outputCb(decoded)
} }
} else { } else {
......
var remixLib = require('remix-lib')
var executionContext = remixLib.execution.executionContext
module.exports = executionContext
...@@ -5,7 +5,6 @@ var remixLib = require('remix-lib') ...@@ -5,7 +5,6 @@ var remixLib = require('remix-lib')
var EventManager = require('../lib/events') var EventManager = require('../lib/events')
var CompilerImport = require('../app/compiler/compiler-imports') var CompilerImport = require('../app/compiler/compiler-imports')
var executionContext = require('../execution-context')
var toolTip = require('../app/ui/tooltip') var toolTip = require('../app/ui/tooltip')
var globalRegistry = require('../global/registry') var globalRegistry = require('../global/registry')
var SourceHighlighter = require('../app/editor/sourceHighlighter') var SourceHighlighter = require('../app/editor/sourceHighlighter')
...@@ -15,9 +14,10 @@ var solidityTypeFormatter = require('../app/tabs/debugger/debuggerUI/vmDebugger/ ...@@ -15,9 +14,10 @@ var solidityTypeFormatter = require('../app/tabs/debugger/debuggerUI/vmDebugger/
var GistHandler = require('./gist-handler') var GistHandler = require('./gist-handler')
class CmdInterpreterAPI { class CmdInterpreterAPI {
constructor (terminal, localRegistry) { constructor (terminal, localRegistry, executionContext) {
const self = this const self = this
self.event = new EventManager() self.event = new EventManager()
self.executionContext = executionContext
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
self._components.terminal = terminal self._components.terminal = terminal
...@@ -62,14 +62,14 @@ class CmdInterpreterAPI { ...@@ -62,14 +62,14 @@ class CmdInterpreterAPI {
debug (hash, cb) { debug (hash, cb) {
var self = this var self = this
delete self.d delete self.d
executionContext.web3().eth.getTransaction(hash, (error, tx) => { self.executionContext.web3().eth.getTransaction(hash, (error, tx) => {
if (error) return cb(error) if (error) return cb(error)
var debugSession = new RemixDebug({ var debugSession = new RemixDebug({
compilationResult: () => { compilationResult: () => {
return self._deps.compilersArtefacts['__last'].getData() return self._deps.compilersArtefacts['__last'].getData()
} }
}) })
debugSession.addProvider('web3', executionContext.web3()) debugSession.addProvider('web3', self.executionContext.web3())
debugSession.switchProvider('web3') debugSession.switchProvider('web3')
debugSession.debug(tx) debugSession.debug(tx)
self.d = debugSession self.d = debugSession
...@@ -180,7 +180,7 @@ class CmdInterpreterAPI { ...@@ -180,7 +180,7 @@ class CmdInterpreterAPI {
}) })
} }
setproviderurl (url, cb) { setproviderurl (url, cb) {
executionContext.setProviderFromEndpoint(url, 'web3', (error) => { this.executionContext.setProviderFromEndpoint(url, 'web3', (error) => {
if (error) toolTip(error) if (error) toolTip(error)
if (cb) cb() if (cb) cb()
}) })
......
'use strict' 'use strict'
var executionContext = require('../execution-context')
module.exports = class TransactionReceiptResolver { module.exports = class TransactionReceiptResolver {
constructor () { constructor (executionContext) {
this._transactionReceipts = {} this._transactionReceipts = {}
this.executionContext = executionContext
} }
resolve (tx, cb) { resolve (tx, cb) {
if (this._transactionReceipts[tx.hash]) { if (this._transactionReceipts[tx.hash]) {
return cb(null, 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) { if (!error) {
this._transactionReceipts[tx.hash] = receipt this._transactionReceipts[tx.hash] = receipt
cb(null, receipt) cb(null, receipt)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment