Cosmos-- 三.教程 -- 8.Querier

cosmos主网即将上线,对文档做了大量更新。特地翻译了一下,方便小伙伴们阅览, 之后会持续更新

第三章教程:

  1. 开始
  2. 程序目标
  3. 开始编写你的程序
  4. Keeper
  5. Msg和Handler
  6. SetName
  7. BuyName
  8. Querier
  9. Codec文件
  10. Nameservice模块的CLI
  11. nameservice模块的REST接口
  12. 引入你的模块并完成程序
  13. Entrypoint
  14. 编译你的程序
  15. 编译并运行程序
  16. 运行REST路由

Querier

首先创建./x/nameservice/querier.go文件。在这里定义应用程序用户可以对那些状态进行查询。你的nameservice模块会暴露两个querier:

  • resolve : 传入一个域名返回nameservice给定的解析值。类似于DNS查询。
  • whois : 传入一个域名返回价格解析值和域名的所有者。用于确定你想要购买名称的成本。

首先定义NewQuerier函数,该函数充当查询此模块的子路由器(类似于NewHandler函数)。请注意,因为querier没有类似于Msg的接口,所以需要手动定义switch语句(它们无法从query.Route()函数中删除):

package nameservice

import (
    "github.com/cosmos/cosmos-sdk/codec"

    sdk "github.com/cosmos/cosmos-sdk/types"
    abci "github.com/tendermint/tendermint/abci/types"
)

// query endpoints supported by the governance Querier
const (
    QueryResolve = "resolve"
    QueryWhois   = "whois"
)

// NewQuerier is the module level router for state queries
func NewQuerier(keeper Keeper) sdk.Querier {
    return func(ctx sdk.Context, path []string, req abci.RequestQuery) (res []byte, err sdk.Error) {
        switch path[0] {
        case QueryResolve:
            return queryResolve(ctx, path[1:], req, keeper)
        case QueryWhois:
            return queryWhois(ctx, path[1:], req, keeper)
        default:
            return nil, sdk.ErrUnknownRequest("unknown nameservice query endpoint")
        }
    }
}

现在已定义路由器,为每个查询定义输入和响应:

// nolint: unparam
func queryResolve(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
    name := path[0]

    value := keeper.ResolveName(ctx, name)

    if value == "" {
        return []byte{}, sdk.ErrUnknownRequest("could not resolve name")
    }

    return []byte(value), nil
}

// nolint: unparam
func queryWhois(ctx sdk.Context, path []string, req abci.RequestQuery, keeper Keeper) (res []byte, err sdk.Error) {
    name := path[0]

    whois := Whois{}

    whois.Value = keeper.ResolveName(ctx, name)
    whois.Owner = keeper.GetOwner(ctx, name)
    whois.Price = keeper.GetPrice(ctx, name)

    bz, err2 := codec.MarshalJSONIndent(keeper.cdc, whois)
    if err2 != nil {
        panic("could not marshal result to JSON")
    }

    return bz, nil
}

// Whois represents a name -> value lookup
type Whois struct {
    Value string         `json:"value"`
    Owner sdk.AccAddress `json:"owner"`
    Price sdk.Coins      `json:"price"`
}

上述代码中要注意:

  • 在这里你的Keeper的getter和setter方法被大量使用。在构建使用此模块的任何其他应用程序时,你可能需要返回并定义更多getter/setter以访问所需的状态。
  • 如果你的应用程序需要一些自定义响应类型(本例中为Whois),请在此文件中定义它们。

你可能感兴趣的:(Cosmos-- 三.教程 -- 8.Querier)