diff --git a/apps/remix-ide/src/app/tabs/web3-provider.js b/apps/remix-ide/src/app/tabs/web3-provider.js index 4224106a39..42de424839 100644 --- a/apps/remix-ide/src/app/tabs/web3-provider.js +++ b/apps/remix-ide/src/app/tabs/web3-provider.js @@ -24,8 +24,15 @@ export class Web3ProviderModule extends Plugin { return new Promise((resolve, reject) => { const provider = this.blockchain.web3().currentProvider // see https://github.com/ethereum/web3.js/pull/1018/files#diff-d25786686c1053b786cc2626dc6e048675050593c0ebaafbf0814e1996f22022R129 - provider[provider.sendAsync ? 'sendAsync' : 'send'](payload, (error, message) => { + provider[provider.sendAsync ? 'sendAsync' : 'send'](payload, async (error, message) => { if (error) return reject(error) + if (payload.method === 'eth_sendTransaction') { + if (payload.params.length && !payload.params[0].to && message.result) { + const receipt = await this.call('blockchain', 'getTransactionReceipt', message.result) + const contractData = await this.call('compilerArtefacts', 'getContractDataFromAddress', receipt.contractAddress) + if (contractData) this.call('udapp', 'addInstance', receipt.contractAddress, contractData.contract.abi, contractData.name) + } + } resolve(message) }) }) diff --git a/apps/remix-ide/src/app/udapp/run-tab.js b/apps/remix-ide/src/app/udapp/run-tab.js index 05a015c4fc..313161b121 100644 --- a/apps/remix-ide/src/app/udapp/run-tab.js +++ b/apps/remix-ide/src/app/udapp/run-tab.js @@ -18,7 +18,7 @@ const profile = { version: packageJson.version, permission: true, events: ['newTransaction'], - methods: ['createVMAccount', 'sendTransaction', 'getAccounts', 'pendingTransactionsCount', 'getSettings', 'setEnvironmentMode'] + methods: ['createVMAccount', 'sendTransaction', 'getAccounts', 'pendingTransactionsCount', 'getSettings', 'setEnvironmentMode', 'clearAllInstances', 'addInstance'] } export class RunTab extends ViewPlugin { @@ -64,6 +64,14 @@ export class RunTab extends ViewPlugin { } } + clearAllInstances () { + this.emit('clearAllInstancesReducer') + } + + addInstance (address, abi, name) { + this.emit('addInstanceReducer', address, abi, name) + } + createVMAccount (newAccount) { return this.blockchain.createVMAccount(newAccount) } diff --git a/apps/remix-ide/src/blockchain/blockchain.js b/apps/remix-ide/src/blockchain/blockchain.js index 3382d3a649..705c3089bd 100644 --- a/apps/remix-ide/src/blockchain/blockchain.js +++ b/apps/remix-ide/src/blockchain/blockchain.js @@ -22,7 +22,7 @@ const profile = { name: 'blockchain', displayName: 'Blockchain', description: 'Blockchain - Logic', - methods: [], + methods: ['getCode', 'getTransactionReceipt'], version: packageJson.version } @@ -392,6 +392,14 @@ export class Blockchain extends Plugin { return Object.keys(this.txRunner.pendingTxs).length } + async getCode(address) { + return await this.web3().eth.getCode(address) + } + + async getTransactionReceipt (hash) { + return await this.web3().eth.getTransactionReceipt(hash) + } + /** * This function send a tx only to javascript VM or testnet, will return an error for the mainnet * SHOULD BE TAKEN CAREFULLY! diff --git a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts index df7a895bfc..24b0a6bee6 100644 --- a/libs/remix-core-plugin/src/lib/compiler-artefacts.ts +++ b/libs/remix-core-plugin/src/lib/compiler-artefacts.ts @@ -1,10 +1,11 @@ 'use strict' import { Plugin } from '@remixproject/engine' +import { util } from '@remix-project/remix-lib' import { CompilerAbstract } from '@remix-project/remix-solidity' const profile = { name: 'compilerArtefacts', - methods: ['get', 'addResolvedContract', 'getCompilerAbstract', 'getAllContractDatas', 'getLastCompilationResult', 'getArtefactsByContractName'], + methods: ['get', 'addResolvedContract', 'getCompilerAbstract', 'getAllContractDatas', 'getLastCompilationResult', 'getArtefactsByContractName', 'getContractDataFromAddress'], events: [], version: '0.0.1' } @@ -72,15 +73,27 @@ export class CompilerArtefacts extends Plugin { * @returns compilatin output */ getAllContractDatas () { + return this.filterAllContractDatas(() => true) + } + + /** + * filter compilation output for contracts compiled during a session of Remix IDE + * @returns compilatin output + */ + filterAllContractDatas (filter) { const contractsData = {} Object.keys(this.compilersArtefactsPerFile).map((targetFile) => { const contracts = this.compilersArtefactsPerFile[targetFile].getContracts() - Object.keys(contracts).map((file) => { contractsData[file] = contracts[file] }) + Object.keys(contracts).map((file) => { + if (filter(file, contracts[file])) contractsData[file] = contracts[file] + }) }) // making sure we save last compilation result in there if (this.compilersArtefacts.__last) { const contracts = this.compilersArtefacts.__last.getContracts() - Object.keys(contracts).map((file) => { contractsData[file] = contracts[file] }) + Object.keys(contracts).map((file) => { + if (filter(file, contracts[file])) contractsData[file] = contracts[file] + }) } return contractsData } @@ -182,4 +195,20 @@ export class CompilerArtefacts extends Plugin { get (key) { return this.compilersArtefacts[key] } + + async getContractDataFromAddress (address) { + const code = await this.call('blockchain', 'getCode', address) + let found + this.filterAllContractDatas((file, contractsData) => { + for (let name of Object.keys(contractsData)) { + const contract = contractsData[name] + if (util.compareByteCode(code, '0x' + contract.evm.deployedBytecode.object)) { + found = { name, contract } + return true + } + } + return true + }) + return found + } } diff --git a/libs/remix-core-plugin/src/lib/compiler-metadata.ts b/libs/remix-core-plugin/src/lib/compiler-metadata.ts index e7c5f3eec6..07f1996f90 100644 --- a/libs/remix-core-plugin/src/lib/compiler-metadata.ts +++ b/libs/remix-core-plugin/src/lib/compiler-metadata.ts @@ -42,6 +42,7 @@ export class CompilerMetadata extends Plugin { await this._setArtefacts(content, contract, path) })() }) + this.emit('artefactsUpdated') }) } @@ -103,7 +104,7 @@ export class CompilerMetadata extends Plugin { }, abi: contract.object.abi } - await this.call('fileManager', 'writeFile', fileName, JSON.stringify(data, null, '\t')) + await this.call('fileManager', 'writeFile', fileName, JSON.stringify(data, null, '\t')) } _syncContext (contract, metadata) { diff --git a/libs/remix-ui/run-tab/src/lib/actions/index.ts b/libs/remix-ui/run-tab/src/lib/actions/index.ts index 17ae11e4bb..6e0ebeae9c 100644 --- a/libs/remix-ui/run-tab/src/lib/actions/index.ts +++ b/libs/remix-ui/run-tab/src/lib/actions/index.ts @@ -83,6 +83,14 @@ const setupEvents = () => { setExecutionContext(env) }) + plugin.on('udapp', 'clearAllInstancesReducer', () => { + dispatch(clearAllInstances()) + }) + + plugin.on('udapp', 'addInstanceReducer', (address, abi, name) => { + addInstance({ abi, address, name }) + }) + plugin.on('filePanel', 'setWorkspace', () => { dispatch(resetUdapp()) resetAndInit() @@ -549,7 +557,7 @@ export const updateTxFeeContent = (content: string) => { dispatch(setTxFeeContent(content)) } -const addInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any, decodedResponse?: Record }) => { +export const addInstance = (instance: { contractData?: ContractData, address: string, name: string, abi?: any, decodedResponse?: Record }) => { instance.decodedResponse = {} dispatch(addNewInstance(instance)) }