diff --git a/apps/etherscan/src/app/RemixPlugin.tsx b/apps/etherscan/src/app/RemixPlugin.tsx new file mode 100644 index 0000000000..0000e73b82 --- /dev/null +++ b/apps/etherscan/src/app/RemixPlugin.tsx @@ -0,0 +1,25 @@ +import { PluginClient } from '@remixproject/plugin'; +import { verify, EtherScanReturn } from './utils/verify'; +import { getReceiptStatus, getEtherScanApi, getNetworkName } from './utils'; + +export class RemixClient extends PluginClient { + + loaded() { + return this.onload() + } + + async verify (apiKey: string, contractAddress: string, contractArguments: string, contractName: string, compilationResultParam: any) { + const result = await verify(apiKey, contractAddress, contractArguments, contractName, compilationResultParam, this, + (value: EtherScanReturn) => {}, (value: string) => {}) + return result + } + + async receiptStatus (receiptGuid: string, apiKey: string) { + const network = await getNetworkName(this) + if (network === "vm") { + throw new Error("Cannot check the receip status in the selected network") + } + const etherscanApi = getEtherScanApi(network) + return getReceiptStatus(receiptGuid, apiKey, etherscanApi) + } +} diff --git a/apps/etherscan/src/app/utils/verify.ts b/apps/etherscan/src/app/utils/verify.ts new file mode 100644 index 0000000000..1de8b3da06 --- /dev/null +++ b/apps/etherscan/src/app/utils/verify.ts @@ -0,0 +1,164 @@ +import { getNetworkName, getEtherScanApi, getReceiptStatus } from "../utils" +import { CompilationResult } from "@remixproject/plugin-api" +import axios from 'axios' +import { PluginClient } from "@remixproject/plugin" + +const resetAfter10Seconds = (client: PluginClient, setResults: (value: string) => void) => { + setTimeout(() => { + client.emit("statusChanged", { key: "none" }) + setResults("") + }, 10000) + } + +export type EtherScanReturn = { + guid: any, + status: any, +} +export const verify = async ( + apiKeyParam: string, + contractAddress: string, + contractArgumentsParam: string, + contractName: string, + compilationResultParam: any, + client: PluginClient, + onVerifiedContract: (value: EtherScanReturn) => void, + setResults: (value: string) => void + ) => { + const network = await getNetworkName(client) + if (network === "vm") { + return { + succeed: false, + message: "Cannot verify in the selected network" + } + } + const etherscanApi = getEtherScanApi(network) + + try { + const contractMetadata = getContractMetadata( + compilationResultParam.data, + contractName + ) + + if (!contractMetadata) { + return { + succeed: false, + message: "Please recompile contract" + } + } + + const contractMetadataParsed = JSON.parse(contractMetadata) + + const fileName = getContractFileName( + compilationResultParam.data, + contractName + ) + + const jsonInput = { + language: 'Solidity', + sources: compilationResultParam.source.sources, + settings: { + optimizer: { + enabled: contractMetadataParsed.settings.optimizer.enabled, + runs: contractMetadataParsed.settings.optimizer.runs + } + } + } + + const data: { [key: string]: string | any } = { + apikey: apiKeyParam, // A valid API-Key is required + module: "contract", // Do not change + action: "verifysourcecode", // Do not change + codeformat: "solidity-standard-json-input", + contractaddress: contractAddress, // Contract Address starts with 0x... + sourceCode: JSON.stringify(jsonInput), + contractname: fileName + ':' + contractName, + compilerversion: `v${contractMetadataParsed.compiler.version}`, // see http://etherscan.io/solcversions for list of support versions + constructorArguements: contractArgumentsParam, // if applicable + } + + const body = new FormData() + Object.keys(data).forEach((key) => body.append(key, data[key])) + + client.emit("statusChanged", { + key: "loading", + type: "info", + title: "Verifying ...", + }) + const response = await axios.post(etherscanApi, body) + const { message, result, status } = await response.data + + if (message === "OK" && status === "1") { + resetAfter10Seconds(client, setResults) + const receiptStatus = await getReceiptStatus( + result, + apiKeyParam, + etherscanApi + ) + + const returnValue = { + guid: result, + status: receiptStatus, + message: `Contract verified correctly. Receipt GUID ${result}`, + succeed: true + } + onVerifiedContract(returnValue) + return returnValue + } + if (message === "NOTOK") { + client.emit("statusChanged", { + key: "failed", + type: "error", + title: result, + }) + const returnValue = { + status: result, + message: `Contract not verified`, + succeed: false + } + resetAfter10Seconds(client, setResults) + return returnValue + } + return result + } catch (error) { + console.error(error) + setResults("Something wrong happened, try again") + } + } + + export const getContractFileName = ( + compilationResult: CompilationResult, + contractName: string + ) => { + const compiledContracts = compilationResult.contracts + let fileName = "" + + for (const file of Object.keys(compiledContracts)) { + for (const contract of Object.keys(compiledContracts[file])) { + if (contract === contractName) { + fileName = file + break + } + } + } + return fileName + } + + export const getContractMetadata = ( + compilationResult: CompilationResult, + contractName: string + ) => { + const compiledContracts = compilationResult.contracts + let contractMetadata = "" + + for (const file of Object.keys(compiledContracts)) { + for (const contract of Object.keys(compiledContracts[file])) { + if (contract === contractName) { + contractMetadata = compiledContracts[file][contract].metadata + if (contractMetadata) { + break + } + } + } + } + return contractMetadata + } \ No newline at end of file diff --git a/apps/etherscan/src/app/views/VerifyView.tsx b/apps/etherscan/src/app/views/VerifyView.tsx index 3e85d471b7..34173f2345 100644 --- a/apps/etherscan/src/app/views/VerifyView.tsx +++ b/apps/etherscan/src/app/views/VerifyView.tsx @@ -5,11 +5,9 @@ import { } from "@remixproject/plugin" import { Formik, ErrorMessage, Field } from "formik" -import { getNetworkName, getEtherScanApi, getReceiptStatus } from "../utils" import { SubmitButton } from "../components" import { Receipt } from "../types" -import { CompilationResult } from "@remixproject/plugin-api" -import axios from 'axios' +import { verify } from "../utils/verify" interface Props { client: PluginClient @@ -24,43 +22,7 @@ interface FormValues { contractAddress: string } -export const getContractFileName = ( - compilationResult: CompilationResult, - contractName: string -) => { - const compiledContracts = compilationResult.contracts - let fileName = "" - - for (const file of Object.keys(compiledContracts)) { - for (const contract of Object.keys(compiledContracts[file])) { - if (contract === contractName) { - fileName = file - break - } - } - } - return fileName -} - -export const getContractMetadata = ( - compilationResult: CompilationResult, - contractName: string -) => { - const compiledContracts = compilationResult.contracts - let contractMetadata = "" - for (const file of Object.keys(compiledContracts)) { - for (const contract of Object.keys(compiledContracts[file])) { - if (contract === contractName) { - contractMetadata = compiledContracts[file][contract].metadata - if (contractMetadata) { - break - } - } - } - } - return contractMetadata -} export const VerifyView: React.FC = ({ apiKey, @@ -80,117 +42,20 @@ export const VerifyView: React.FC = ({ throw new Error("no compilation result available") } - const contractArguments = values.contractArguments.replace("0x", "") - - const verify = async ( - apiKeyParam: string, - contractAddress: string, - contractArgumentsParam: string, - contractName: string, - compilationResultParam: any - ) => { - const network = await getNetworkName(client) - if (network === "vm") { - return "Cannot verify in the selected network" - } - const etherscanApi = getEtherScanApi(network) - - try { - const contractMetadata = getContractMetadata( - compilationResultParam.data, - contractName - ) - - if (!contractMetadata) { - return "Please recompile contract" - } - - const contractMetadataParsed = JSON.parse(contractMetadata) - - const fileName = getContractFileName( - compilationResultParam.data, - contractName - ) - - const jsonInput = { - language: 'Solidity', - sources: compilationResultParam.source.sources, - settings: { - optimizer: { - enabled: contractMetadataParsed.settings.optimizer.enabled, - runs: contractMetadataParsed.settings.optimizer.runs - } - } - } - - const data: { [key: string]: string | any } = { - apikey: apiKeyParam, // A valid API-Key is required - module: "contract", // Do not change - action: "verifysourcecode", // Do not change - codeformat: "solidity-standard-json-input", - contractaddress: contractAddress, // Contract Address starts with 0x... - sourceCode: JSON.stringify(jsonInput), - contractname: fileName + ':' + contractName, - compilerversion: `v${contractMetadataParsed.compiler.version}`, // see http://etherscan.io/solcversions for list of support versions - constructorArguements: contractArgumentsParam, // if applicable - } - - const body = new FormData() - Object.keys(data).forEach((key) => body.append(key, data[key])) - - client.emit("statusChanged", { - key: "loading", - type: "info", - title: "Verifying ...", - }) - const response = await axios.post(etherscanApi, body) - const { message, result, status } = await response.data - - if (message === "OK" && status === "1") { - resetAfter10Seconds() - const receiptStatus = await getReceiptStatus( - result, - apiKey, - etherscanApi - ) - - onVerifiedContract({ - guid: result, - status: receiptStatus, - }) - return `Contract verified correctly
Receipt GUID ${result}` - } - if (message === "NOTOK") { - client.emit("statusChanged", { - key: "failed", - type: "error", - title: result, - }) - resetAfter10Seconds() - } - return result - } catch (error) { - console.error(error) - setResults("Something wrong happened, try again") - } - } - - const resetAfter10Seconds = () => { - setTimeout(() => { - client.emit("statusChanged", { key: "none" }) - setResults("") - }, 10000) - } + const contractArguments = values.contractArguments.replace("0x", "") const verificationResult = await verify( apiKey, values.contractAddress, contractArguments, values.contractName, - compilationResult + compilationResult, + client, + onVerifiedContract, + setResults, ) - setResults(verificationResult) + setResults(verificationResult.message) } return ( diff --git a/libs/remix-debug/src/debugger/VmDebugger.ts b/libs/remix-debug/src/debugger/VmDebugger.ts index 91d7e54d0a..19a8be3d51 100644 --- a/libs/remix-debug/src/debugger/VmDebugger.ts +++ b/libs/remix-debug/src/debugger/VmDebugger.ts @@ -119,7 +119,6 @@ export class VmDebuggerLogic { } catch (error) { this.event.trigger('traceManagerMemoryUpdate', [{}]) } - try { const address = this._traceManager.getCurrentCalledAddressAt(index) if (!this.storageResolver) return