cosmos主網(wǎng)即將上線缘缚,對(duì)文檔做了大量更新。特地翻譯了一下阿宅,方便小伙伴們閱覽, 之后會(huì)持續(xù)更新
第三章教程:
Nameservice模塊的CLI
Cosmos SDK使用cobra
庫(kù)進(jìn)行CLI交互候衍。該庫(kù)使每個(gè)模塊都可以輕松地公開(kāi)自己的操作命令。要開(kāi)始定義用戶與模塊的CLI交互洒放,請(qǐng)創(chuàng)建以下文件:
./x/nameservice/client/cli/query.go
./x/nameservice/client/cli/tx.go
./x/nameservice/client/module_client.go
Querier
在query.go
文件中為你模塊的每個(gè)Query
(resolve
和whois
)定義cobra.Command
:
package cli
import (
"fmt"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/spf13/cobra"
)
// GetCmdResolveName queries information about a name
func GetCmdResolveName(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "resolve [name]",
Short: "resolve name",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
name := args[0]
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/resolve/%s", queryRoute, name), nil)
if err != nil {
fmt.Printf("could not resolve name - %s \n", string(name))
return nil
}
fmt.Println(string(res))
return nil
},
}
}
// GetCmdWhois queries information about a domain
func GetCmdWhois(queryRoute string, cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "whois [name]",
Short: "Query whois info of name",
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc)
name := args[0]
res, err := cliCtx.QueryWithData(fmt.Sprintf("custom/%s/whois/%s", queryRoute, name), nil)
if err != nil {
fmt.Printf("could not resolve whois - %s \n", string(name))
return nil
}
fmt.Println(string(res))
return nil
},
}
}
注意上述代碼中:
- CLI引入了一個(gè)新的
context
:CLIContext
蛉鹿。它包含有關(guān)CLI交互所需的用戶輸入和應(yīng)用程序配置的數(shù)據(jù)。 -
cliCtx.QueryWithData()
函數(shù)所需的path
直接從你的查詢路徑中映射往湿。- 路徑的第一部分用于區(qū)分SDK應(yīng)用程序可能的querier類(lèi)型:
custom
用于Querier
- 第二部分(
nameservice
)是將查詢路由到的模塊的名稱妖异。 - 最后是要調(diào)用模塊中的特定的querier。
- 在這個(gè)例子中领追,第四部分是查詢他膳。這是因?yàn)椴樵儏?shù)是一個(gè)簡(jiǎn)單的字符串。要啟用更復(fù)雜的查詢輸入绒窑,你需要使用
.QueryWithData()
函數(shù)的第二個(gè)參數(shù)來(lái)傳入data
棕孙。有關(guān)此示例,請(qǐng)參閱Staking模塊中的querier些膨。
- 路徑的第一部分用于區(qū)分SDK應(yīng)用程序可能的querier類(lèi)型:
Transaction
現(xiàn)在已經(jīng)定義了查詢交互蟀俊,是時(shí)候繼續(xù)在tx.go
中的交易生成了:
你的應(yīng)用程序需要導(dǎo)入你剛編寫(xiě)的代碼。這里導(dǎo)入路徑設(shè)置為此存儲(chǔ)庫(kù)(github.com/cosmos/sdk-application-tutorial/x/nameservice)订雾。如果您是在自己的倉(cāng)庫(kù)中進(jìn)行的前面的操作欧漱,則需要更改導(dǎo)入路徑(github.com/{.Username}/{.Project.Repo}/x/nameservice)。
package cli
import (
"github.com/spf13/cobra"
"github.com/cosmos/cosmos-sdk/client/context"
"github.com/cosmos/cosmos-sdk/client/utils"
"github.com/cosmos/cosmos-sdk/codec"
"github.com/cosmos/sdk-application-tutorial/x/nameservice"
sdk "github.com/cosmos/cosmos-sdk/types"
authtxb "github.com/cosmos/cosmos-sdk/x/auth/client/txbuilder"
)
// GetCmdBuyName is the CLI command for sending a BuyName transaction
func GetCmdBuyName(cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "buy-name [name] [amount]",
Short: "bid for existing name or claim new name",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
if err := cliCtx.EnsureAccountExists(); err != nil {
return err
}
coins, err := sdk.ParseCoins(args[1])
if err != nil {
return err
}
msg := nameservice.NewMsgBuyName(args[0], coins, cliCtx.GetFromAddress())
err = msg.ValidateBasic()
if err != nil {
return err
}
cliCtx.PrintResponse = true
return utils.CompleteAndBroadcastTxCLI(txBldr, cliCtx, []sdk.Msg{msg})
},
}
}
// GetCmdSetName is the CLI command for sending a SetName transaction
func GetCmdSetName(cdc *codec.Codec) *cobra.Command {
return &cobra.Command{
Use: "set-name [name] [value]",
Short: "set the value associated with a name that you own",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
cliCtx := context.NewCLIContext().WithCodec(cdc).WithAccountDecoder(cdc)
txBldr := authtxb.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
if err := cliCtx.EnsureAccountExists(); err != nil {
return err
}
msg := nameservice.NewMsgSetName(args[0], args[1], cliCtx.GetFromAddress())
err := msg.ValidateBasic()
if err != nil {
return err
}
cliCtx.PrintResponse = true
// return utils.CompleteAndBroadcastTxCLI(txBldr, cliCtx, msgs)
return utils.CompleteAndBroadcastTxCLI(txBldr, cliCtx, []sdk.Msg{msg})
},
}
}
注意在上述代碼中:
- 使用了
authcmd
包葬燎。查看文檔了解更多使用信息。它提供對(duì)CLI控制的帳戶的訪問(wèn)權(quán)限缚甩,并便于簽名谱净。
Module Client
導(dǎo)出此功能的最后一部分稱為ModuleClient
,在./x/nameservice/client/module_client.go
文件中實(shí)現(xiàn)擅威。Module Client為模塊提供了導(dǎo)出客戶端功能的標(biāo)準(zhǔn)方法壕探。
注意:你的應(yīng)用程序需要導(dǎo)入你剛編寫(xiě)的代碼。這里導(dǎo)入路徑設(shè)置為此倉(cāng)庫(kù)(github.com/cosmos/sdk-application-tutorial/x/nameservice)郊丛。如果你是在自己項(xiàng)目中編寫(xiě)的李请,則需要更改導(dǎo)入路徑成(github.com/{.Username}/ {.Project.Repo}/x/nameservice)瞧筛。
package client
import (
"github.com/cosmos/cosmos-sdk/client"
nameservicecmd "github.com/cosmos/sdk-application-tutorial/x/nameservice/client/cli"
"github.com/spf13/cobra"
amino "github.com/tendermint/go-amino"
)
// ModuleClient exports all client functionality from this module
type ModuleClient struct {
storeKey string
cdc *amino.Codec
}
func NewModuleClient(storeKey string, cdc *amino.Codec) ModuleClient {
return ModuleClient{storeKey, cdc}
}
// GetQueryCmd returns the cli query commands for this module
func (mc ModuleClient) GetQueryCmd() *cobra.Command {
// Group gov queries under a subcommand
govQueryCmd := &cobra.Command{
Use: "nameservice",
Short: "Querying commands for the nameservice module",
}
govQueryCmd.AddCommand(client.GetCommands(
nameservicecmd.GetCmdResolveName(mc.storeKey, mc.cdc),
nameservicecmd.GetCmdWhois(mc.storeKey, mc.cdc),
)...)
return govQueryCmd
}
// GetTxCmd returns the transaction commands for this module
func (mc ModuleClient) GetTxCmd() *cobra.Command {
govTxCmd := &cobra.Command{
Use: "nameservice",
Short: "Nameservice transactions subcommands",
}
govTxCmd.AddCommand(client.PostCommands(
nameservicecmd.GetCmdBuyName(mc.cdc),
nameservicecmd.GetCmdSetName(mc.cdc),
)...)
return govTxCmd
}
上述代碼要注意:
- 此抽象允許客戶端以標(biāo)準(zhǔn)方式從模塊導(dǎo)入客戶端功能。當(dāng)我們構(gòu)建入口時(shí)导盅,你將看到這一點(diǎn)较幌。
- 有一個(gè)未解決的問(wèn)題是將其余功能(在本教程的下一部分中描述)添加到此接口。