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

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