decred.org/dcrdex@v1.0.5/client/asset/eth/cmd/deploy/main.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package main
     5  
     6  /*
     7  	deploy is a utility for deploying swap contracts. Examples of use:
     8  
     9  	1) Estimate the funding required to deploy a base asset swap contract to
    10  	   Ethereum
    11  		./deploy --mainnet --chain eth --fundingrequired
    12  	   This will use the current prevailing fee rate to estimate the fee
    13  	   requirements for the deployment transaction. The estimate is only
    14  	   accurate if there are already enough funds in the wallet (so estimateGas
    15  	   can be used), otherwise, a generously-padded constant is used to estimate
    16  	   the gas requirements.
    17  
    18  	2) Deploy a base asset swap contract to Ethereum.
    19  		./deploy --mainnet --chain eth
    20  
    21  	3) Deploy a token swap contract to Polygon.
    22  		./deploy --mainnet --chain polygon --tokenaddr 0x2791bca1f2de4661ed88a30c99a7a9449aa84174
    23  
    24  	4) Return remaining Sepolia testnet ETH balance to specified address.
    25  		./deploy --testnet --chain eth --returnaddr 0x18d65fb8d60c1199bb1ad381be47aa692b482605
    26  
    27  	IMPORTANT: deploy uses the same wallet configuration as getgas. See getgas
    28  	README for instructions.
    29  
    30  	5) Test reading of the Polygon credentials file.
    31  		./deploy --chain polygon --mainnet --readcreds
    32  */
    33  
    34  import (
    35  	"context"
    36  	"flag"
    37  	"fmt"
    38  	"os"
    39  	"os/user"
    40  	"path/filepath"
    41  	"strings"
    42  
    43  	"decred.org/dcrdex/client/asset"
    44  	"decred.org/dcrdex/client/asset/eth"
    45  	"decred.org/dcrdex/client/asset/polygon"
    46  	"decred.org/dcrdex/dex"
    47  	dexeth "decred.org/dcrdex/dex/networks/eth"
    48  	dexpolygon "decred.org/dcrdex/dex/networks/polygon"
    49  	"github.com/ethereum/go-ethereum/common"
    50  	"github.com/ethereum/go-ethereum/params"
    51  )
    52  
    53  func main() {
    54  	if err := mainErr(); err != nil {
    55  		fmt.Fprint(os.Stderr, err, "\n")
    56  		os.Exit(1)
    57  	}
    58  	os.Exit(0)
    59  }
    60  
    61  func mainErr() error {
    62  	ctx, cancel := context.WithCancel(context.Background())
    63  	defer cancel()
    64  
    65  	u, err := user.Current()
    66  	if err != nil {
    67  		return fmt.Errorf("could not get the current user: %w", err)
    68  	}
    69  	defaultCredentialsPath := filepath.Join(u.HomeDir, "dextest", "credentials.json")
    70  
    71  	var contractVerI int
    72  	var chain, credentialsPath, tokenAddress, returnAddr string
    73  	var useTestnet, useMainnet, useSimnet, trace, debug, readCreds, fundingReq, multiBal bool
    74  	flag.BoolVar(&readCreds, "readcreds", false, "does not run gas estimates. read the credentials file and print the address")
    75  	flag.BoolVar(&fundingReq, "fundingrequired", false, "does not run gas estimates. calculate the funding required by the wallet to get estimates")
    76  	flag.StringVar(&returnAddr, "return", "", "does not run gas estimates. return ethereum funds to supplied address")
    77  	flag.BoolVar(&useMainnet, "mainnet", false, "use mainnet")
    78  	flag.BoolVar(&useTestnet, "testnet", false, "use testnet")
    79  	flag.BoolVar(&useSimnet, "simnet", false, "use simnet")
    80  	flag.BoolVar(&trace, "trace", false, "trace logs")
    81  	flag.BoolVar(&debug, "debug", false, "debug logs")
    82  	flag.StringVar(&chain, "chain", "eth", "symbol of the base chain")
    83  	flag.StringVar(&tokenAddress, "tokenaddr", "", "launches an erc20-linked contract with this token. default launches a base chain contract")
    84  	flag.IntVar(&contractVerI, "ver", 0, "contract version")
    85  	flag.StringVar(&credentialsPath, "creds", defaultCredentialsPath, "path for JSON credentials file.")
    86  	flag.BoolVar(&multiBal, "multibalance", false, "deploy / estimate the MultiBalanceV0 contract instead of the swap contract")
    87  	flag.Parse()
    88  
    89  	if !useMainnet && !useTestnet && !useSimnet {
    90  		return fmt.Errorf("no network specified. add flag --mainnet, --testnet, or --simnet")
    91  	}
    92  	if (useMainnet && useTestnet) || (useMainnet && useSimnet) || (useTestnet && useSimnet) {
    93  		return fmt.Errorf("more than one network specified")
    94  	}
    95  
    96  	net := dex.Mainnet
    97  	if useSimnet {
    98  		net = dex.Simnet
    99  		dexeth.MaybeReadSimnetAddrs()
   100  		dexpolygon.MaybeReadSimnetAddrs()
   101  	}
   102  	if useTestnet {
   103  		net = dex.Testnet
   104  	}
   105  
   106  	if readCreds {
   107  		addr, providers, err := eth.GetGas.ReadCredentials(chain, credentialsPath, net)
   108  		if err != nil {
   109  			return err
   110  		}
   111  		fmt.Println("Credentials successfully parsed")
   112  		fmt.Println("Address:", addr)
   113  		fmt.Println("Providers:", strings.Join(providers, ", "))
   114  		return nil
   115  	}
   116  
   117  	assetID, found := dex.BipSymbolID(chain)
   118  	if !found {
   119  		return fmt.Errorf("asset %s not known", chain)
   120  	}
   121  
   122  	if tkn := asset.TokenInfo(assetID); tkn != nil {
   123  		return fmt.Errorf("specified chain is not a base chain. appears to be token %s", tkn.Name)
   124  	}
   125  
   126  	contractVer := uint32(contractVerI)
   127  
   128  	logLvl := dex.LevelInfo
   129  	if debug {
   130  		logLvl = dex.LevelDebug
   131  	}
   132  	if trace {
   133  		logLvl = dex.LevelTrace
   134  	}
   135  
   136  	var tokenAddr common.Address
   137  	if tokenAddress != "" {
   138  		if !common.IsHexAddress(tokenAddress) {
   139  			return fmt.Errorf("token address %q does not appear to be valid", tokenAddress)
   140  		}
   141  		tokenAddr = common.HexToAddress(tokenAddress)
   142  	}
   143  
   144  	log := dex.StdOutLogger("DEPLOY", logLvl)
   145  
   146  	var bui *dex.UnitInfo
   147  	var chainCfg *params.ChainConfig
   148  	switch chain {
   149  	case "eth":
   150  		bui = &dexeth.UnitInfo
   151  		chainCfg, err = eth.ChainConfig(net)
   152  		if err != nil {
   153  			return fmt.Errorf("error finding chain config: %v", err)
   154  		}
   155  	case "polygon":
   156  		bui = &dexpolygon.UnitInfo
   157  		chainCfg, err = polygon.ChainConfig(net)
   158  		if err != nil {
   159  			return fmt.Errorf("error finding chain config: %v", err)
   160  		}
   161  	}
   162  
   163  	switch {
   164  	case fundingReq:
   165  		if multiBal {
   166  			return eth.ContractDeployer.EstimateMultiBalanceDeployFunding(
   167  				ctx,
   168  				chain,
   169  				credentialsPath,
   170  				chainCfg,
   171  				bui,
   172  				log,
   173  				net,
   174  			)
   175  		}
   176  		return eth.ContractDeployer.EstimateDeployFunding(
   177  			ctx,
   178  			chain,
   179  			contractVer,
   180  			tokenAddr,
   181  			credentialsPath,
   182  			chainCfg,
   183  			bui,
   184  			log,
   185  			net,
   186  		)
   187  	case returnAddr != "":
   188  		if !common.IsHexAddress(returnAddr) {
   189  			return fmt.Errorf("return address %q is not valid", returnAddr)
   190  		}
   191  		addr := common.HexToAddress(returnAddr)
   192  		return eth.ContractDeployer.ReturnETH(ctx, chain, addr, credentialsPath, chainCfg, bui, log, net)
   193  	case multiBal:
   194  		return eth.ContractDeployer.DeployMultiBalance(
   195  			ctx,
   196  			chain,
   197  			credentialsPath,
   198  			chainCfg,
   199  			bui,
   200  			log,
   201  			net,
   202  		)
   203  	default:
   204  		return eth.ContractDeployer.DeployContract(
   205  			ctx,
   206  			chain,
   207  			contractVer,
   208  			tokenAddr,
   209  			credentialsPath,
   210  			chainCfg,
   211  			bui,
   212  			log,
   213  			net,
   214  		)
   215  	}
   216  }