github.com/ChainSafe/chainbridge-core@v1.4.2/chains/evm/cli/deploy/deploy.go (about) 1 package deploy 2 3 import ( 4 "errors" 5 "fmt" 6 "math/big" 7 8 "github.com/ChainSafe/chainbridge-core/chains/evm/calls" 9 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/bridge" 10 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/erc20" 11 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/erc721" 12 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/contracts/generic" 13 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/evmclient" 14 evmgaspricer "github.com/ChainSafe/chainbridge-core/chains/evm/calls/evmgaspricer" 15 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/evmtransaction" 16 "github.com/ChainSafe/chainbridge-core/chains/evm/calls/transactor/signAndSend" 17 18 "github.com/ChainSafe/chainbridge-core/chains/evm/cli/flags" 19 "github.com/ChainSafe/chainbridge-core/chains/evm/cli/logger" 20 "github.com/ChainSafe/chainbridge-core/chains/evm/cli/utils" 21 "github.com/ethereum/go-ethereum/common" 22 "github.com/rs/zerolog/log" 23 "github.com/spf13/cobra" 24 ) 25 26 var ErrNoDeploymentFlagsProvided = errors.New("provide at least one deployment flag. For help use --help") 27 28 var DeployEVM = &cobra.Command{ 29 Use: "deploy", 30 Short: "Deploy smart contracts", 31 Long: "This command can be used to deploy all or some of the contracts required for bridging. Selection of contracts can be made by either specifying --all or a subset of flags", 32 PreRun: func(cmd *cobra.Command, args []string) { 33 logger.LoggerMetadata(cmd.Name(), cmd.Flags()) 34 }, 35 RunE: CallDeployCLI, 36 Args: func(cmd *cobra.Command, args []string) error { 37 err := ValidateDeployFlags(cmd, args) 38 if err != nil { 39 return err 40 } 41 err = ProcessDeployFlags(cmd, args) 42 return err 43 }, 44 } 45 46 const ( 47 TwoDaysTermInBlocks int64 = 6200 48 ) 49 50 var ( 51 // Flags for all EVM Deploy CLI commands 52 Bridge bool 53 BridgeAddress string 54 DeployAll bool 55 DomainId uint8 56 GenericHandler bool 57 Erc20 bool 58 Erc20Handler bool 59 Erc20Name string 60 Erc20Symbol string 61 Erc721 bool 62 Erc721Handler bool 63 Erc721Name string 64 Erc721Symbol string 65 Erc721BaseURI string 66 Fee uint64 67 RelayerThreshold uint64 68 Relayers []string 69 ) 70 71 func BindDeployEVMFlags(cmd *cobra.Command) { 72 cmd.Flags().BoolVar(&Bridge, "bridge", false, "Deploy bridge") 73 cmd.Flags().StringVar(&BridgeAddress, "bridge-address", "", "Bridge contract address. Should be provided if handlers are deployed separately") 74 cmd.Flags().BoolVar(&DeployAll, "all", false, "Deploy all") 75 cmd.Flags().Uint8Var(&DomainId, "domain", 1, "Domain ID for the instance") 76 cmd.Flags().BoolVar(&Erc20, "erc20", false, "Deploy ERC20") 77 cmd.Flags().BoolVar(&Erc20Handler, "erc20-handler", false, "Deploy ERC20 handler") 78 cmd.Flags().StringVar(&Erc20Name, "erc20-name", "", "ERC20 contract name") 79 cmd.Flags().StringVar(&Erc20Symbol, "erc20-symbol", "", "ERC20 contract symbol") 80 cmd.Flags().BoolVar(&Erc721, "erc721", false, "Deploy ERC721") 81 cmd.Flags().BoolVar(&Erc721Handler, "erc721-handler", false, "Deploy ERC721 handler") 82 cmd.Flags().StringVar(&Erc721Name, "erc721-name", "", "ERC721 contract name") 83 cmd.Flags().StringVar(&Erc721Symbol, "erc721-symbol", "", "ERC721 contract symbol") 84 cmd.Flags().StringVar(&Erc721BaseURI, "erc721-base-uri", "", "ERC721 base URI") 85 cmd.Flags().BoolVar(&GenericHandler, "generic-handler", false, "Deploy generic handler") 86 cmd.Flags().Uint64Var(&Fee, "fee", 0, "Fee to be taken when making a deposit (in ETH, decimals are allowed)") 87 cmd.Flags().StringSliceVar(&Relayers, "relayers", []string{}, "List of initial relayers") 88 cmd.Flags().Uint64Var(&RelayerThreshold, "relayer-threshold", 1, "Number of votes required for a proposal to pass") 89 } 90 91 func init() { 92 BindDeployEVMFlags(DeployEVM) 93 } 94 95 func ValidateDeployFlags(cmd *cobra.Command, args []string) error { 96 Deployments = make([]string, 0) 97 if DeployAll { 98 flags.MarkFlagsAsRequired(cmd, "relayer-threshold", "domain", "fee", "erc20-symbol", "erc20-name") 99 Deployments = append(Deployments, []string{"bridge", "erc20-handler", "erc721-handler", "generic-handler", "erc20", "erc721"}...) 100 } else { 101 if Bridge { 102 flags.MarkFlagsAsRequired(cmd, "relayer-threshold", "domain", "fee") 103 Deployments = append(Deployments, "bridge") 104 } 105 if Erc20Handler { 106 if !Bridge { 107 flags.MarkFlagsAsRequired(cmd, "bridge-address") 108 } 109 Deployments = append(Deployments, "erc20-handler") 110 } 111 if Erc721Handler { 112 if !Bridge { 113 flags.MarkFlagsAsRequired(cmd, "bridge-address") 114 } 115 Deployments = append(Deployments, "erc721-handler") 116 } 117 if GenericHandler { 118 if !Bridge { 119 flags.MarkFlagsAsRequired(cmd, "bridge-address") 120 } 121 Deployments = append(Deployments, "generic-handler") 122 } 123 if Erc20 { 124 flags.MarkFlagsAsRequired(cmd, "erc20-symbol", "erc20-name") 125 Deployments = append(Deployments, "erc20") 126 } 127 if Erc721 { 128 flags.MarkFlagsAsRequired(cmd, "erc721-name", "erc721-symbol", "erc721-base-uri") 129 Deployments = append(Deployments, "erc721") 130 } 131 } 132 133 if len(Deployments) == 0 { 134 log.Error().Err(ErrNoDeploymentFlagsProvided) 135 return ErrNoDeploymentFlagsProvided 136 } 137 138 return nil 139 } 140 141 var Deployments []string 142 var BridgeAddr common.Address 143 var RelayerAddresses []common.Address 144 145 func ProcessDeployFlags(cmd *cobra.Command, args []string) error { 146 if common.IsHexAddress(BridgeAddress) { 147 BridgeAddr = common.HexToAddress(BridgeAddress) 148 } 149 for _, addr := range Relayers { 150 if !common.IsHexAddress(addr) { 151 return fmt.Errorf("invalid relayer address %s", addr) 152 } 153 RelayerAddresses = append(RelayerAddresses, common.HexToAddress(addr)) 154 } 155 return nil 156 } 157 158 func CallDeployCLI(cmd *cobra.Command, args []string) error { 159 txFabric := evmtransaction.NewTransaction 160 return DeployCLI(cmd, args, txFabric, &evmgaspricer.LondonGasPriceDeterminant{}) 161 } 162 163 func DeployCLI(cmd *cobra.Command, args []string, txFabric calls.TxFabric, gasPricer utils.GasPricerWithPostConfig) error { 164 // fetch global flag values 165 url, gasLimit, gasPrice, senderKeyPair, _, err := flags.GlobalFlagValues(cmd) 166 if err != nil { 167 return err 168 } 169 170 log.Debug().Msgf("url: %s gas limit: %v gas price: %v", url, gasLimit, gasPrice) 171 log.Debug().Msgf("SENDER Address %s", senderKeyPair.CommonAddress().Hex()) 172 173 ethClient, err := evmclient.NewEVMClient(url, senderKeyPair) 174 if err != nil { 175 log.Error().Err(fmt.Errorf("ethereum client error: %v", err)).Msg("error initializing new EVM client") 176 return err 177 } 178 gasPricer.SetClient(ethClient) 179 gasPricer.SetOpts(&evmgaspricer.GasPricerOpts{UpperLimitFeePerGas: gasPrice}) 180 log.Debug().Msgf("Relayers for deploy %+v", Relayers) 181 log.Debug().Msgf("all bool: %v", DeployAll) 182 183 t := signAndSend.NewSignAndSendTransactor(txFabric, gasPricer, ethClient) 184 185 deployedContracts := make(map[string]string) 186 for _, v := range Deployments { 187 switch v { 188 case "bridge": 189 log.Debug().Msgf("deploying bridge..") 190 bc := bridge.NewBridgeContract(ethClient, common.Address{}, t) 191 BridgeAddr, err = bc.DeployContract( 192 DomainId, 193 RelayerAddresses, 194 big.NewInt(0).SetUint64(RelayerThreshold), 195 big.NewInt(0).SetUint64(Fee), 196 big.NewInt(TwoDaysTermInBlocks), // _expiry is set to 48 hours by default 197 ) 198 if err != nil { 199 log.Error().Err(fmt.Errorf("bridge deploy failed: %w", err)) 200 return err 201 } 202 deployedContracts["bridge"] = BridgeAddr.String() 203 log.Debug().Msgf("bridge address; %v", BridgeAddr.String()) 204 case "erc20": 205 log.Debug().Msgf("deploying ERC20..") 206 erc20Contract := erc20.NewERC20Contract(ethClient, common.Address{}, t) 207 erc20Addr, err := erc20Contract.DeployContract(Erc20Name, Erc20Symbol) 208 if err != nil { 209 log.Error().Err(fmt.Errorf("erc 20 deploy failed: %w", err)) 210 return err 211 } 212 deployedContracts["erc20Token"] = erc20Addr.String() 213 case "erc20-handler": 214 log.Debug().Msgf("deploying ERC20 handler..") 215 erc20HandlerContract := erc20.NewERC20HandlerContract(ethClient, common.Address{}, t) 216 erc20HandlerAddr, err := erc20HandlerContract.DeployContract(BridgeAddr) 217 if err != nil { 218 log.Error().Err(fmt.Errorf("ERC20 handler deploy failed: %w", err)) 219 return err 220 } 221 deployedContracts["erc20Handler"] = erc20HandlerAddr.String() 222 case "erc721": 223 log.Debug().Msgf("deploying ERC721..") 224 erc721Contract := erc721.NewErc721Contract(ethClient, common.Address{}, t) 225 erc721Addr, err := erc721Contract.DeployContract(Erc721Name, Erc721Symbol, Erc721BaseURI) 226 if err != nil { 227 log.Error().Err(fmt.Errorf("ERC721 deploy failed: %w", err)) 228 return err 229 } 230 deployedContracts["erc721Token"] = erc721Addr.String() 231 case "erc721-handler": 232 log.Debug().Msgf("deploying ERC721 handler..") 233 erc721HandlerContract := erc721.NewERC721HandlerContract(ethClient, common.Address{}, t) 234 erc721HandlerAddr, err := erc721HandlerContract.DeployContract(BridgeAddr) 235 if err != nil { 236 log.Error().Err(fmt.Errorf("ERC721 handler deploy failed: %w", err)) 237 return err 238 } 239 deployedContracts["erc721Handler"] = erc721HandlerAddr.String() 240 case "generic-handler": 241 log.Debug().Msgf("deploying generic handler..") 242 emptyAddr := common.Address{} 243 if BridgeAddr == emptyAddr { 244 log.Error().Err(errors.New("bridge flag or bridge-address param should be set for contracts Deployments")) 245 return err 246 } 247 genericHandlerContract := generic.NewGenericHandlerContract(ethClient, common.Address{}, t) 248 genericHandlerAddr, err := genericHandlerContract.DeployContract(BridgeAddr) 249 if err != nil { 250 log.Error().Err(fmt.Errorf("Generic handler deploy failed: %w", err)) 251 return err 252 } 253 deployedContracts["genericHandler"] = genericHandlerAddr.String() 254 } 255 } 256 fmt.Printf(` 257 Deployed contracts 258 ========================================================= 259 Bridge: %s 260 --------------------------------------------------------- 261 ERC20 Token: %s 262 --------------------------------------------------------- 263 ERC20 Handler: %s 264 --------------------------------------------------------- 265 ERC721 Token: %s 266 --------------------------------------------------------- 267 ERC721 Handler: %s 268 --------------------------------------------------------- 269 Generic Handler: %s 270 ========================================================= 271 `, 272 deployedContracts["bridge"], 273 deployedContracts["erc20Token"], 274 deployedContracts["erc20Handler"], 275 deployedContracts["erc721Token"], 276 deployedContracts["erc721Handler"], 277 deployedContracts["genericHandler"], 278 ) 279 return nil 280 }