pull/5370/head
yann300 2 years ago committed by Aniket
parent bed774757a
commit 7f71b08231
  1. 3
      apps/remix-ide/src/app/tabs/locales/en/udapp.json
  2. 2
      apps/remix-ide/src/app/tabs/locales/zh/udapp.json
  3. 7
      libs/remix-core-plugin/src/types/contract.ts
  4. 89
      libs/remix-lib/src/execution/txFormat.ts
  5. 29
      libs/remix-ui/run-tab/src/lib/actions/deploy.ts
  6. 4
      libs/remix-ui/run-tab/src/lib/actions/index.ts
  7. 15
      libs/remix-ui/run-tab/src/lib/components/contractDropdownUI.tsx
  8. 4
      libs/remix-ui/run-tab/src/lib/types/index.ts

@ -27,7 +27,8 @@
"udapp.contractOptionsTitle3": "Select and compile *.sol file to deploy or access a contract.",
"udapp.contractOptionsTitle4": "When there is a compiled .sol file, choose the contract to deploy or to use with AtAddress.'",
"udapp.checkSumWarning": "It seems you are not using a checksumed address.A checksummed address is an address that contains uppercase letters, as specified in {a}.Checksummed addresses are meant to help prevent users from sending transactions to the wrong address.",
"udapp.isOverSizePrompt": "Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails. More info: {a}",
"udapp.isOverSizePromptEip170": "Contract creation initialization returns data with length of more than 24576 bytes. The deployment will likely fails. More info: {a}",
"udapp.isOverSizePromptEip3860": "Contract creation init code exceeds the allowed max code size of 49152 bytes. The deployment will likely fails. More info: {a}",
"udapp.thisContractMayBeAbstract": "This contract may be abstract, it may not implement an abstract parent's methods completely or it may not invoke an inherited contract's constructor correctly.",
"udapp.noCompiledContracts": "No compiled contracts",
"udapp.addressOfContract": "Address of contract",

@ -27,7 +27,7 @@
"udapp.contractOptionsTitle3": "选择并编译 *.sol 文件以部署或访问合约。",
"udapp.contractOptionsTitle4": "当有编译的 .sol 文件时,选择 {br} 合约进行部署或与 AtAddress 一起使用。",
"udapp.checkSumWarning": "您似乎没有使用 checksumed address 。{br} checksumed address 是包含大写字母的地址,如 {a} 中所指定。{br} checksumed address 旨在帮助防止用户将交易发送到错误地址。",
"udapp.isOverSizePrompt": "合约创建初始化返回长度超过24576字节的数据。部署可能会失败。 {br}更多信息:{a}",
"udapp.isOverSizePromptEip170": "合约创建初始化返回长度超过24576字节的数据。部署可能会失败。 {br}更多信息:{a}",
"udapp.thisContractMayBeAbstract": "这个合约可能是抽象的,它可能没有完全实现抽象父类的方法,或者它可能没有正确调用继承合约的构造函数。",
"udapp.noCompiledContracts": "没有已编译的合约",
"udapp.addressOfContract": "合约地址",

@ -8,6 +8,11 @@ export interface FuncABI {
constant?: any
}
export type OverSizeLimit = {
overSizeEip3860: boolean,
overSizeEip170: boolean
}
export interface ContractData {
name: string,
contract: any,
@ -19,7 +24,7 @@ export interface ContractData {
deployedBytecode: any,
getConstructorInterface: () => any,
getConstructorInputs: () => any,
isOverSizeLimit: () => boolean,
isOverSizeLimit: (args: string) => Promise<OverSizeLimit>,
metadata: any,
contractName?: string
}

@ -35,52 +35,59 @@ export function encodeData (funABI, values, contractbyteCode) {
* @param {Object} funAbi - abi definition of the function to call. null if building data for the ctor.
* @param {Function} callback - callback
*/
export function encodeParams (params, funAbi, callback) {
let data: Buffer | string = ''
let dataHex = ''
let funArgs = []
if (Array.isArray(params)) {
funArgs = params
if (funArgs.length > 0) {
export function encodeParams (params, funAbi, callback?) {
return new Promise((resolve, reject) => {
let data: Buffer | string = ''
let dataHex = ''
let funArgs = []
if (Array.isArray(params)) {
funArgs = params
if (funArgs.length > 0) {
try {
data = encodeParamsHelper(funAbi, funArgs)
dataHex = data.toString()
} catch (e) {
reject('Error encoding arguments: ' + e)
return callback && callback('Error encoding arguments: ' + e)
}
}
if (data.slice(0, 9) === 'undefined') {
dataHex = data.slice(9)
}
if (data.slice(0, 2) === '0x') {
dataHex = data.slice(2)
}
} else if (params.indexOf('raw:0x') === 0) {
// in that case we consider that the input is already encoded and *does not* contain the method signature
dataHex = params.replace('raw:0x', '')
data = Buffer.from(dataHex, 'hex')
} else {
try {
data = encodeParamsHelper(funAbi, funArgs)
dataHex = data.toString()
funArgs = parseFunctionParams(params)
} catch (e) {
return callback('Error encoding arguments: ' + e)
reject('Error encoding arguments: ' + e)
return callback && callback('Error encoding arguments: ' + e)
}
}
if (data.slice(0, 9) === 'undefined') {
dataHex = data.slice(9)
}
if (data.slice(0, 2) === '0x') {
dataHex = data.slice(2)
}
} else if (params.indexOf('raw:0x') === 0) {
// in that case we consider that the input is already encoded and *does not* contain the method signature
dataHex = params.replace('raw:0x', '')
data = Buffer.from(dataHex, 'hex')
} else {
try {
funArgs = parseFunctionParams(params)
} catch (e) {
return callback('Error encoding arguments: ' + e)
}
try {
if (funArgs.length > 0) {
data = encodeParamsHelper(funAbi, funArgs)
dataHex = data.toString()
try {
if (funArgs.length > 0) {
data = encodeParamsHelper(funAbi, funArgs)
dataHex = data.toString()
}
} catch (e) {
reject('Error encoding arguments: ' + e)
return callback && callback('Error encoding arguments: ' + e)
}
if (data.slice(0, 9) === 'undefined') {
dataHex = data.slice(9)
}
if (data.slice(0, 2) === '0x') {
dataHex = data.slice(2)
}
} catch (e) {
return callback('Error encoding arguments: ' + e)
}
if (data.slice(0, 9) === 'undefined') {
dataHex = data.slice(9)
}
if (data.slice(0, 2) === '0x') {
dataHex = data.slice(2)
}
}
callback(null, { data: data, dataHex: dataHex, funArgs: funArgs })
const result = { data: data, dataHex: dataHex, funArgs: funArgs }
callback && callback(null, result)
resolve(result)
})
}
/**

@ -1,4 +1,4 @@
import { ContractData, FuncABI, NetworkDeploymentFile, SolcBuildFile } from "@remix-project/core-plugin"
import { ContractData, FuncABI, NetworkDeploymentFile, SolcBuildFile, OverSizeLimit } from "@remix-project/core-plugin"
import { RunTab } from "../types/run-tab"
import { CompilerAbstract as CompilerAbstractType } from '@remix-project/remix-solidity'
import * as remixLib from '@remix-project/remix-lib'
@ -64,10 +64,19 @@ export const getSelectedContract = (contractName: string, compiler: CompilerAbst
return txHelper.inputParametersDeclarationToString(constructorInteface.inputs)
},
isOverSizeLimit: () => {
const deployedBytecode = contract.object.evm.deployedBytecode
isOverSizeLimit: async (args: string) => {
const encodedParams = await txFormat.encodeParams(args, txHelper.getConstructorInterface(contract.object.abi))
const bytecode = contract.object.evm.bytecode.object + (encodedParams as any).dataHex
// https://eips.ethereum.org/EIPS/eip-3860
const initCodeOversize = (bytecode && bytecode.length / 2 > 2 * 24576)
return (deployedBytecode && deployedBytecode.object.length / 2 > 24576)
const deployedBytecode = contract.object.evm.deployedBytecode
// https://eips.ethereum.org/EIPS/eip-170
const deployedBytecodeOversize = (deployedBytecode && deployedBytecode.object.length / 2 > 24576)
return {
overSizeEip3860: initCodeOversize,
overSizeEip170: deployedBytecodeOversize
}
},
metadata: contract.object.metadata
}
@ -135,7 +144,7 @@ export const createInstance = async (
publishToStorage: (storage: 'ipfs' | 'swarm',
contract: ContractData) => void,
mainnetPrompt: MainnetPrompt,
isOverSizePrompt: () => JSX.Element,
isOverSizePrompt: (values: OverSizeLimit) => JSX.Element,
args,
deployMode: DeployMode[]) => {
const isProxyDeployment = (deployMode || []).find(mode => mode === 'Deploy with Proxy')
@ -181,9 +190,11 @@ export const createInstance = async (
const compilerContracts = getCompilerContracts(plugin)
const confirmationCb = getConfirmationCb(plugin, dispatch, mainnetPrompt)
if (selectedContract.isOverSizeLimit()) {
return dispatch(displayNotification('Contract code size over limit', isOverSizePrompt(), 'Force Send', 'Cancel', () => {
deployContract(plugin, selectedContract, !isProxyDeployment && !isContractUpgrade ? args : '', contractMetadata, compilerContracts, {
args = !isProxyDeployment && !isContractUpgrade ? args : ''
const overSize = await selectedContract.isOverSizeLimit(args)
if (overSize.overSizeEip170 || overSize.overSizeEip3860) {
return dispatch(displayNotification('Contract code size over limit', isOverSizePrompt(overSize), 'Force Send', 'Cancel', () => {
deployContract(plugin, selectedContract, args, contractMetadata, compilerContracts, {
continueCb: (error, continueTxExecution, cancelCb) => {
continueHandler(dispatch, gasEstimationPrompt, error, continueTxExecution, cancelCb)
},
@ -199,7 +210,7 @@ export const createInstance = async (
return terminalLogger(plugin, log)
}))
}
deployContract(plugin, selectedContract, !isProxyDeployment && !isContractUpgrade ? args : '', contractMetadata, compilerContracts, {
deployContract(plugin, selectedContract, args, contractMetadata, compilerContracts, {
continueCb: (error, continueTxExecution, cancelCb) => {
continueHandler(dispatch, gasEstimationPrompt, error, continueTxExecution, cancelCb)
},

@ -8,7 +8,7 @@ import { clearInstances, clearPopUp, removeInstance, setAccount, setGasFee, setM
updateBaseFeePerGas, updateConfirmSettings, updateGasPrice, updateGasPriceStatus, updateMaxFee, updateMaxPriorityFee, updateScenarioPath } from './actions'
import { createInstance, getContext, getFuncABIInputs, getSelectedContract, loadAddress, runTransactions, updateInstanceBalance, syncContractsInternal, isValidContractAddress, isValidContractUpgrade } from './deploy'
import { CompilerAbstract as CompilerAbstractType } from '@remix-project/remix-solidity'
import { ContractData, FuncABI } from "@remix-project/core-plugin"
import { ContractData, FuncABI, OverSizeLimit } from "@remix-project/core-plugin"
import { DeployMode, MainnetPrompt } from '../types'
import { runCurrentScenario, storeScenario } from './recorder'
import { SolcInput, SolcOutput } from '@openzeppelin/upgrades-core'
@ -39,7 +39,7 @@ export const setPassphraseModal = (passphrase: string) => setPassphrasePrompt(di
export const setMatchPassphraseModal = (passphrase: string) => setMatchPassphrasePrompt(dispatch, passphrase)
export const signMessage = (account: string, message: string, modalContent: (hash: string, data: string) => JSX.Element, passphrase?: string) => signMessageWithAddress(plugin, dispatch, account, message, modalContent, passphrase)
export const fetchSelectedContract = (contractName: string, compiler: CompilerAbstractType) => getSelectedContract(contractName, compiler)
export const createNewInstance = async (selectedContract: ContractData, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, publishToStorage: (storage: 'ipfs' | 'swarm', contract: ContractData) => void, mainnetPrompt: MainnetPrompt, isOverSizePrompt: () => JSX.Element, args, deployMode: DeployMode[]) => createInstance(plugin, dispatch, selectedContract, gasEstimationPrompt, passphrasePrompt, publishToStorage, mainnetPrompt, isOverSizePrompt, args, deployMode)
export const createNewInstance = async (selectedContract: ContractData, gasEstimationPrompt: (msg: string) => JSX.Element, passphrasePrompt: (msg: string) => JSX.Element, publishToStorage: (storage: 'ipfs' | 'swarm', contract: ContractData) => void, mainnetPrompt: MainnetPrompt, isOverSizePrompt: (values: OverSizeLimit) => JSX.Element, args, deployMode: DeployMode[]) => createInstance(plugin, dispatch, selectedContract, gasEstimationPrompt, passphrasePrompt, publishToStorage, mainnetPrompt, isOverSizePrompt, args, deployMode)
export const setSendValue = (value: string) => setSendTransactionValue(dispatch, value)
export const setBaseFeePerGas = (baseFee: string) => updateBaseFeePerGas(dispatch, baseFee)
export const setConfirmSettings = (confirmation: boolean) => updateConfirmSettings(dispatch, confirmation)

@ -2,7 +2,7 @@
import React, { useEffect, useRef, useState } from 'react'
import { FormattedMessage, useIntl } from 'react-intl'
import { ContractDropdownProps, DeployMode } from '../types'
import { ContractData, FuncABI } from '@remix-project/core-plugin'
import { ContractData, FuncABI, OverSizeLimit} from '@remix-project/core-plugin'
import * as ethJSUtil from '@ethereumjs/util'
import { ContractGUI } from './contractGUI'
import { CustomTooltip, deployWithProxyMsg, upgradeWithProxyMsg } from '@remix-ui/helper'
@ -246,10 +246,19 @@ export function ContractDropdownUI (props: ContractDropdownProps) {
)
}
const isOverSizePrompt = () => {
const isOverSizePrompt = (values: OverSizeLimit) => {
return (
<div>
<FormattedMessage id='udapp.isOverSizePrompt' values={{ br: <br />, a: <a href="https://github.com/ethereum/EIPs/blob/master/EIPS/eip-170.md" target="_blank" rel="noreferrer">eip-170</a> }} />
{
values.overSizeEip170 && <div>
<FormattedMessage id='udapp.isOverSizePromptEip170' values={{ br: <br />, a: <a href="https://eips.ethereum.org/EIPS/eip-170" target="_blank" rel="noreferrer">eip-170</a> }} />
</div>
}
{
values.overSizeEip3860 && <div>
<FormattedMessage id='udapp.isOverSizePromptEip3860' values={{ br: <br />, a: <a href="https://eips.ethereum.org/EIPS/eip-3860" target="_blank" rel="noreferrer">eip-170</a> }} />
</div>
}
</div>
)
}

@ -1,6 +1,6 @@
import { Ref } from 'react'
import { CompilerAbstract } from '@remix-project/remix-solidity'
import { ContractData, FuncABI } from '@remix-project/core-plugin'
import { ContractData, FuncABI, OverSizeLimit } from '@remix-project/core-plugin'
import { RunTab } from './run-tab'
import { SolcInput, SolcOutput } from '@openzeppelin/upgrades-core'
import { LayoutCompatibilityReport } from '@openzeppelin/upgrades-core/dist/storage/report'
@ -250,7 +250,7 @@ export interface ContractDropdownProps {
publishToStorage: (storage: 'ipfs' | 'swarm',
contract: ContractData) => void,
mainnetPrompt: MainnetPrompt,
isOverSizePrompt: () => JSX.Element,
isOverSizePrompt: (values: OverSizeLimit) => JSX.Element,
args,
deployMode: DeployMode[]) => void,
ipfsCheckedState: boolean,

Loading…
Cancel
Save