wasmd/x/wasm/client/cli/gov_tx.go

615 lines
20 KiB
Go

package cli
import (
"fmt"
"strconv"
"github.com/cosmos/cosmos-sdk/client"
"github.com/cosmos/cosmos-sdk/client/tx"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov/client/cli"
govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/CosmWasm/wasmd/x/wasm/types"
)
func ProposalStoreCodeCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "wasm-store [wasm file] --title [text] --description [text] --run-as [address]",
Short: "Submit a wasm binary proposal",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
src, err := parseStoreCodeArgs(args[0], clientCtx.FromAddress, cmd.Flags())
if err != nil {
return err
}
runAs, err := cmd.Flags().GetString(flagRunAs)
if err != nil {
return fmt.Errorf("run-as: %s", err)
}
if len(runAs) == 0 {
return errors.New("run-as address is required")
}
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
content := types.StoreCodeProposal{
Title: proposalTitle,
Description: proposalDescr,
RunAs: runAs,
WASMByteCode: src.WASMByteCode,
InstantiatePermission: src.InstantiatePermission,
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
cmd.Flags().String(flagRunAs, "", "The address that is stored as code creator")
cmd.Flags().String(flagInstantiateByEverybody, "", "Everybody can instantiate a contract from the code, optional")
cmd.Flags().String(flagInstantiateByAddress, "", "Only this address can instantiate a contract instance from the code, optional")
// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}
func ProposalInstantiateContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "instantiate-contract [code_id_int64] [json_encoded_init_args] --label [text] --title [text] --description [text] --run-as [address] --admin [address,optional] --amount [coins,optional]",
Short: "Submit an instantiate wasm contract proposal",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
src, err := parseInstantiateArgs(args[0], args[1], clientCtx.FromAddress, cmd.Flags())
if err != nil {
return err
}
runAs, err := cmd.Flags().GetString(flagRunAs)
if err != nil {
return fmt.Errorf("run-as: %s", err)
}
if len(runAs) == 0 {
return errors.New("run-as address is required")
}
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
content := types.InstantiateContractProposal{
Title: proposalTitle,
Description: proposalDescr,
RunAs: runAs,
Admin: src.Admin,
CodeID: src.CodeID,
Label: src.Label,
Msg: src.Msg,
Funds: src.Funds,
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation")
cmd.Flags().String(flagLabel, "", "A human-readable name for this contract in lists")
cmd.Flags().String(flagAdmin, "", "Address of an admin")
cmd.Flags().String(flagRunAs, "", "The address that pays the init funds. It is the creator of the contract and passed to the contract as sender on proposal execution")
// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}
func ProposalMigrateContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "migrate-contract [contract_addr_bech32] [new_code_id_int64] [json_encoded_migration_args]",
Short: "Submit a migrate wasm contract to a new code version proposal",
Args: cobra.ExactArgs(3),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
src, err := parseMigrateContractArgs(args, clientCtx)
if err != nil {
return err
}
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
content := types.MigrateContractProposal{
Title: proposalTitle,
Description: proposalDescr,
Contract: src.Contract,
CodeID: src.CodeID,
Msg: src.Msg,
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}
func ProposalExecuteContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "execute-contract [contract_addr_bech32] [json_encoded_migration_args]",
Short: "Submit a execute wasm contract proposal (run by any address)",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
contract := args[0]
execMsg := []byte(args[1])
amountStr, err := cmd.Flags().GetString(flagAmount)
if err != nil {
return fmt.Errorf("amount: %s", err)
}
funds, err := sdk.ParseCoinsNormalized(amountStr)
if err != nil {
return fmt.Errorf("amount: %s", err)
}
runAs, err := cmd.Flags().GetString(flagRunAs)
if err != nil {
return fmt.Errorf("run-as: %s", err)
}
if len(runAs) == 0 {
return errors.New("run-as address is required")
}
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
content := types.ExecuteContractProposal{
Title: proposalTitle,
Description: proposalDescr,
Contract: contract,
Msg: execMsg,
RunAs: runAs,
Funds: funds,
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
cmd.Flags().String(flagRunAs, "", "The address that is passed as sender to the contract on proposal execution")
cmd.Flags().String(flagAmount, "", "Coins to send to the contract during instantiation")
// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}
func ProposalSudoContractCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "sudo-contract [contract_addr_bech32] [json_encoded_migration_args]",
Short: "Submit a sudo wasm contract proposal (to call privileged commands)",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
contract := args[0]
sudoMsg := []byte(args[1])
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return err
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
content := types.SudoContractProposal{
Title: proposalTitle,
Description: proposalDescr,
Contract: contract,
Msg: sudoMsg,
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
// proposal flagsExecute
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}
func ProposalUpdateContractAdminCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "set-contract-admin [contract_addr_bech32] [new_admin_addr_bech32]",
Short: "Submit a new admin for a contract proposal",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
src, err := parseUpdateContractAdminArgs(args, clientCtx)
if err != nil {
return err
}
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return fmt.Errorf("deposit: %s", err)
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
content := types.UpdateAdminProposal{
Title: proposalTitle,
Description: proposalDescr,
Contract: src.Contract,
NewAdmin: src.NewAdmin,
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}
func ProposalClearContractAdminCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "clear-contract-admin [contract_addr_bech32]",
Short: "Submit a clear admin for a contract to prevent further migrations proposal",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return fmt.Errorf("deposit: %s", err)
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
content := types.ClearAdminProposal{
Title: proposalTitle,
Description: proposalDescr,
Contract: args[0],
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}
func ProposalPinCodesCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "pin-codes [code-ids]",
Short: "Submit a pin code proposal for pinning a code to cache",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return fmt.Errorf("deposit: %s", err)
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
codeIds, err := parsePinCodesArgs(args)
if err != nil {
return err
}
content := types.PinCodesProposal{
Title: proposalTitle,
Description: proposalDescr,
CodeIDs: codeIds,
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}
func parsePinCodesArgs(args []string) ([]uint64, error) {
codeIDs := make([]uint64, len(args))
for i, c := range args {
codeID, err := strconv.ParseUint(c, 10, 64)
if err != nil {
return codeIDs, fmt.Errorf("code IDs: %s", err)
}
codeIDs[i] = codeID
}
return codeIDs, nil
}
func ProposalUnpinCodesCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "unpin-codes [code-ids]",
Short: "Submit a unpin code proposal for unpinning a code to cache",
Args: cobra.MinimumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
return err
}
proposalTitle, err := cmd.Flags().GetString(cli.FlagTitle)
if err != nil {
return fmt.Errorf("proposal title: %s", err)
}
proposalDescr, err := cmd.Flags().GetString(cli.FlagDescription)
if err != nil {
return fmt.Errorf("proposal description: %s", err)
}
depositArg, err := cmd.Flags().GetString(cli.FlagDeposit)
if err != nil {
return fmt.Errorf("deposit: %s", err)
}
deposit, err := sdk.ParseCoinsNormalized(depositArg)
if err != nil {
return err
}
codeIds, err := parsePinCodesArgs(args)
if err != nil {
return err
}
content := types.UnpinCodesProposal{
Title: proposalTitle,
Description: proposalDescr,
CodeIDs: codeIds,
}
msg, err := govtypes.NewMsgSubmitProposal(&content, deposit, clientCtx.GetFromAddress())
if err != nil {
return err
}
if err = msg.ValidateBasic(); err != nil {
return err
}
return tx.GenerateOrBroadcastTxCLI(clientCtx, cmd.Flags(), msg)
},
}
// proposal flags
cmd.Flags().String(cli.FlagTitle, "", "Title of proposal")
cmd.Flags().String(cli.FlagDescription, "", "Description of proposal")
cmd.Flags().String(cli.FlagDeposit, "", "Deposit of proposal")
cmd.Flags().String(cli.FlagProposal, "", "Proposal file path (if this path is given, other proposal flags are ignored)")
// type values must match the "ProposalHandler" "routes" in cli
cmd.Flags().String(flagProposalType, "", "Permission of proposal, types: store-code/instantiate/migrate/update-admin/clear-admin/text/parameter_change/software_upgrade")
return cmd
}