github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/x/gov/client/cli/tx.go (about)

     1  package cli
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/spf13/cobra"
    10  
    11  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client"
    12  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/context"
    13  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/client/flags"
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    15  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    16  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/version"
    17  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth"
    18  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/auth/client/utils"
    19  	govutils "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/client/utils"
    20  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/gov/types"
    21  )
    22  
    23  // Proposal flags
    24  const (
    25  	FlagTitle        = "title"
    26  	FlagDescription  = "description"
    27  	flagProposalType = "type"
    28  	FlagDeposit      = "deposit"
    29  	flagVoter        = "voter"
    30  	flagDepositor    = "depositor"
    31  	flagStatus       = "status"
    32  	FlagProposal     = "proposal"
    33  )
    34  
    35  type proposal struct {
    36  	Title       string
    37  	Description string
    38  	Type        string
    39  	Deposit     string
    40  }
    41  
    42  // ProposalFlags defines the core required fields of a proposal. It is used to
    43  // verify that these values are not provided in conjunction with a JSON proposal
    44  // file.
    45  var ProposalFlags = []string{
    46  	FlagTitle,
    47  	FlagDescription,
    48  	flagProposalType,
    49  	FlagDeposit,
    50  }
    51  
    52  // GetTxCmd returns the transaction commands for this module
    53  // governance ModuleClient is slightly different from other ModuleClients in that
    54  // it contains a slice of "proposal" child commands. These commands are respective
    55  // to proposal type handlers that are implemented in other modules but are mounted
    56  // under the governance CLI (eg. parameter change proposals).
    57  func GetTxCmd(storeKey string, cdc *codec.Codec, pcmds []*cobra.Command) *cobra.Command {
    58  	govTxCmd := &cobra.Command{
    59  		Use:                        types.ModuleName,
    60  		Short:                      "Governance transactions subcommands",
    61  		DisableFlagParsing:         true,
    62  		SuggestionsMinimumDistance: 2,
    63  		RunE:                       client.ValidateCmd,
    64  	}
    65  
    66  	cmdSubmitProp := GetCmdSubmitProposal(cdc)
    67  	for _, pcmd := range pcmds {
    68  		cmdSubmitProp.AddCommand(flags.PostCommands(pcmd)[0])
    69  	}
    70  
    71  	govTxCmd.AddCommand(flags.PostCommands(
    72  		GetCmdDeposit(cdc),
    73  		GetCmdVote(cdc),
    74  		cmdSubmitProp,
    75  	)...)
    76  
    77  	return govTxCmd
    78  }
    79  
    80  // GetCmdSubmitProposal implements submitting a proposal transaction command.
    81  func GetCmdSubmitProposal(cdc *codec.Codec) *cobra.Command {
    82  	cmd := &cobra.Command{
    83  		Use:   "submit-proposal",
    84  		Short: "Submit a proposal along with an initial deposit",
    85  		Long: strings.TrimSpace(
    86  			fmt.Sprintf(`Submit a proposal along with an initial deposit.
    87  Proposal title, description, type and deposit can be given directly or through a proposal JSON file.
    88  
    89  Example:
    90  $ %s tx gov submit-proposal --proposal="path/to/proposal.json" --from mykey
    91  
    92  Where proposal.json contains:
    93  
    94  {
    95    "title": "Test Proposal",
    96    "description": "My awesome proposal",
    97    "type": "Text",
    98    "deposit": "10test"
    99  }
   100  
   101  Which is equivalent to:
   102  
   103  $ %s tx gov submit-proposal --title="Test Proposal" --description="My awesome proposal" --type="Text" --deposit="10test" --from mykey
   104  `,
   105  				version.ClientName, version.ClientName,
   106  			),
   107  		),
   108  		RunE: func(cmd *cobra.Command, args []string) error {
   109  			inBuf := bufio.NewReader(cmd.InOrStdin())
   110  			txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
   111  			cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc)
   112  
   113  			proposal, err := parseSubmitProposalFlags()
   114  			if err != nil {
   115  				return err
   116  			}
   117  
   118  			amount, err := sdk.ParseCoins(proposal.Deposit)
   119  			if err != nil {
   120  				return err
   121  			}
   122  
   123  			content := types.ContentFromProposalType(proposal.Title, proposal.Description, proposal.Type)
   124  
   125  			msg := types.NewMsgSubmitProposal(content, amount, cliCtx.GetFromAddress())
   126  			if err := msg.ValidateBasic(); err != nil {
   127  				return err
   128  			}
   129  
   130  			return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
   131  		},
   132  	}
   133  
   134  	cmd.Flags().String(FlagTitle, "", "title of proposal")
   135  	cmd.Flags().String(FlagDescription, "", "description of proposal")
   136  	cmd.Flags().String(flagProposalType, "", "proposalType of proposal, types: text/parameter_change/software_upgrade")
   137  	cmd.Flags().String(FlagDeposit, "", "deposit of proposal")
   138  	cmd.Flags().String(FlagProposal, "", "proposal file path (if this path is given, other proposal flags are ignored)")
   139  
   140  	return cmd
   141  }
   142  
   143  // GetCmdDeposit implements depositing tokens for an active proposal.
   144  func GetCmdDeposit(cdc *codec.Codec) *cobra.Command {
   145  	return &cobra.Command{
   146  		Use:   "deposit [proposal-id] [deposit]",
   147  		Args:  cobra.ExactArgs(2),
   148  		Short: "Deposit tokens for an active proposal",
   149  		Long: strings.TrimSpace(
   150  			fmt.Sprintf(`Submit a deposit for an active proposal. You can
   151  find the proposal-id by running "%s query gov proposals".
   152  
   153  Example:
   154  $ %s tx gov deposit 1 10stake --from mykey
   155  `,
   156  				version.ClientName, version.ClientName,
   157  			),
   158  		),
   159  		RunE: func(cmd *cobra.Command, args []string) error {
   160  			inBuf := bufio.NewReader(cmd.InOrStdin())
   161  			txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
   162  			cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc)
   163  
   164  			// validate that the proposal id is a uint
   165  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   166  			if err != nil {
   167  				return fmt.Errorf("proposal-id %s not a valid uint, please input a valid proposal-id", args[0])
   168  			}
   169  
   170  			// Get depositor address
   171  			from := cliCtx.GetFromAddress()
   172  
   173  			// Get amount of coins
   174  			amount, err := sdk.ParseCoins(args[1])
   175  			if err != nil {
   176  				return err
   177  			}
   178  
   179  			msg := types.NewMsgDeposit(from, proposalID, amount)
   180  			err = msg.ValidateBasic()
   181  			if err != nil {
   182  				return err
   183  			}
   184  
   185  			return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
   186  		},
   187  	}
   188  }
   189  
   190  // GetCmdVote implements creating a new vote command.
   191  func GetCmdVote(cdc *codec.Codec) *cobra.Command {
   192  	return &cobra.Command{
   193  		Use:   "vote [proposal-id] [option]",
   194  		Args:  cobra.ExactArgs(2),
   195  		Short: "Vote for an active proposal, options: yes/no/no_with_veto/abstain",
   196  		Long: strings.TrimSpace(
   197  			fmt.Sprintf(`Submit a vote for an active proposal. You can
   198  find the proposal-id by running "%s query gov proposals".
   199  
   200  
   201  Example:
   202  $ %s tx gov vote 1 yes --from mykey
   203  `,
   204  				version.ClientName, version.ClientName,
   205  			),
   206  		),
   207  		RunE: func(cmd *cobra.Command, args []string) error {
   208  			inBuf := bufio.NewReader(cmd.InOrStdin())
   209  			txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
   210  			cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc)
   211  
   212  			// Get voting address
   213  			from := cliCtx.GetFromAddress()
   214  
   215  			// validate that the proposal id is a uint
   216  			proposalID, err := strconv.ParseUint(args[0], 10, 64)
   217  			if err != nil {
   218  				return fmt.Errorf("proposal-id %s not a valid int, please input a valid proposal-id", args[0])
   219  			}
   220  
   221  			// Find out which vote option user chose
   222  			byteVoteOption, err := types.VoteOptionFromString(govutils.NormalizeVoteOption(args[1]))
   223  			if err != nil {
   224  				return err
   225  			}
   226  
   227  			// Build vote message and run basic validation
   228  			msg := types.NewMsgVote(from, proposalID, byteVoteOption)
   229  			err = msg.ValidateBasic()
   230  			if err != nil {
   231  				return err
   232  			}
   233  
   234  			return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
   235  		},
   236  	}
   237  }
   238  
   239  // DONTCOVER