UNPKG

@ethsub/sol-cli

Version:

A cli to interact with ethereum

335 lines (317 loc) 10.5 kB
const ethers = require("ethers"); const {Command} = require("commander"); const constants = require("../constants"); const {setupParentArgs, splitCommaList, isValidAddress} = require("./utils"); const deployCmd = new Command("deploy") .description("Deploys contracts via RPC") .option( "--chainId <value>", "Chain ID for the instance", constants.DEFAULT_SOURCE_ID ) .option( "--relayers <value>", "List of initial relayers", splitCommaList, constants.relayerAddresses ) .option( "--relayerThreshold <value>", "Number of votes required for a proposal to pass", 2 ) .option( "--fee <ether>", "Fee to be taken when making a deposit (decimals allowed)", 0 ) .option( "--expiry <blocks>", "Numer of blocks after which a proposal is considered cancelled", 100 ) .option("--all", "Deploy all contracts") .option("--bridge", "Deploy bridge contract") .option("--erc20Handler", "Deploy erc20Handler contract") .option("--erc721Handler", "Deploy erc721Handler contract") .option("--genericHandler", "Deploy genericHandler contract") .option( "--bridgeAddress <address>", "Bridge contract address for independent handler deployment", "" ) .option("--erc20", "Deploy erc20 contract") .option("--erc20Symbol <symbol>", "Name for the erc20 contract", "") .option("--erc20Name <name>", "Symbol for the erc20 contract", "") .option("--erc20Decimals <amount>", "Decimals for erc20 contract", 18) .option("--erc721", "Deploy erc721 contract") .option("--erc721Symbol <symbol>", "Name for the erc721 contract", "") .option("--erc721Name <name>", "Symbol for the erc721 contract", "") .option("--erc721BaseUri <uri>", "Base URI for the erc721 contract", "") .option("--chainAsset", "Deploy chain asset contract") .option("--weth", "Deploy wrapped ETH Erc20 contract") .option("--config", "Logs the configuration based on the deployment", false) .action(async (args) => { await setupParentArgs(args, args.parent); let startBal = await args.provider.getBalance(args.wallet.address); console.log("Deploying contracts..."); if (args.all) { await deployBridgeContract(args); await deployERC20Handler(args); await deployERC721Handler(args); await deployGenericHandler(args); await deployERC20(args); await deployERC721(args); await deployChainAssetStore(args); } else { let deployed = false; if (args.bridge) { await deployBridgeContract(args); deployed = true; } if (args.erc20Handler) { await deployERC20Handler(args); deployed = true; } if (args.erc721Handler) { await deployERC721Handler(args); deployed = true; } if (args.genericHandler) { await deployGenericHandler(args); deployed = true; } if (args.erc20) { await deployERC20(args); deployed = true; } if (args.erc721) { await deployERC721(args); deployed = true; } if (args.asset) { await deployChainAssetStore(args); deployed = true; } if (args.weth) { await deployWETH(args); deployed = true; } if (!deployed) { throw new Error("must specify --all or specific contracts to deploy"); } } args.cost = startBal.sub( await args.provider.getBalance(args.wallet.address) ); displayLog(args); if (args.config) { createConfig(args); } }); const createConfig = (args) => { const config = {}; config.name = "eth"; config.chainId = args.chainId; config.endpoint = args.url; config.bridge = args.bridgeAddress; config.erc20Handler = args.erc20HandlerContract; config.erc721Handler = args.erc721HandlerContract; config.genericHandler = args.genericHandlerContract; config.gasLimit = args.gasLimit.toNumber(); config.maxGasPrice = args.gasPrice.toNumber(); config.startBlock = "0"; config.http = "false"; config.relayers = args.relayers; const data = JSON.stringify(config, null, 4); console.log( "EVM Configuration, please copy this into your ChainBridge config file:" ); console.log(data); }; const displayLog = (args) => { console.log(` ================================================================ Url: ${args.url} Deployer: ${args.wallet.address} Gas Limit: ${ethers.BigNumber.from(args.gasLimit).toNumber()} Gas Price: ${ethers.BigNumber.from(args.gasPrice).toNumber()} Deploy Cost: ${ethers.utils.formatEther(args.cost)} Options ======= Chain Id: ${args.chainId} Threshold: ${args.relayerThreshold} Relayers: ${args.relayers} Bridge Fee: ${args.fee} Expiry: ${args.expiry} Contract Addresses ================================================================ Bridge: ${args.bridgeAddress ? args.bridgeAddress : "Not Deployed"} ---------------------------------------------------------------- Erc20 Handler: ${ args.erc20HandlerContract ? args.erc20HandlerContract : "Not Deployed" } ---------------------------------------------------------------- Erc721 Handler: ${ args.erc721HandlerContract ? args.erc721HandlerContract : "Not Deployed" } ---------------------------------------------------------------- Generic Handler: ${ args.genericHandlerContract ? args.genericHandlerContract : "Not Deployed" } ---------------------------------------------------------------- Erc20: ${args.erc20Contract ? args.erc20Contract : "Not Deployed"} ---------------------------------------------------------------- Erc721: ${ args.erc721Contract ? args.erc721Contract : "Not Deployed" } ---------------------------------------------------------------- Chain Asset: ${ args.chainAssetStoreContract ? args.chainAssetStoreContract : "Not Deployed" } ---------------------------------------------------------------- WETH: ${args.WETHContract ? args.WETHContract : "Not Deployed"} ================================================================ `); }; async function deployBridgeContract(args) { // Create an instance of a Contract Factory let factory = new ethers.ContractFactory( constants.ContractABIs.Bridge.abi, constants.ContractABIs.Bridge.bytecode, args.wallet ); // Deploy let contract = await factory.deploy( args.chainId, args.relayers, args.relayerThreshold, ethers.utils.parseEther(args.fee.toString()), args.expiry, {gasPrice: args.gasPrice, gasLimit: args.gasLimit} ); await contract.deployed(); args.bridgeAddress = contract.address; console.log("✓ Bridge contract deployed"); } async function deployERC20(args) { const factory = new ethers.ContractFactory( constants.ContractABIs.Erc20Mintable.abi, constants.ContractABIs.Erc20Mintable.bytecode, args.wallet ); const contract = await factory.deploy( args.erc20Name, args.erc20Symbol, args.erc20Decimals, {gasPrice: args.gasPrice, gasLimit: args.gasLimit} ); await contract.deployed(); args.erc20Contract = contract.address; console.log("✓ ERC20 contract deployed"); } async function deployERC20Handler(args) { if (!isValidAddress(args.bridgeAddress)) { console.log( "ERC20Handler contract failed to deploy due to invalid bridge address" ); return; } const factory = new ethers.ContractFactory( constants.ContractABIs.Erc20Handler.abi, constants.ContractABIs.Erc20Handler.bytecode, args.wallet ); const contract = await factory.deploy(args.bridgeAddress, { gasPrice: args.gasPrice, gasLimit: args.gasLimit, }); await contract.deployed(); args.erc20HandlerContract = contract.address; console.log("✓ ERC20Handler contract deployed"); } async function deployERC721(args) { const factory = new ethers.ContractFactory( constants.ContractABIs.Erc721Mintable.abi, constants.ContractABIs.Erc721Mintable.bytecode, args.wallet ); const contract = await factory.deploy( args.erc721Name, args.erc721Symbol, args.erc721BaseUri, {gasPrice: args.gasPrice, gasLimit: args.gasLimit} ); await contract.deployed(); args.erc721Contract = contract.address; console.log("✓ ERC721 contract deployed"); } async function deployERC721Handler(args) { if (!isValidAddress(args.bridgeAddress)) { console.log( "ERC721Handler contract failed to deploy due to invalid bridge address" ); return; } const factory = new ethers.ContractFactory( constants.ContractABIs.Erc721Handler.abi, constants.ContractABIs.Erc721Handler.bytecode, args.wallet ); const contract = await factory.deploy(args.bridgeAddress, { gasPrice: args.gasPrice, gasLimit: args.gasLimit, }); await contract.deployed(); args.erc721HandlerContract = contract.address; console.log("✓ ERC721Handler contract deployed"); } async function deployGenericHandler(args) { if (!isValidAddress(args.bridgeAddress)) { console.log( "GenericHandler contract failed to deploy due to invalid bridge address" ); return; } const factory = new ethers.ContractFactory( constants.ContractABIs.GenericHandler.abi, constants.ContractABIs.GenericHandler.bytecode, args.wallet ); const contract = await factory.deploy(args.bridgeAddress, { gasPrice: args.gasPrice, gasLimit: args.gasLimit, }); await contract.deployed(); args.genericHandlerContract = contract.address; console.log("✓ GenericHandler contract deployed"); } async function deployChainAssetStore(args) { const factory = new ethers.ContractFactory( constants.ContractABIs.ChainAssetStore.abi, constants.ContractABIs.ChainAssetStore.bytecode, args.wallet ); const contract = await factory.deploy({ gasPrice: args.gasPrice, gasLimit: args.gasLimit, }); await contract.deployed(); args.chainAssetStoreContract = contract.address; console.log("✓ ChainAssetStore contract deployed"); } async function deployWETH(args) { const factory = new ethers.ContractFactory( constants.ContractABIs.WETH.abi, constants.ContractABIs.WETH.bytecode, args.wallet ); const contract = await factory.deploy({ gasPrice: args.gasPrice, gasLimit: args.gasLimit, }); await contract.deployed(); args.WETHContract = contract.address; console.log("✓ WETH contract deployed"); } module.exports = deployCmd;