add evmCheck

pull/5367/head
Joseph Izang 3 weeks ago committed by Aniket
parent 91850e4699
commit db26b53327
  1. 66
      libs/remix-ui/run-tab/src/lib/actions/evmmap.ts
  2. 13
      libs/remix-ui/run-tab/src/lib/components/contractGUI.tsx
  3. 13
      libs/remix-ui/run-tab/src/lib/components/environment.tsx
  4. 9
      libs/remix-ui/run-tab/src/lib/components/settingsUI.tsx
  5. 44
      libs/remix-ui/run-tab/src/lib/run-tab.tsx
  6. 2
      libs/remix-ui/run-tab/src/lib/types/index.ts

@ -3,6 +3,12 @@ export type ChainInfo = {
name: string name: string
} }
export type ChainCompatibleInfo = {
chain: ChainInfo
minCompilerVersion: string
evmVersion: HardFork
}
export type HardFork = export type HardFork =
| 'cancun' | 'cancun'
| 'shanghai' | 'shanghai'
@ -37,7 +43,8 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 534352, name: "Scroll" }, { id: 534352, name: "Scroll" },
{ id: 11155111, name: "Sepolia" } { id: 11155111, name: "Sepolia" }
], ],
minCompilerVersion: "0.8.24+commit.e11b9ed9" minCompilerVersion: "0.8.24+commit.e11b9ed9",
evmVersion: 'cancun'
}], }],
['shanghai', { ['shanghai', {
chainId: [ chainId: [
@ -65,11 +72,13 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 59141, name: "Linea Testnet" }, { id: 59141, name: "Linea Testnet" },
{ id: 59902, name: "Metis Sepolia Testnet" }, { id: 59902, name: "Metis Sepolia Testnet" },
{ id: 421614, name: "Arbitrum Sepolia" }, { id: 421614, name: "Arbitrum Sepolia" },
{ id: 534352, name: "Scroll" },
{ id: 11155111, name: "Sepolia" }, { id: 11155111, name: "Sepolia" },
{ id: 11155420, name: "Optimism Sepolia Testnet" }, { id: 11155420, name: "Optimism Sepolia Testnet" },
{ id: 1666600000, name: "Harmony Mainnet Shard 0" } { id: 1666600000, name: "Harmony Mainnet Shard 0" }
], ],
minCompilerVersion: "0.8.20+commit.a1b79de6" minCompilerVersion: "0.8.20+commit.a1b79de6",
evmVersion: 'shanghai'
}], }],
['paris', { ['paris', {
chainId: [ chainId: [
@ -99,11 +108,13 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 59141, name: "Linea Testnet" }, { id: 59141, name: "Linea Testnet" },
{ id: 59902, name: "Metis Sepolia Testnet" }, { id: 59902, name: "Metis Sepolia Testnet" },
{ id: 421614, name: "Arbitrum Sepolia" }, { id: 421614, name: "Arbitrum Sepolia" },
{ id: 534352, name: "Scroll" },
{ id: 11155111, name: "Sepolia" }, { id: 11155111, name: "Sepolia" },
{ id: 11155420, name: "Optimism Sepolia Testnet" }, { id: 11155420, name: "Optimism Sepolia Testnet" },
{ id: 1666600000, name: "Harmony Mainnet Shard 0" } { id: 1666600000, name: "Harmony Mainnet Shard 0" }
], ],
minCompilerVersion: "0.8.18+commit.87f61d96" minCompilerVersion: "0.8.18+commit.87f61d96",
evmVersion: 'paris'
}], }],
['london', { ['london', {
chainId: [ chainId: [
@ -123,7 +134,8 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 59141, name: "Linea Testnet" }, { id: 59141, name: "Linea Testnet" },
{ id: 11155111, name: "Sepolia" }, { id: 11155111, name: "Sepolia" },
], ],
minCompilerVersion: "0.8.7+commit.e28d00a7" minCompilerVersion: "0.8.7+commit.e28d00a7",
evmVersion: 'london'
}], }],
['berlin', { ['berlin', {
chainId: [ chainId: [
@ -143,7 +155,8 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 59141, name: "Linea Testnet" }, { id: 59141, name: "Linea Testnet" },
{ id: 11155111, name: "Sepolia" } { id: 11155111, name: "Sepolia" }
], ],
minCompilerVersion: "0.8.5+commit.a4f2e591" minCompilerVersion: "0.8.5+commit.a4f2e591",
evmVersion: 'berlin'
}], }],
['istanbul', { ['istanbul', {
chainId: [ chainId: [
@ -163,7 +176,8 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 59141, name: "Linea Testnet" }, { id: 59141, name: "Linea Testnet" },
{ id: 11155111, name: "Sepolia" } { id: 11155111, name: "Sepolia" }
], ],
minCompilerVersion: "0.5.14+commit.01f1aaa4" minCompilerVersion: "0.5.14+commit.01f1aaa4",
evmVersion: 'istanbul'
}], }],
['petersburg', { ['petersburg', {
chainId: [ chainId: [
@ -171,7 +185,8 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 5, name: "Goerli" }, { id: 5, name: "Goerli" },
{ id: 11155111, name: "Sepolia" } { id: 11155111, name: "Sepolia" }
], ],
minCompilerVersion: "0.5.5+commit.47a71e8f" minCompilerVersion: "0.5.5+commit.47a71e8f",
evmVersion: 'petersburg'
}], }],
['constantinople', { ['constantinople', {
chainId: [ chainId: [
@ -179,25 +194,29 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 5, name: "Goerli" }, { id: 5, name: "Goerli" },
{ id: 11155111, name: "Sepolia" } { id: 11155111, name: "Sepolia" }
], ],
minCompilerVersion: "0.5.5+commit.47a71e8f" minCompilerVersion: "0.5.5+commit.47a71e8f",
evmVersion: 'constantinople'
}], }],
['byzantium', { ['byzantium', {
chainId: [ chainId: [
{ id: 1, name: "Ethereum Mainnet" } { id: 1, name: "Ethereum Mainnet" }
], ],
minCompilerVersion: "0.4.21+commit.dfe3193c" minCompilerVersion: "0.4.21+commit.dfe3193c",
evmVersion: 'byzantium'
}], }],
['spuriousDragon', { ['spuriousDragon', {
chainId: [ chainId: [
{ id: 1, name: "Ethereum Mainnet" } { id: 1, name: "Ethereum Mainnet" }
], ],
minCompilerVersion: "0.4.9+commit.364da425" minCompilerVersion: "0.4.9+commit.364da425",
evmVersion: 'spuriousDragon'
}], }],
['tangerineWhistle', { ['tangerineWhistle', {
chainId: [ chainId: [
{ id: 1, name: "Ethereum Mainnet" } { id: 1, name: "Ethereum Mainnet" }
], ],
minCompilerVersion: "0.4.0+commit.acd334c9" minCompilerVersion: "0.4.0+commit.acd334c9",
evmVersion: 'tangerineWhistle'
}], }],
['homestead', { ['homestead', {
chainId: [ chainId: [
@ -205,7 +224,8 @@ export const evmMap: Map<HardFork, { chainId: ChainInfo[], minCompilerVersion: s
{ id: 5, name: "Goerli" }, { id: 5, name: "Goerli" },
{ id: 11155111, name: "Sepolia" } { id: 11155111, name: "Sepolia" }
], ],
minCompilerVersion: "0.1.2+commit.d0d36e3" minCompilerVersion: "0.1.2+commit.d0d36e3",
evmVersion: 'homestead'
}], }],
]) ])
@ -223,9 +243,21 @@ export function isChainCompatibleWithAnyFork(chainId: number, forks: HardFork[])
return forks.some(fork => isChainCompatible(fork, chainId)) return forks.some(fork => isChainCompatible(fork, chainId))
} }
export function getCompatibleChain(fork: HardFork, chainId: number): ChainInfo | undefined { export function getCompatibleChain(
const compatibleChains = getCompatibleChains(fork) fork: HardFork,
console.log('fork in getCompatibleChain', fork) chainId: number
console.log('compatibleChains', compatibleChains) ): ChainCompatibleInfo | undefined {
return compatibleChains.find(chain => chain.id === chainId) const forkData = evmMap.get(fork)
if (!forkData) return undefined
const compatibleChain = forkData.chainId.find(chain => chain.id === chainId)
if (compatibleChain) {
return {
chain: compatibleChain,
minCompilerVersion: forkData.minCompilerVersion,
evmVersion: fork
}
}
return undefined;
} }

@ -172,20 +172,9 @@ export function ContractGUI(props: ContractGUIProps) {
} }
} }
const checkUrlLocationForEvmVersion = async () => {
// if the evmVersion is not provided in the url, we use the default value
// and the default would be the latest evmFork, which is now cancun.
// checking both url and compiler details
const url = window.location.href
const regVersion = url.match(/evmVersion=([a-zA-Z]+)/)?.[1]
const fetched = await props.getCompilerDetails()
return { regVersion, fetched }
}
const handleActionClick = async () => { const handleActionClick = async () => {
props.getVersion() props.getVersion()
const { regVersion, fetched } = await checkUrlLocationForEvmVersion() await props.getCompilerDetails()
console.log('checkUrlLocationForEvmVersion', { regVersion, fetched })
if (deployState.deploy) { if (deployState.deploy) {
const proxyInitializeString = getMultiValsString(initializeFields.current) const proxyInitializeString = getMultiValsString(initializeFields.current)
props.clickCallBack(props.initializerOptions.inputs.inputs, proxyInitializeString, ['Deploy with Proxy']) props.clickCallBack(props.initializerOptions.inputs.inputs, proxyInitializeString, ['Deploy with Proxy'])

@ -11,6 +11,16 @@ export function EnvironmentUI(props: EnvironmentProps) {
Object.entries(props.providers.providerList.filter((provider) => { return provider.isInjected })) Object.entries(props.providers.providerList.filter((provider) => { return provider.isInjected }))
Object.entries(props.providers.providerList.filter((provider) => { return !(provider.isVM || provider.isInjected) })) Object.entries(props.providers.providerList.filter((provider) => { return !(provider.isVM || provider.isInjected) }))
const EvaluateSelectionForCorrectness = async () => {
// if the evmVersion is not provided in the url, we use the default value
// and the default would be the latest evmFork, which is now cancun.
// checking both url and compiler details
const url = window.location.href
const regVersion = url.match(/evmVersion=([a-zA-Z]+)/)?.[1]
const fetched = await props.checkSelectionCorrectness()
return { regVersion, fetched }
}
const handleChangeExEnv = (env: string) => { const handleChangeExEnv = (env: string) => {
const provider = props.providers.providerList.find((exEnv) => exEnv.name === env) const provider = props.providers.providerList.find((exEnv) => exEnv.name === env)
const context = provider.name const context = provider.name
@ -69,6 +79,9 @@ export function EnvironmentUI(props: EnvironmentProps) {
onClick={() => { onClick={() => {
handleChangeExEnv(name) handleChangeExEnv(name)
}} }}
onSelect={() => {
EvaluateSelectionForCorrectness()
}}
data-id={`dropdown-item-${name}`} data-id={`dropdown-item-${name}`}
> >
<span className=""> <span className="">

@ -1,5 +1,5 @@
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
import React from 'react' import React, { useEffect } from 'react'
import { SettingsProps } from '../types' import { SettingsProps } from '../types'
import { EnvironmentUI } from './environment' import { EnvironmentUI } from './environment'
import { NetworkUI } from './network' import { NetworkUI } from './network'
@ -10,9 +10,14 @@ import { ValueUI } from './value'
export function SettingsUI(props: SettingsProps) { export function SettingsUI(props: SettingsProps) {
// this._deps.config.events.on('settings/personal-mode_changed', this.onPersonalChange.bind(this)) // this._deps.config.events.on('settings/personal-mode_changed', this.onPersonalChange.bind(this))
useEffect(() => {
// listen for chainId change on window.ethereum and call EvaluateEnvironmentSelection
// (window as any).ethereum?.on('chainChanged', console.log('metamask did something')) //props.EvaluateEnvironmentSelection)
}, [])
return ( return (
<div className="udapp_settings"> <div className="udapp_settings">
<EnvironmentUI runTabPlugin={props.runTabPlugin} selectedEnv={props.selectExEnv} providers={props.providers} setExecutionContext={props.setExecutionContext} /> <EnvironmentUI runTabPlugin={props.runTabPlugin} selectedEnv={props.selectExEnv} providers={props.providers} setExecutionContext={props.setExecutionContext} checkSelectionCorrectness={props.EvaluateEnvironmentSelection} />
<NetworkUI networkName={props.networkName} /> <NetworkUI networkName={props.networkName} />
<AccountUI <AccountUI
addFile={props.addFile} addFile={props.addFile}

@ -56,7 +56,7 @@ import { PassphrasePrompt } from './components/passphrase'
import { MainnetPrompt } from './components/mainnet' import { MainnetPrompt } from './components/mainnet'
import { ScenarioPrompt } from './components/scenario' import { ScenarioPrompt } from './components/scenario'
import { setIpfsCheckedState, setRemixDActivated } from './actions/payload' import { setIpfsCheckedState, setRemixDActivated } from './actions/payload'
import { getCompatibleChain, getCompatibleChains, HardFork, isChainCompatible, isChainCompatibleWithAnyFork } from './actions/evmmap' import { ChainCompatibleInfo, getCompatibleChain, getCompatibleChains, HardFork, isChainCompatible, isChainCompatibleWithAnyFork } from './actions/evmmap'
export function RunTabUI(props: RunTabProps) { export function RunTabUI(props: RunTabProps) {
const { plugin } = props const { plugin } = props
@ -107,45 +107,34 @@ export function RunTabUI(props: RunTabProps) {
const getCompilerDetails = async () => await checkEvmChainCompatibility() const getCompilerDetails = async () => await checkEvmChainCompatibility()
const returnCompatibleChain = async (evmVersion: HardFork, targetChainId: number) => { const returnCompatibleChain = async (evmVersion: HardFork, targetChainId: number) => {
return getCompatibleChain(evmVersion ?? 'cancun', targetChainId) return getCompatibleChain(evmVersion ?? 'paris', targetChainId) // using paris evm as a default fallback version
} }
const checkEvmChainCompatibilityOkFunction = async (targetChainId: number, fetchDetails: any) => { const checkEvmChainCompatibilityOkFunction = async (fetchDetails: ChainCompatibleInfo) => {
const compilerParams = { const compilerParams = {
evmVersion: 'paris', evmVersion: fetchDetails.evmVersion,
optimize: false, optimize: false,
language: 'Solidity', language: 'Solidity',
runs: 200, runs: '200',
version: '0.8.27+commit.40a35a09' version: fetchDetails.minCompilerVersion
} }
await plugin.call('solidity', 'setCompilerConfig', compilerParams) await plugin.call('solidity', 'setCompilerConfig', compilerParams)
const compilerState = await plugin.call('solidity', 'getCompilerState')
console.log('compilerState', compilerState)
const currentFile = await plugin.call('fileManager', 'getCurrentFile') const currentFile = await plugin.call('fileManager', 'getCurrentFile')
await plugin.call('solidity', 'compile', currentFile) await plugin.call('solidity', 'compile', currentFile)
} }
const checkEvmChainCompatibilityCancelFunction = async (targetChainId: number, fetchDetails: any, currentFile: string) => {
() => {
console.log('cancel')
}
}
const checkEvmChainCompatibility = async () => { const checkEvmChainCompatibility = async () => {
const isVm = await plugin.call('blockchain', 'getProvider') // vms are exempt from this treatment const isVm = await plugin.call('blockchain', 'getProvider')
const fetchDetails = await plugin.call('solidity', 'getCompilerQueryParameters') //compiler details including evmVersion const fetchDetails = await plugin.call('solidity', 'getCompilerQueryParameters')
console.log('isVm', isVm) const compilerState = await plugin.call('solidity', 'getCompilerState')
if (!isVm.startsWith('vm')) { console.log('compilerState', compilerState)
console.log('runTab', runTab)
if (!isVm.startsWith('vm') && compilerState.target !== null) { //vms are exempt from this treatment & if no contract file is open, don't do anything
const targetChainId = runTab.chainId ? parseInt(runTab.chainId) : runTab.chainId const targetChainId = runTab.chainId ? parseInt(runTab.chainId) : runTab.chainId
console.log('targetChainId', runTab.chainId)
const IsCompatible = isChainCompatible(fetchDetails.evmVersion ?? 'cancun', targetChainId) const IsCompatible = isChainCompatible(fetchDetails.evmVersion ?? 'cancun', targetChainId)
console.log('evmVersion matches everywhere', fetchDetails.evmVersion)
console.log('compiler stuff', fetchDetails)
console.log('chain is compatible', IsCompatible)
const currentFile = await plugin.call('fileManager', 'getCurrentFile')
if (!IsCompatible) { if (!IsCompatible) {
console.log('chain is undefined') const chain = await returnCompatibleChain(fetchDetails.evmVersion, targetChainId)
console.log('chain obtained', { chain, targetChainId, fetchDetails })
//show modal //show modal
plugin.call('notification', 'modal', { plugin.call('notification', 'modal', {
id: 'evm-chainId-incompatible', id: 'evm-chainId-incompatible',
@ -161,8 +150,8 @@ export function RunTabUI(props: RunTabProps) {
modalType: 'modal', modalType: 'modal',
okLabel: 'Switch EVM and Recompile', okLabel: 'Switch EVM and Recompile',
cancelLabel: 'Cancel', cancelLabel: 'Cancel',
okFn: checkEvmChainCompatibilityOkFunction, okFn: () => checkEvmChainCompatibilityOkFunction(chain),
cancelFn: checkEvmChainCompatibilityCancelFunction cancelFn: () => {}
}) })
} }
} }
@ -351,6 +340,7 @@ export function RunTabUI(props: RunTabProps) {
networkName={runTab.networkName} networkName={runTab.networkName}
personalMode={runTab.personalMode} personalMode={runTab.personalMode}
selectExEnv={runTab.selectExEnv} selectExEnv={runTab.selectExEnv}
EvaluateEnvironmentSelection={checkEvmChainCompatibility}
accounts={runTab.accounts} accounts={runTab.accounts}
setAccount={setAccountAddress} setAccount={setAccountAddress}
setUnit={setUnitValue} setUnit={setUnitValue}

@ -125,6 +125,7 @@ export interface RunTabState {
export interface SettingsProps { export interface SettingsProps {
runTabPlugin: RunTab, runTabPlugin: RunTab,
selectExEnv: string, selectExEnv: string,
EvaluateEnvironmentSelection: any
accounts: { accounts: {
loadedAccounts: Record<string, any>, loadedAccounts: Record<string, any>,
selectedAccount: string, selectedAccount: string,
@ -159,6 +160,7 @@ export interface SettingsProps {
} }
export interface EnvironmentProps { export interface EnvironmentProps {
checkSelectionCorrectness: any
runTabPlugin: RunTab, runTabPlugin: RunTab,
selectedEnv: string, selectedEnv: string,
providers: { providers: {

Loading…
Cancel
Save