add 'web2 scripts'

pull/3707/head
yann300 2 years ago
parent 4ecd635ad3
commit ee3159cc91
  1. 2
      apps/remix-ide/src/app/tabs/locales/en/filePanel.json
  2. 8
      libs/remix-ui/workspace/src/lib/actions/workspace.ts
  3. 6
      libs/remix-ui/workspace/src/lib/components/workspace-hamburger.tsx
  4. 1
      libs/remix-ui/workspace/src/lib/contexts/index.ts
  5. 9
      libs/remix-ui/workspace/src/lib/providers/FileSystemProvider.tsx
  6. 5
      libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
  7. 258
      libs/remix-ui/workspace/src/lib/scripts/contract-deployer/create2-factory-deploy.ts
  8. 6
      libs/remix-ui/workspace/src/lib/scripts/contract-deployer/index.ts
  9. 11
      libs/remix-ui/workspace/src/lib/scripts/etherscan/index.ts
  10. 8
      libs/remix-ui/workspace/src/lib/scripts/etherscan/receiptGuidScript.ts
  11. 13
      libs/remix-ui/workspace/src/lib/scripts/etherscan/verifyScript.ts

@ -29,6 +29,8 @@
"filePanel.tssoltestghaction": "Mocha Chai Test Workflow", "filePanel.tssoltestghaction": "Mocha Chai Test Workflow",
"filePanel.workspace.slitherghaction": "Adds a preset yml file to run slither analysis on github actions CI", "filePanel.workspace.slitherghaction": "Adds a preset yml file to run slither analysis on github actions CI",
"filePanel.slitherghaction": "Slither Workflow", "filePanel.slitherghaction": "Slither Workflow",
"filePanel.workspace.helperscripts": "Adds convenient scripts to the 'scripts' directory",
"filePanel.helperscripts": "Web3 Scripts",
"filePanel.newFile": "New File", "filePanel.newFile": "New File",
"filePanel.newFolder": "New Folder", "filePanel.newFolder": "New Folder",
"filePanel.rename": "Rename", "filePanel.rename": "Rename",

@ -13,6 +13,8 @@ import { ROOT_PATH, slitherYml, solTestYml, tsSolTestYml } from '../utils/consta
import { IndexedDBStorage } from '../../../../../../apps/remix-ide/src/app/files/filesystems/indexedDB' import { IndexedDBStorage } from '../../../../../../apps/remix-ide/src/app/files/filesystems/indexedDB'
import { getUncommittedFiles } from '../utils/gitStatusFilter' import { getUncommittedFiles } from '../utils/gitStatusFilter'
import { AppModal, ModalTypes } from '@remix-ui/app' import { AppModal, ModalTypes } from '@remix-ui/app'
import { contractDeployerScripts } from '../scripts/contract-deployer'
import { etherscanScripts } from '../scripts/etherscan'
declare global { declare global {
interface Window { remixFileSystemCallback: IndexedDBStorage; } interface Window { remixFileSystemCallback: IndexedDBStorage; }
@ -677,6 +679,12 @@ export const createSlitherGithubAction = async () => {
plugin.call('fileManager', 'open', path) plugin.call('fileManager', 'open', path)
} }
export const createHelperScripts = async () => {
await contractDeployerScripts(plugin)
await etherscanScripts(plugin)
plugin.call('notification', 'toast', 'scripts added in the "scripts" folder')
}
export const checkoutRemoteBranch = async (branch: string, remote: string) => { export const checkoutRemoteBranch = async (branch: string, remote: string) => {
const localChanges = await hasLocalChanges() const localChanges = await hasLocalChanges()

@ -15,6 +15,7 @@ export interface HamburgerMenuProps {
addGithubAction: () => void, addGithubAction: () => void,
addTsSolTestGithubAction: () => void, addTsSolTestGithubAction: () => void,
addSlitherGithubAction: () => void, addSlitherGithubAction: () => void,
addHelperScripts: () => void,
showIconsMenu: boolean, showIconsMenu: boolean,
hideWorkspaceOptions: boolean, hideWorkspaceOptions: boolean,
hideLocalhostOptions: boolean hideLocalhostOptions: boolean
@ -70,6 +71,11 @@ export function HamburgerMenu (props: HamburgerMenuProps) {
props.addSlitherGithubAction() props.addSlitherGithubAction()
props.hideIconsMenu(!showIconsMenu) props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem> }}></HamburgerMenuItem>
<Dropdown.Divider className="border mb-0 mt-0 remixui_menuhr" style={{ pointerEvents: 'none' }} />
<HamburgerMenuItem kind='helperscripts' fa='fak fa-ts-logo' hideOption={hideWorkspaceOptions} actionOnClick={() => {
props.addHelperScripts()
props.hideIconsMenu(!showIconsMenu)
}}></HamburgerMenuItem>
</> </>
) )
} }

@ -45,6 +45,7 @@ export const FileSystemContext = createContext<{
dispatchCreateSolidityGithubAction: () => Promise<void>, dispatchCreateSolidityGithubAction: () => Promise<void>,
dispatchCreateTsSolGithubAction: () => Promise<void>, dispatchCreateTsSolGithubAction: () => Promise<void>,
dispatchCreateSlitherGithubAction: () => Promise<void> dispatchCreateSlitherGithubAction: () => Promise<void>
dispatchCreateHelperScripts: () => Promise<void>
}>(null) }>(null)

@ -8,7 +8,7 @@ import { browserReducer, browserInitialState } from '../reducers/workspace'
import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, deleteAllWorkspaces, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder, import { initWorkspace, fetchDirectory, removeInputField, deleteWorkspace, deleteAllWorkspaces, clearPopUp, publishToGist, createNewFile, setFocusElement, createNewFolder,
deletePath, renamePath, downloadPath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace, deletePath, renamePath, downloadPath, copyFile, copyFolder, runScript, emitContextMenuEvent, handleClickFile, handleExpandPath, addInputField, createWorkspace,
fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, uploadFolder, handleDownloadWorkspace, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder, fetchWorkspaceDirectory, renameWorkspace, switchToWorkspace, uploadFile, uploadFolder, handleDownloadWorkspace, handleDownloadFiles, restoreBackupZip, cloneRepository, moveFile, moveFolder,
showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch, createSolidityGithubAction, createTsSolGithubAction, createSlitherGithubAction showAllBranches, switchBranch, createNewBranch, checkoutRemoteBranch, createSolidityGithubAction, createTsSolGithubAction, createSlitherGithubAction, createHelperScripts
} from '../actions' } from '../actions'
import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types' import { Modal, WorkspaceProps, WorkspaceTemplate } from '../types'
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
@ -183,6 +183,10 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
await createSlitherGithubAction() await createSlitherGithubAction()
} }
const dispatchCreateHelperScripts = async () => {
await createHelperScripts()
}
useEffect(() => { useEffect(() => {
dispatchInitWorkspace() dispatchInitWorkspace()
}, []) }, [])
@ -299,7 +303,8 @@ export const FileSystemProvider = (props: WorkspaceProps) => {
dispatchCheckoutRemoteBranch, dispatchCheckoutRemoteBranch,
dispatchCreateSolidityGithubAction, dispatchCreateSolidityGithubAction,
dispatchCreateTsSolGithubAction, dispatchCreateTsSolGithubAction,
dispatchCreateSlitherGithubAction dispatchCreateSlitherGithubAction,
dispatchCreateHelperScripts
} }
return ( return (
<FileSystemContext.Provider value={value}> <FileSystemContext.Provider value={value}>

@ -209,6 +209,10 @@ export function Workspace () {
global.dispatchCreateSlitherGithubAction() global.dispatchCreateSlitherGithubAction()
} }
const addHelperScripts = () => {
global.dispatchCreateHelperScripts()
}
const downloadWorkspaces = async () => { const downloadWorkspaces = async () => {
try { try {
await global.dispatchHandleDownloadFiles() await global.dispatchHandleDownloadFiles()
@ -726,6 +730,7 @@ export function Workspace () {
hideIconsMenu={hideIconsMenu} hideIconsMenu={hideIconsMenu}
addGithubAction={addGithubAction} addGithubAction={addGithubAction}
addSlitherGithubAction={addSlitherGithubAction} addSlitherGithubAction={addSlitherGithubAction}
addHelperScripts={addHelperScripts}
addTsSolTestGithubAction={addTsSolTestGithubAction} addTsSolTestGithubAction={addTsSolTestGithubAction}
showIconsMenu={showIconsMenu} showIconsMenu={showIconsMenu}
hideWorkspaceOptions={ currentWorkspace === LOCALHOST } hideWorkspaceOptions={ currentWorkspace === LOCALHOST }

@ -0,0 +1,258 @@
import { ethers } from 'ethers'
// https://etherscan.io/address/0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2#code
export const CREATE2_DEPLOYER_ADDRESS =
"0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2";
/**
* Deploy the given contract
* @param {string} address of the factory contract
* @param {string} contractName name of the contract to deploy
* @param {Array<any>} args list of constructor' parameters
* @param {number} salt (using during address generation)
* @param {number} accountIndex account index from the exposed account
* @return {string} deployed contract address
*/
export const deploy = async (contractName: string, args: Array<any>, salt: string, accountIndex?: number): Promise<string> => {
console.log(`deploying ${contractName}`)
const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner(accountIndex)
const factory = new ethers.Contract(CREATE2_DEPLOYER_ADDRESS, contractDeployerAbi, signer);
const contract = await ethers.getContractFactory(contractName)
const initCode = contract.getDeployTransaction(args)
const codeHash = ethers.utils.keccak256(initCode.data)
const saltBytes = ethers.utils.id(salt)
const deployedAddress = await factory.computeAddress(saltBytes, codeHash)
try {
const tx = await factory.deploy(0, saltBytes, initCode.data)
await tx.wait()
return deployedAddress
} catch (e) {
console.error(e.message)
console.error(`Please check a contract isn't already deployed at that address`)
throw e
}
}
export const contractDeployerAbi = [
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "Paused",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "Unpaused",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "codeHash",
"type": "bytes32"
}
],
"name": "computeAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "codeHash",
"type": "bytes32"
},
{
"internalType": "address",
"name": "deployer",
"type": "address"
}
],
"name": "computeAddressWithDeployer",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
},
{
"internalType": "bytes",
"name": "code",
"type": "bytes"
}
],
"name": "deploy",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "salt",
"type": "bytes32"
}
],
"name": "deployERC1820Implementer",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address payable",
"name": "payoutAddress",
"type": "address"
}
],
"name": "killCreate2Deployer",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pause",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "paused",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "unpause",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]

@ -0,0 +1,6 @@
export const contractDeployerScripts = async (plugin) => {
await plugin.call('fileManager', 'writeFile',
'scripts/contract-deployer/create2-factory-deploy.ts' ,
// @ts-ignore
(await import('!!raw-loader!./create2-factory-deploy.ts')).default)
}

@ -0,0 +1,11 @@
export const etherscanScripts = async (plugin) => {
await plugin.call('fileManager', 'writeFile',
'scripts/etherscan/verifyScript.ts' ,
// @ts-ignore
(await import('!!raw-loader!./verifyScript.ts')).default)
await plugin.call('fileManager', 'writeFile',
'scripts/etherscan/receiptGuidScript.ts' ,
// @ts-ignore
(await import('!!raw-loader!./receiptGuidScript.ts')).default)
}

@ -0,0 +1,8 @@
/**
* @param {string} apikey - etherscan api key.
* @param {string} guid - receipt id.
* @returns {{ status, message, succeed }} receiptStatus
*/
export const receiptStatus = async (apikey: string, guid: string) => {
return await remix.call('etherscan' as any, 'receiptStatus', guid, apikey)
}

@ -0,0 +1,13 @@
/**
* @param {string} apikey - etherscan api key.
* @param {string} contractAddress - Address of the contract to verify.
* @param {string} contractArguments - Parameters used in the contract constructor during the initial deployment. It should be the hex encoded value.
* @param {string} contractName - Name of the contract
* @param {string} contractFile - File where the contract is located
* @returns {{ guid, status, message, succeed }} verification result
*/
export const verify = async (apikey: string, contractAddress: string, contractArguments: string, contractName: string, contractFile: string) => {
const compilationResultParam = await remix.call('compilerArtefacts' as any, 'getCompilerAbstract', contractFile)
console.log('verifying.. ' + contractName)
return await remix.call('etherscan' as any, 'verify', apikey, contractAddress, contractArguments, contractName, compilationResultParam)
}
Loading…
Cancel
Save