diff --git a/src/app/tabs/run-tab.js b/src/app/tabs/run-tab.js index 8f399940dd..981ba24aa0 100644 --- a/src/app/tabs/run-tab.js +++ b/src/app/tabs/run-tab.js @@ -195,18 +195,8 @@ function runTab (container, appAPI, appEvents, opts) { ` container.appendChild(el) - function addInstance (result) { - // { - // "result": { - // "gasUsed": "5318", - // "vm": { "exception": 1, "selfdestruct": {} }, - // "bloom": { "bitvector": { "type": "Buffer", "data": [0, /* ... */ 0, 0] } }, - // "amountSpent": "5318" - // }, - // "transactionHash": "0x84f68f96944a47b27af4b4ed1986637aa1bc05fd7a6f5cb1d6a53f68058276d8" - // } - var contractNames = document.querySelector(`.${css.contractNames.classNames[0]}`) - var contract = appAPI.getContract(contractNames.children[contractNames.selectedIndex].innerHTML) + function addInstance (sourcename) { + var contract = appAPI.getContract(sourcename) var address = self._view.atAddressButtonInput.value var instance = udapp.renderInstance(contract.object, address, self._view.selectContractNames.value) instanceContainer.appendChild(instance) @@ -322,22 +312,27 @@ function makeRecorder (self, appAPI, appEvents) { var json = appAPI.filesProviders['browser'].get(filename) if (!json) return modalDialogCustom.alert('Could not find file with transactions, please try again') try { - var txArray = JSON.parse(json) + var obj = JSON.parse(json) + var txArray = obj.transactions || [] + var addresses = obj.addresses || {} } catch (e) { modalDialogCustom.alert('Invalid JSON, please try again') } if (txArray.length) { txArray.forEach(tx => { - udapp.getAccounts((err, accounts = []) => { + var record = recorder.resolveAddress(tx.record, addresses) + udapp.rerunTx(record, function (err, result) { + // { + // "result": { + // "gasUsed": "5318", + // "vm": { "exception": 1, "selfdestruct": {} }, + // "bloom": { "bitvector": { "type": "Buffer", "data": [0, /* ... */ 0, 0] } }, + // "amountSpent": "5318" + // }, + // "transactionHash": "0x84f68f96944a47b27af4b4ed1986637aa1bc05fd7a6f5cb1d6a53f68058276d8" + // } if (err) console.error(err) - tx.record = recorder.resolveAddress(tx.record, accounts) - udapp.rerunTx(tx.record, function (err, result) { - if (err) console.error(err) - else { - // at each callback call, if the transaction succeed and if this is a creation transaction, we should call - self.addInstance(result) - } - }) + else if (record.src) self.addInstance(record.src) }) }) } diff --git a/src/recorder.js b/src/recorder.js index ad9bfbe2c1..d213a53d34 100644 --- a/src/recorder.js +++ b/src/recorder.js @@ -7,25 +7,35 @@ class Recorder { self._api = opts.api self.event = new EventManager() self.data = { journal: [], _pendingCreation: {} } - opts.events.executioncontext.register('contextChanged', function () { - self.clearAll() - }) + opts.events.executioncontext.register('contextChanged', () => self.clearAll()) var counter = 0 - function getIndex (accounts, address) { - var index - accounts.forEach((addr, idx) => { if (address === addr) index = idx }) - if (!index) index = (++counter) - return index - } self._addressCache = {} + + function getAddresses (cb) { + self._api.getAccounts(function (err, accounts = []) { + if (err) console.error(err) + var addresses = accounts.reduce((addr, account) => { + if (!addr[account]) addr[account] = `account{${++counter}}` + return addr + }, self._addressCache) + cb(addresses) + }) + } + function getCurrentContractName () { + var contractNames = document.querySelector(`[class^="contractNames"]`) + var contractName = contractNames.children[contractNames.selectedIndex].innerHTML + return contractName + } opts.events.udapp.register('initiatingTransaction', (timestamp, tx) => { var { from, to, value, gas, data } = tx var record = { value, gas, data } - self._api.getAccounts(function (err, accounts = []) { - if (err) console.error(err) - record.from = self._addressCache[from] || (self._addressCache[from] = ``) - if (to) record.to = self._addressCache[to] || (self._addressCache[to] = ``) - else self.data._pendingCreation[timestamp] = record + getAddresses(addresses => { + if (to) record.to = addresses[to] || (addresses[to] = self._addressCache[to] = `contract{${++counter}}`) + else { + record.src = getCurrentContractName() + self.data._pendingCreation[timestamp] = record + } + record.from = addresses[from] || (addresses[from] = self._addressCache[from] = `account{${++counter}}`) self.append(timestamp, record) }) }) @@ -38,20 +48,32 @@ class Recorder { delete self.data._pendingCreation[timestamp] if (!record) return var to = args[2] - self._api.getAccounts(function (err, accounts = []) { - if (err) console.error(err) - if (to) record.to = self._addressCache[to] || (self._addressCache[to] = ``) + getAddresses(addresses => { + if (to) { + delete record.src + record.to = addresses[to] || (addresses[to] = self._addressCache[to] = `account{${++counter}}`) + } else record.src = getCurrentContractName() }) }) } - resolveAddress (record, accounts) { - if (record.to && record.to[0] === '<') record.to = accounts[record.to.split('>')[0].slice(11)] - if (record.from && record.from[0] === '<') record.from = accounts[record.from.split('>')[0].slice(11)] - // @TODO: change copy/paste to write and read from history file + resolveAddress (record, addresses) { + // var getPseudoAddress = placeholder => placeholder.split(' ')[0]//.split('-')[1].slice(1) + var pseudos = Object.keys(addresses).reduce((pseudos, address) => { + // var p = addresses[address]//getPseudoAddress()//.split('>')[0].split('-')[1].slice(1) + pseudos[addresses[address]] = address + return pseudos + }, {}) + if (record.to && record.to[0] !== '0') record.to = pseudos[record.to] + if (record.from && record.from[0] !== '0') record.from = pseudos[record.from] + + // @TODO: fix load transactions and execute ! + // @TODO: add 'clean' button to clear all recorded transactions + // @TODO: prefix path with `browser/` or `localhost/` if user provides + // @TODO: offer users by default a "save path" prefixed with the currently open file in the editor + // @TODO: offer users by default a "load path" prefixed with the currently open file in the editor (show first one that comes) // @TODO: writing browser test - // @TODO: replace addresses with custom ones (maybe address mapping file?) return record } append (timestamp, record) { @@ -61,11 +83,14 @@ class Recorder { getAll () { var self = this var records = [].concat(self.data.journal) - return records.sort((A, B) => { - var stampA = A.timestamp - var stampB = B.timestamp - return stampA - stampB - }) + return { + addresses: self._addressCache, + transactions: records.sort((A, B) => { + var stampA = A.timestamp + var stampB = B.timestamp + return stampA - stampB + }) + } } clearAll () { var self = this diff --git a/src/universal-dapp.js b/src/universal-dapp.js index 65359d0b7a..450d39204e 100644 --- a/src/universal-dapp.js +++ b/src/universal-dapp.js @@ -469,12 +469,10 @@ function execute (pipeline, env, callback) { UniversalDApp.prototype.rerunTx = function (args, cb) { var self = this - self.getAccounts(function (err, accounts = []) { - if (err) console.error(err) - var pipeline = [queryGasLimit, runTransaction] - var env = { self, args, tx: { to: args.to, from: args.from, data: args.data, useCall: args.useCall } } - execute(pipeline, env, cb) - }) + var tx = { to: args.to, from: args.from, data: args.data, useCall: args.useCall } + var pipeline = [queryGasLimit, runTransaction] + var env = { self, args, tx } + execute(pipeline, env, cb) } UniversalDApp.prototype.runTx = function (args, cb) {