github.com/Finschia/finschia-sdk@v0.49.1/x/genutil/client/cli/init.go (about)

     1  package cli
     2  
     3  import (
     4  	"bufio"
     5  	"encoding/json"
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	cfg "github.com/Finschia/ostracon/config"
    11  	"github.com/Finschia/ostracon/libs/cli"
    12  	ostos "github.com/Finschia/ostracon/libs/os"
    13  	ostrand "github.com/Finschia/ostracon/libs/rand"
    14  	"github.com/Finschia/ostracon/types"
    15  	"github.com/cosmos/go-bip39"
    16  	"github.com/pkg/errors"
    17  	"github.com/spf13/cobra"
    18  
    19  	"github.com/Finschia/finschia-sdk/client"
    20  	"github.com/Finschia/finschia-sdk/client/flags"
    21  	"github.com/Finschia/finschia-sdk/client/input"
    22  	"github.com/Finschia/finschia-sdk/server"
    23  	sdk "github.com/Finschia/finschia-sdk/types"
    24  	"github.com/Finschia/finschia-sdk/types/module"
    25  	"github.com/Finschia/finschia-sdk/x/genutil"
    26  )
    27  
    28  const (
    29  	// FlagOverwrite defines a flag to overwrite an existing genesis JSON file.
    30  	FlagOverwrite = "overwrite"
    31  
    32  	// FlagSeed defines a flag to initialize the private validator key from a specific seed.
    33  	FlagRecover = "recover"
    34  )
    35  
    36  type printInfo struct {
    37  	Moniker    string          `json:"moniker" yaml:"moniker"`
    38  	ChainID    string          `json:"chain_id" yaml:"chain_id"`
    39  	NodeID     string          `json:"node_id" yaml:"node_id"`
    40  	GenTxsDir  string          `json:"gentxs_dir" yaml:"gentxs_dir"`
    41  	AppMessage json.RawMessage `json:"app_message" yaml:"app_message"`
    42  }
    43  
    44  func newPrintInfo(moniker, chainID, nodeID, genTxsDir string, appMessage json.RawMessage) printInfo {
    45  	return printInfo{
    46  		Moniker:    moniker,
    47  		ChainID:    chainID,
    48  		NodeID:     nodeID,
    49  		GenTxsDir:  genTxsDir,
    50  		AppMessage: appMessage,
    51  	}
    52  }
    53  
    54  func displayInfo(info printInfo) error {
    55  	out, err := json.MarshalIndent(info, "", " ")
    56  	if err != nil {
    57  		return err
    58  	}
    59  
    60  	_, err = fmt.Fprintf(os.Stderr, "%s\n", string(sdk.MustSortJSON(out)))
    61  
    62  	return err
    63  }
    64  
    65  // InitCmd returns a command that initializes all files needed for Tendermint
    66  // and the respective application.
    67  func InitCmd(mbm module.BasicManager, defaultNodeHome string) *cobra.Command {
    68  	cmd := &cobra.Command{
    69  		Use:   "init [moniker]",
    70  		Short: "Initialize private validator, p2p, genesis, and application configuration files",
    71  		Long:  `Initialize validators's and node's configuration files.`,
    72  		Args:  cobra.ExactArgs(1),
    73  		RunE: func(cmd *cobra.Command, args []string) error {
    74  			clientCtx := client.GetClientContextFromCmd(cmd)
    75  			cdc := clientCtx.Codec
    76  
    77  			serverCtx := server.GetServerContextFromCmd(cmd)
    78  			config := serverCtx.Config
    79  			config.SetRoot(clientCtx.HomeDir)
    80  
    81  			chainID, _ := cmd.Flags().GetString(flags.FlagChainID)
    82  			if chainID == "" {
    83  				chainID = fmt.Sprintf("test-chain-%v", ostrand.Str(6))
    84  			}
    85  
    86  			// Get bip39 mnemonic
    87  			var mnemonic string
    88  			recover, _ := cmd.Flags().GetBool(FlagRecover)
    89  			if recover {
    90  				inBuf := bufio.NewReader(cmd.InOrStdin())
    91  				value, err := input.GetString("Enter your bip39 mnemonic", inBuf)
    92  				if err != nil {
    93  					return err
    94  				}
    95  
    96  				mnemonic = value
    97  				if !bip39.IsMnemonicValid(mnemonic) {
    98  					return errors.New("invalid mnemonic")
    99  				}
   100  			}
   101  
   102  			nodeID, _, err := genutil.InitializeNodeValidatorFilesFromMnemonic(config, mnemonic)
   103  			if err != nil {
   104  				return err
   105  			}
   106  
   107  			config.Moniker = args[0]
   108  
   109  			genFile := config.GenesisFile()
   110  			overwrite, _ := cmd.Flags().GetBool(FlagOverwrite)
   111  
   112  			if !overwrite && ostos.FileExists(genFile) {
   113  				return fmt.Errorf("genesis.json file already exists: %v", genFile)
   114  			}
   115  
   116  			appState, err := json.MarshalIndent(mbm.DefaultGenesis(cdc), "", " ")
   117  			if err != nil {
   118  				return errors.Wrap(err, "Failed to marshall default genesis state")
   119  			}
   120  
   121  			genDoc := &types.GenesisDoc{}
   122  			if _, err := os.Stat(genFile); err != nil {
   123  				if !os.IsNotExist(err) {
   124  					return err
   125  				}
   126  			} else {
   127  				genDoc, err = types.GenesisDocFromFile(genFile)
   128  				if err != nil {
   129  					return errors.Wrap(err, "Failed to read genesis doc from file")
   130  				}
   131  			}
   132  
   133  			genDoc.ChainID = chainID
   134  			genDoc.Validators = nil
   135  			genDoc.AppState = appState
   136  
   137  			if err = genutil.ExportGenesisFile(genDoc, genFile); err != nil {
   138  				return errors.Wrap(err, "Failed to export gensis file")
   139  			}
   140  
   141  			toPrint := newPrintInfo(config.Moniker, chainID, nodeID, "", appState)
   142  
   143  			cfg.WriteConfigFile(filepath.Join(config.RootDir, "config", "config.toml"), config)
   144  			return displayInfo(toPrint)
   145  		},
   146  	}
   147  
   148  	cmd.Flags().String(cli.HomeFlag, defaultNodeHome, "node's home directory")
   149  	cmd.Flags().BoolP(FlagOverwrite, "o", false, "overwrite the genesis.json file")
   150  	cmd.Flags().Bool(FlagRecover, false, "provide seed phrase to recover existing key instead of creating")
   151  	cmd.Flags().String(flags.FlagChainID, "", "genesis file chain-id, if left blank will be randomly created")
   152  
   153  	return cmd
   154  }