-
-
-
- {currentWorkspace !== LOCALHOST ? (
- }
- >
- {
- e.stopPropagation()
- createWorkspace()
- _paq.push(['trackEvent', 'fileExplorer', 'workspaceMenu', 'workspaceCreate'])
- }}
- style={{ fontSize: 'medium' }}
- className='far fa-plus remixui_menuicon d-flex align-self-end'
- >
-
-
-
- ) : null}
+
+
+ {currentWorkspace !== LOCALHOST ? (
+
+ ) : null}
+
+
+
-
} args list of constructor' parameters
+ * @param {Number} accountIndex account index from the exposed account
+ * @return {Contract} deployed contract
+ */
+export const deploy = async (contractName: string, args: Array, accountIndex?: number): Promise => {
+
+ console.log(`deploying ${contractName}`)
+ // Note that the script needs the ABI which is generated from the compilation artifact.
+ // Make sure contract is compiled and artifacts are generated
+ const artifactsPath = `browser/contracts/artifacts/${contractName}.json` // Change this for different path
+
+ const metadata = JSON.parse(await remix.call('fileManager', 'getFile', artifactsPath))
+ // 'web3Provider' is a remix global variable object
+
+ const signer = (new ethers.providers.Web3Provider(web3Provider)).getSigner(accountIndex)
+
+ const factory = new ethers.ContractFactory(metadata.abi, metadata.data.bytecode.object, signer)
+
+ const contract = await factory.deploy(...args)
+
+ // The contract is NOT deployed yet; we must wait until it is mined
+ await contract.deployed()
+ return contract
+}
\ No newline at end of file
diff --git a/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/create2-factory-deploy.ts b/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/create2-factory-deploy.ts
new file mode 100644
index 0000000000..13b6d690a7
--- /dev/null
+++ b/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/create2-factory-deploy.ts
@@ -0,0 +1,258 @@
+import { ethers } from 'ethers'
+
+// https://etherscan.io/address/0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2#code
+export const CREATE2_DEPLOYER_ADDRESS =
+ "0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2";
+
+/**
+ * Deploy the given contract using a factory
+ * @param {string} address of the factory contract
+ * @param {string} contractName name of the contract to deploy
+ * @param {Array} 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, salt: string, accountIndex?: number): Promise => {
+
+ 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"
+ }
+]
\ No newline at end of file
diff --git a/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/index.ts b/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/index.ts
new file mode 100644
index 0000000000..0fbeeb1f48
--- /dev/null
+++ b/libs/remix-ui/workspace/src/lib/scripts/contract-deployer/index.ts
@@ -0,0 +1,11 @@
+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)
+
+ await plugin.call('fileManager', 'writeFile',
+ 'scripts/contract-deployer/basic-contract-deploy.ts' ,
+ // @ts-ignore
+ (await import('!!raw-loader!./basic-contract-deploy.ts')).default)
+}
\ No newline at end of file
diff --git a/libs/remix-ui/workspace/src/lib/scripts/etherscan/index.ts b/libs/remix-ui/workspace/src/lib/scripts/etherscan/index.ts
new file mode 100644
index 0000000000..34000b7ca2
--- /dev/null
+++ b/libs/remix-ui/workspace/src/lib/scripts/etherscan/index.ts
@@ -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)
+}
\ No newline at end of file
diff --git a/libs/remix-ui/workspace/src/lib/scripts/etherscan/receiptGuidScript.ts b/libs/remix-ui/workspace/src/lib/scripts/etherscan/receiptGuidScript.ts
new file mode 100644
index 0000000000..a09a9fb780
--- /dev/null
+++ b/libs/remix-ui/workspace/src/lib/scripts/etherscan/receiptGuidScript.ts
@@ -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)
+}
\ No newline at end of file
diff --git a/libs/remix-ui/workspace/src/lib/scripts/etherscan/verifyScript.ts b/libs/remix-ui/workspace/src/lib/scripts/etherscan/verifyScript.ts
new file mode 100644
index 0000000000..3531595239
--- /dev/null
+++ b/libs/remix-ui/workspace/src/lib/scripts/etherscan/verifyScript.ts
@@ -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)
+}
\ No newline at end of file
diff --git a/libs/remix-ui/workspace/src/lib/scripts/index.ts b/libs/remix-ui/workspace/src/lib/scripts/index.ts
new file mode 100644
index 0000000000..4f2c005e98
--- /dev/null
+++ b/libs/remix-ui/workspace/src/lib/scripts/index.ts
@@ -0,0 +1,7 @@
+import { contractDeployerScripts } from '../scripts/contract-deployer'
+import { etherscanScripts } from '../scripts/etherscan'
+
+export const scripts = {
+ 'etherscan': etherscanScripts,
+ 'deployer': contractDeployerScripts
+}
\ No newline at end of file