diff --git a/apps/remix-ide/src/blockchain/blockchain.js b/apps/remix-ide/src/blockchain/blockchain.js index 1a1c591833..c345231ce9 100644 --- a/apps/remix-ide/src/blockchain/blockchain.js +++ b/apps/remix-ide/src/blockchain/blockchain.js @@ -170,7 +170,7 @@ export class Blockchain extends Plugin { } const continueCb = (error, continueTxExecution, cancelCb) => { continueTxExecution() } const promptCb = (okCb, cancelCb) => { okCb() } - const finalCb = (error, txResult, address, returnValue) => { + const finalCb = async (error, txResult, address, returnValue) => { if (error) { const log = logBuilder(error) @@ -179,6 +179,7 @@ export class Blockchain extends Plugin { } if (networkInfo.name === 'VM') this.config.set('vm/proxy', address) else this.config.set(`${networkInfo.name}/${networkInfo.currentFork}/${networkInfo.id}/proxy`, address) + await this.saveDeployedContractStorageLayout(implementationContractObject, address, networkInfo) _paq.push(['trackEvent', 'blockchain', 'Deploy With Proxy', 'Proxy deployment successful']) this.call('udapp', 'addInstance', addressToString(address), implementationContractObject.abi, implementationContractObject.name) } @@ -209,25 +210,61 @@ export class Blockchain extends Plugin { async runUpgradeTx (proxyAddress, data, newImplementationContractObject) { const args = { useCall: false, data, to: proxyAddress } + let networkInfo const confirmationCb = (network, tx, gasEstimation, continueTxExecution, cancelCb) => { // continue using original authorization given by user + networkInfo = network continueTxExecution(null) } const continueCb = (error, continueTxExecution, cancelCb) => { continueTxExecution() } const promptCb = (okCb, cancelCb) => { okCb() } - const finalCb = (error, txResult, address, returnValue) => { + const finalCb = async (error, txResult, address, returnValue) => { if (error) { const log = logBuilder(error) _paq.push(['trackEvent', 'blockchain', 'Upgrade With Proxy', 'Upgrade failed']) return this.call('terminal', 'logHtml', log) } + await this.saveDeployedContractStorageLayout(newImplementationContractObject, proxyAddress, networkInfo) _paq.push(['trackEvent', 'blockchain', 'Upgrade With Proxy', 'Upgrade Successful']) this.call('udapp', 'addInstance', addressToString(proxyAddress), newImplementationContractObject.abi, newImplementationContractObject.name) } this.runTx(args, confirmationCb, continueCb, promptCb, finalCb) } + async saveDeployedContractStorageLayout (contractObject, proxyAddress, networkInfo) { + const { contractName, implementationAddress, contract } = contractObject + const hasPreviousDeploys = await this.call('fileManager', 'exists', `.deploys/upgradeable-contracts/${networkInfo.name}/UUPS.json`) + // TODO: make deploys folder read only. + if (hasPreviousDeploys) { + const deployments = await this.call('fileManager', 'readFile', `.deploys/upgradeable-contracts/${networkInfo.name}/UUPS.json`) + const parsedDeployments = JSON.parse(deployments) + + parsedDeployments.deployments[proxyAddress] = { + date: new Date().toISOString(), + contractName: contractName, + fork: networkInfo.currentFork, + implementationAddress: implementationAddress, + layout: contract.object.storageLayout + } + await this.call('fileManager', 'writeFile', `.deploys/upgradeable-contracts/${networkInfo.name}/UUPS.json`, JSON.stringify(parsedDeployments, null, 2)) + } else { + await this.call('fileManager', 'writeFile', `.deploys/upgradeable-contracts/${networkInfo.name}/UUPS.json`, JSON.stringify({ + id: networkInfo.id, + network: networkInfo.name, + deployments: { + [proxyAddress]: { + date: new Date().toISOString(), + contractName: contractName, + fork: networkInfo.currentFork, + implementationAddress: implementationAddress, + layout: contract.object.storageLayout + } + } + }, null, 2)) + } + } + async getEncodedFunctionHex (args, funABI) { return new Promise((resolve, reject) => { txFormat.encodeFunctionCall(args, funABI, (error, data) => { diff --git a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts index 9caa46e441..47db52425f 100644 --- a/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts +++ b/libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts @@ -100,6 +100,8 @@ export class OpenZeppelinProxy extends Plugin { } // re-use implementation contract's ABI for UI display in udapp and change name to proxy name. + implementationContractObject.contractName = implementationContractObject.name + implementationContractObject.implementationAddress = implAddress implementationContractObject.name = proxyName this.blockchain.deployProxy(data, implementationContractObject) } @@ -116,6 +118,8 @@ export class OpenZeppelinProxy extends Plugin { dataHex: fnData.replace('0x', '') } // re-use implementation contract's ABI for UI display in udapp and change name to proxy name. + newImplementationContractObject.contractName = newImplementationContractObject.name + newImplementationContractObject.implementationAddress = newImplAddress newImplementationContractObject.name = proxyName this.blockchain.upgradeProxy(proxyAddress, newImplAddress, data, newImplementationContractObject) } diff --git a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx index f0617adf6a..40c86aaec6 100644 --- a/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx +++ b/libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx @@ -1,7 +1,6 @@ // eslint-disable-next-line no-use-before-define import React, { useEffect, useRef, useState } from 'react' import * as remixLib from '@remix-project/remix-lib' -import Web3 from 'web3' import { ContractGUIProps } from '../types' import { CopyToClipboard } from '@remix-ui/clipboard' import { CustomTooltip } from '@remix-ui/helper'