Merge pull request #3707 from ethereum/script
Add 'web3 scripts' (to FE context menu)pull/3744/head
commit
4b8cec5791
@ -0,0 +1,29 @@ |
||||
import { ethers } from 'ethers' |
||||
|
||||
/** |
||||
* Deploy the given contract |
||||
* @param {string} contractName name of the contract to deploy |
||||
* @param {Array<any>} 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<any>, accountIndex?: number): Promise<ethers.Contract> => {
|
||||
|
||||
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 |
||||
} |
@ -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<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,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) |
||||
} |
@ -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) |
||||
} |
@ -0,0 +1,7 @@ |
||||
import { contractDeployerScripts } from '../scripts/contract-deployer' |
||||
import { etherscanScripts } from '../scripts/etherscan' |
||||
|
||||
export const scripts = { |
||||
'etherscan': etherscanScripts, |
||||
'deployer': contractDeployerScripts |
||||
} |
Loading…
Reference in new issue