cosmos-sdk/x/gov/client/cli/tx.go

252 lines
6.9 KiB
Go

package cli
import (
"fmt"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/cosmos/cosmos-sdk/client/context"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/wire"
authcmd "github.com/cosmos/cosmos-sdk/x/auth/client/cli"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/pkg/errors"
)
const (
flagProposalID = "proposalID"
flagTitle = "title"
flagDescription = "description"
flagProposalType = "type"
flagDeposit = "deposit"
flagProposer = "proposer"
flagDepositer = "depositer"
flagVoter = "voter"
flagOption = "option"
)
// submit a proposal tx
func GetCmdSubmitProposal(cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "submitproposal",
Short: "Submit a proposal along with an initial deposit",
RunE: func(cmd *cobra.Command, args []string) error {
title := viper.GetString(flagTitle)
description := viper.GetString(flagDescription)
strProposalType := viper.GetString(flagProposalType)
initialDeposit := viper.GetString(flagDeposit)
// get the from address from the name flag
from, err := sdk.GetAccAddressBech32(viper.GetString(flagProposer))
if err != nil {
return err
}
amount, err := sdk.ParseCoins(initialDeposit)
if err != nil {
return err
}
proposalType, err := gov.StringToProposalType(strProposalType)
if err != nil {
return err
}
// create the message
msg := gov.NewMsgSubmitProposal(title, description, proposalType, from, amount)
err = msg.ValidateBasic()
if err != nil {
return err
}
// build and sign the transaction, then broadcast to Tendermint
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc)
if err != nil {
return err
}
fmt.Printf("Committed at block:%d. Hash:%s.Response:%+v \n", res.Height, res.Hash.String(), res.DeliverTx)
return nil
},
}
cmd.Flags().String(flagTitle, "", "title of proposal")
cmd.Flags().String(flagDescription, "", "description of proposal")
cmd.Flags().String(flagProposalType, "", "proposalType of proposal")
cmd.Flags().String(flagDeposit, "", "deposit of proposal")
cmd.Flags().String(flagProposer, "", "proposer of proposal")
return cmd
}
// set a new Deposit transaction
func GetCmdDeposit(cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "deposit",
Short: "deposit tokens for activing proposal",
RunE: func(cmd *cobra.Command, args []string) error {
// get the from address from the name flag
depositer, err := sdk.GetAccAddressBech32(viper.GetString(flagDepositer))
if err != nil {
return err
}
proposalID := viper.GetInt64(flagProposalID)
amount, err := sdk.ParseCoins(viper.GetString(flagDeposit))
if err != nil {
return err
}
// create the message
msg := gov.NewMsgDeposit(depositer, proposalID, amount)
err = msg.ValidateBasic()
if err != nil {
return err
}
// build and sign the transaction, then broadcast to Tendermint
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc)
if err != nil {
return err
}
fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String())
return nil
},
}
cmd.Flags().String(flagProposalID, "", "proposalID of proposal depositing on")
cmd.Flags().String(flagDepositer, "", "depositer of deposit")
cmd.Flags().String(flagDeposit, "", "amount of deposit")
return cmd
}
// set a new Vote transaction
func GetCmdVote(cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "vote",
Short: "vote for an active proposal, options: Yes/No/NoWithVeto/Abstain",
RunE: func(cmd *cobra.Command, args []string) error {
bechVoter := viper.GetString(flagVoter)
voter, err := sdk.GetAccAddressBech32(bechVoter)
if err != nil {
return err
}
proposalID := viper.GetInt64(flagProposalID)
option := viper.GetString(flagOption)
byteVoteOption, err := gov.StringToVoteOption(option)
if err != nil {
return err
}
// create the message
msg := gov.NewMsgVote(voter, proposalID, byteVoteOption)
err = msg.ValidateBasic()
if err != nil {
return err
}
fmt.Printf("Vote[Voter:%s,ProposalID:%d,Option:%s]", bechVoter, msg.ProposalID, gov.VoteOptionToString(msg.Option))
// build and sign the transaction, then broadcast to Tendermint
ctx := context.NewCoreContextFromViper().WithDecoder(authcmd.GetAccountDecoder(cdc))
res, err := ctx.EnsureSignBuildBroadcast(ctx.FromAddressName, []sdk.Msg{msg}, cdc)
if err != nil {
return err
}
fmt.Printf("Committed at block %d. Hash: %s\n", res.Height, res.Hash.String())
return nil
},
}
cmd.Flags().String(flagProposalID, "", "proposalID of proposal voting on")
cmd.Flags().String(flagVoter, "", "bech32 voter address")
cmd.Flags().String(flagOption, "", "vote option {Yes, No, NoWithVeto, Abstain}")
return cmd
}
// Command to Get a Proposal Information
func GetCmdQueryProposal(storeName string, cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "query-proposal",
Short: "query proposal details",
RunE: func(cmd *cobra.Command, args []string) error {
proposalID := viper.GetInt64(flagProposalID)
ctx := context.NewCoreContextFromViper()
res, err := ctx.QueryStore(gov.KeyProposal(proposalID), storeName)
if len(res) == 0 || err != nil {
return errors.Errorf("proposalID [%d] is not existed", proposalID)
}
var proposal gov.Proposal
cdc.MustUnmarshalBinary(res, &proposal)
proposalRest := gov.ProposalToRest(proposal)
output, err := wire.MarshalJSONIndent(cdc, proposalRest)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
},
}
cmd.Flags().String(flagProposalID, "", "proposalID of proposal being queried")
return cmd
}
// Command to Get a Proposal Information
func GetCmdQueryVote(storeName string, cdc *wire.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "query-vote",
Short: "query vote",
RunE: func(cmd *cobra.Command, args []string) error {
proposalID := viper.GetInt64(flagProposalID)
voterAddr, err := sdk.GetAccAddressBech32(viper.GetString(flagVoter))
if err != nil {
return err
}
ctx := context.NewCoreContextFromViper()
res, err := ctx.QueryStore(gov.KeyVote(proposalID, voterAddr), storeName)
if len(res) == 0 || err != nil {
return errors.Errorf("proposalID [%d] does not exist", proposalID)
}
var vote gov.Vote
cdc.MustUnmarshalBinary(res, &vote)
voteRest := gov.VoteToRest(vote)
output, err := wire.MarshalJSONIndent(cdc, voteRest)
if err != nil {
return err
}
fmt.Println(string(output))
return nil
},
}
cmd.Flags().String(flagProposalID, "", "proposalID of proposal voting on")
cmd.Flags().String(flagVoter, "", "bech32 voter address")
return cmd
}