func NewMsgUndelegate(delAddr chainTypes.AccountID, valAddr chainTypes.AccountID, amount chainTypes.Coin) MsgUndelegate {
	return MsgUndelegate{
		DelegatorAccount: delAddr,
		ValidatorAccount: valAddr,
		Amount:           amount,
	}
}
NewMsgUndelegate creates a new MsgUndelegate instance.
package types
import (
	chainTypes "github.com/KuChainNetwork/kuchain/chain/types"
	sdk "github.com/cosmos/cosmos-sdk/types"
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
	"github.com/tendermint/tendermint/crypto"
)
var _, _, _, _, _ chainTypes.KuMsgData = (*MsgCreateValidator)(nil), (*MsgEditValidator)(nil), (*MsgDelegate)(nil), (*MsgBeginRedelegate)(nil), (*MsgUndelegate)(nil)
type MsgCreateValidator struct {
	Description      Description `json:"description" yaml:"description"`
	CommissionRates  Dec         `json:"CommissionRates" yaml:"commission_rate"`
	ValidatorAccount AccountID   `json:"validator_account" yaml:"validator_account"`
	DelegatorAccount AccountID   `json:"delegator_account" yaml:"delegator_account"`
	Pubkey           string      `json:"pubkey,omitempty" yaml:"pubkey"`
}
func NewMsgCreateValidator(
	valAddr chainTypes.AccountID, pubKey crypto.PubKey,
	description Description, commission sdk.Dec, delAcc chainTypes.AccountID,
) MsgCreateValidator {
	var pkStr string
	if pubKey != nil {
		pkStr = sdk.MustBech32ifyPubKey(sdk.Bech32PubKeyTypeConsPub, pubKey)
	}
	return MsgCreateValidator{
		Description:      description,
		ValidatorAccount: valAddr,
		Pubkey:           pkStr,
		DelegatorAccount: delAcc,
		CommissionRates:  commission,
	}
}
func (msg MsgCreateValidator) Route() string { return RouterKey }
func (MsgCreateValidator) Type() chainTypes.Name { return chainTypes.MustName("create@staking") }
func (msg MsgCreateValidator) Sender() AccountID {
	return msg.ValidatorAccount
}
func (msg MsgCreateValidator) GetSigners() []sdk.AccAddress {
	addrs := []sdk.AccAddress{}
	delegatorAccAddress, ok := msg.DelegatorAccount.ToAccAddress()
	if ok {  
		addrs = append(addrs, delegatorAccAddress)
	}
	return addrs
}
func (msg MsgCreateValidator) GetSignBytes() []byte {
	bz := ModuleCdc.MustMarshalJSON(msg)
	return sdk.MustSortJSON(bz)
}
func (msg MsgCreateValidator) ValidateBasic() error {
	if msg.DelegatorAccount.Empty() {
		return ErrEmptyDelegatorAddr
	}
	if msg.ValidatorAccount.Empty() {
		return ErrEmptyValidatorAddr
	}
	if msg.Pubkey == "" {
		return ErrEmptyValidatorPubKey
	}
	if msg.Description == (Description{}) {
		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description")
	}
	if msg.CommissionRates.IsNegative() {
		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "commission_rate is negative")
	}
	if msg.CommissionRates.GT(sdk.OneDec()) {
		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "commission_rate is greater then 1")
	}
	return nil
}
type MsgEditValidator struct {
	Description      Description `json:"description" yaml:"description"`
	ValidatorAccount AccountID   `json:"validator_account" yaml:"address"`
	CommissionRate   *Dec        `json:"commission_rate,omitempty" yaml:"commission_rate"`
}
func NewMsgEditValidator(valAddr chainTypes.AccountID, description Description, newRate *sdk.Dec) MsgEditValidator {
	return MsgEditValidator{
		Description:      description,
		CommissionRate:   newRate,
		ValidatorAccount: valAddr,
	}
}
func (msg MsgEditValidator) Route() string { return RouterKey }
func (MsgEditValidator) Type() chainTypes.Name { return chainTypes.MustName("edit@staking") }
func (msg MsgEditValidator) Sender() AccountID {
	return msg.ValidatorAccount
}
func (msg MsgEditValidator) GetSigners() []sdk.AccAddress {
	validatorAccAddress, _ := msg.ValidatorAccount.ToAccAddress()
	return []sdk.AccAddress{validatorAccAddress}
}
func (msg MsgEditValidator) GetSignBytes() []byte {
	bz := ModuleCdc.MustMarshalJSON(msg)
	return sdk.MustSortJSON(bz)
}
func (msg MsgEditValidator) ValidateBasic() error {
	if msg.ValidatorAccount.Empty() {
		return ErrEmptyValidatorAddr
	}
	if msg.Description == (Description{}) {
		return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "empty description")
	}
	if msg.CommissionRate != nil {
		if msg.CommissionRate.GT(sdk.OneDec()) || msg.CommissionRate.IsNegative() {
			return sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "commission rate must be between 0 and 1 (inclusive)")
		}
	}
	return nil
}
type MsgDelegate struct {
	DelegatorAccount AccountID `json:"delegator_account" yaml:"delegator_account"`
	ValidatorAccount AccountID `json:"validator_account" yaml:"validator_account"`
	Amount           Coin      `json:"amount" yaml:"amount"`
}
func NewMsgDelegate(delAddr chainTypes.AccountID, valAddr chainTypes.AccountID, amount chainTypes.Coin) MsgDelegate {
	return MsgDelegate{
		DelegatorAccount: delAddr,
		ValidatorAccount: valAddr,
		Amount:           amount,
	}
}
func (msg MsgDelegate) Route() string { return RouterKey }
func (MsgDelegate) Type() chainTypes.Name { return chainTypes.MustName("delegate") }
func (msg MsgDelegate) Sender() AccountID {
	return msg.DelegatorAccount
}
func (msg MsgDelegate) GetSigners() []sdk.AccAddress {
	delegatorAccAddress, _ := msg.DelegatorAccount.ToAccAddress()
	return []sdk.AccAddress{delegatorAccAddress}
}
func (msg MsgDelegate) GetSignBytes() []byte {
	bz := ModuleCdc.MustMarshalJSON(msg)
	return sdk.MustSortJSON(bz)
}
func (msg MsgDelegate) ValidateBasic() error {
	if msg.DelegatorAccount.Empty() {
		return ErrEmptyDelegatorAddr
	}
	if msg.ValidatorAccount.Empty() {
		return ErrEmptyValidatorAddr
	}
	if !msg.Amount.Amount.IsPositive() {
		return ErrBadDelegationAmount
	}
	return nil
}
type MsgBeginRedelegate struct {
	DelegatorAccount    AccountID `json:"delegator_account" yaml:"delegator_account"`
	ValidatorSrcAccount AccountID `json:"validator_src_account" yaml:"validator_src_account"`
	ValidatorDstAccount AccountID `json:"validator_dst_account" yaml:"validator_dst_account"`
	Amount              Coin      `json:"amount" yaml:"amount"`
}
func NewMsgBeginRedelegate(
	delAddr chainTypes.AccountID, valSrcAddr, valDstAddr chainTypes.AccountID, amount chainTypes.Coin,
) MsgBeginRedelegate {
	return MsgBeginRedelegate{
		DelegatorAccount:    delAddr,
		ValidatorSrcAccount: valSrcAddr,
		ValidatorDstAccount: valDstAddr,
		Amount:              amount,
	}
}
func (msg MsgBeginRedelegate) Route() string { return RouterKey }
func (MsgBeginRedelegate) Type() chainTypes.Name { return chainTypes.MustName("beginredelegate") }
func (msg MsgBeginRedelegate) Sender() AccountID {
	return msg.DelegatorAccount
}
func (msg MsgBeginRedelegate) GetSigners() []sdk.AccAddress {
	delegatorAccAddress, _ := msg.DelegatorAccount.ToAccAddress()
	return []sdk.AccAddress{delegatorAccAddress}
}
func (msg MsgBeginRedelegate) GetSignBytes() []byte {
	bz := ModuleCdc.MustMarshalJSON(msg)
	return sdk.MustSortJSON(bz)
}
func (msg MsgBeginRedelegate) ValidateBasic() error {
	if msg.DelegatorAccount.Empty() {
		return ErrEmptyDelegatorAddr
	}
	if msg.ValidatorSrcAccount.Empty() {
		return ErrEmptyValidatorAddr
	}
	if msg.ValidatorDstAccount.Empty() {
		return ErrEmptyValidatorAddr
	}
	if !msg.Amount.Amount.IsPositive() {
		return ErrBadSharesAmount
	}
	return nil
}
type MsgUndelegate struct {
	DelegatorAccount AccountID `json:"delegator_account" yaml:"delegator_account"`
	ValidatorAccount AccountID `json:"validator_account" yaml:"validator_account"`
	Amount           Coin      `json:"amount" yaml:"amount"`
}