Merge PR #5379: New docs V1 (merge master-docs to master)

This commit is contained in:
gamarin2
2019-12-10 09:29:46 -05:00
committed by Alexander Bezobchuk
parent 7d7821b9af
commit b18bd06a36
75 changed files with 5529 additions and 3599 deletions
+15
View File
@@ -0,0 +1,15 @@
---
order: false
parent:
order: 5
---
# Interfaces
This repository contains documentation on interfaces for Cosmos SDK applications.
1. [Introduction to Interaces](./interfaces-intro.md)
2. [Lifecycle of a Query](./query-lifecycle.md)
3. [Command-Line Interface](./cli.md)
4. [Rest Interface](./rest.md)
+137
View File
@@ -0,0 +1,137 @@
---
order: 3
synopsis: "This document describes how to create a commmand-line interface (CLI) for an [**application**](../basics/app-anatomy.md). A separate document for implementing a CLI for an SDK [**module**](../building-modules/intro.md) can be found [here](#../building-modules/module-interfaces.md#cli)."
---
# Command-Line Interface
## Pre-requisite Readings {hide}
* [Lifecycle of a Query](./query-lifecycle.md) {prereq}
## Command-Line Interface
One of the main entrypoints of an application is the command-line interface. This entrypoint is created via a `main.go` file which compiles to a binary, conventionally placed in the application's `./cmd/cli` folder. The CLI for an application is typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`. Here is where the interfaces docs lie in the directory from the [nameservice tutorial](https://cosmos.network/docs/tutorial).
### Example Command
There is no set way to create a CLI, but SDK modules typically use the [Cobra Library](https://github.com/spf13/cobra). Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) understand the actions users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to.
Here is an example of a command a user might enter to interact with the nameservice CLI `nscli` in order to buy a name:
```bash
nscli tx nameservice buy-name <name> <amount> --gas auto --gas-prices <gasPrices>
```
The first four strings specify the command:
- The root command for the entire application `nscli`.
- The subcommand `tx`, which contains all commands that let users create transactions.
- The subcommand `nameservice` to indicate which module to route the command to (`nameservice` module in this case).
- The type of transaction `buy-name`.
The next two strings are arguments: the `name` the user wishes to buy and the `amount` they want to pay for it. Finally, the last few strings of the command are flags to indicate how much the user is willing to pay in fees (calculated using the amount of gas used to execute the transaction and the gas prices provided by the user).
The CLI interacts with a [node](../core/node.md) (running `nsd`) to handle this command. The interface itself is defined in a `main.go` file.
### Building the CLI
The `main.go` file needs to have a `main()` function that does the following to run the command-line interface:
* **Instantiate the `codec`** by calling the application's `MakeCodec()` function. The [`codec`](../core/encoding.md) is used to code and encode data structures for the application - stores can only persist `[]byte`s so the developer must define a serialization format for their data structures or use the default, [Amino](../core/encoding.md#amino).
* **Configurations** are set by reading in configuration files (e.g. the sdk config file).
* **Create the root command** to which all the application commands will be added as subcommands and add any required flags to it, such as `--chain-id`.
* **Add subcommands** for all the possible user interactions, including [transaction commands](#transaction-commands) and [query commands](#query-commands).
* **Create an Executor** and [execute](https://godoc.org/github.com/spf13/cobra#Command.Execute) the root command.
See an example of `main()` function from the `nameservice` application:
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L23-L66
The rest of the document will detail what needs to be implemented for each step and include smaller portions of code from the nameservice CLI `main.go` file.
## Adding Commands to the CLI
Every application CLI first constructs a root command, then adds functionality by aggregating subcommands (often with further nested subcommands) using `rootCmd.AddCommand()`. The bulk of an application's unique capabilities lies in its transaction and query commands, called `TxCmd` and `QueryCmd` respectively.
### Root Command
The root command (called `rootCmd`) is what the user first types into the command line to indicate which application they wish to interact with. The string used to invoke the command (the "Use" field) is typically the name of the application suffixed with `-cli`, e.g. `appcli`. The root command typically includes the following commands to support basic functionality in the application.
* **Status** command from the SDK rpc client tools, which prints information about the status of the connected [`Node`](../core/node.md). The Status of a node includes `NodeInfo`,`SyncInfo` and `ValidatorInfo`.
* **Config** [command](https://github.com/cosmos/cosmos-sdk/blob/master/client/config.go) from the SDK client tools, which allows the user to edit a `config.toml` file that sets values for [flags](#flags) such as `--chain-id` and which `--node` they wish to connect to.
The `config` command can be invoked by typing `appcli config` with optional arguments `<key> [value]` and a `--get` flag to query configurations or `--home` flag to create a new configuration.
* **Keys** [commands](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys) from the SDK client tools, which includes a collection of subcommands for using the key functions in the SDK crypto tools, including adding a new key and saving it to disk, listing all public keys stored in the key manager, and deleting a key.
For example, users can type `appcli keys add <name>` to add a new key and save an encrypted copy to disk, using the flag `--recover` to recover a private key from a seed phrase or the flag `--multisig` to group multiple keys together to create a multisig key. For full details on the `add` key command, see the code [here](https://github.com/cosmos/cosmos-sdk/blob/master/client/keys/add.go).
* [**Transaction**](#transaction-commands) commands.
* [**Query**](#query-commands) commands.
Next is an example `main()` function from the `nameservice` application. It instantiates the root command, adds a [*persistent* flag](#flags) and `PreRun` function to be run before every execution, and adds all of the necessary subcommands.
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L23-L66
The root-level `status`, `config`, and `keys` subcommands are common across most applications and do not interact with application state. The bulk of an application's functionality - what users can actually *do* with it - is enabled by its transaction commands.
### Transaction Commands
[Transactions](#./transactions.md) are objects wrapping [messages](../building-modules/messages-and-queries.md#messages) that trigger state changes. To enable the creation of transactions using the CLI interface, a function `txCmd` is generally added to the `rootCmd`:
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L51
This `txCmd` function adds all the transaction available to end-users for the application. This typically includes:
* **Sign command** from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module that signs messages in a transaction. To enable multisig, add the `auth` module's `MultiSign` command. Since every transaction requires some sort of signature in order to be valid, thithe signing command is necessary for every application.
* **Broadcast command** from the SDK client tools, to broadcast transactions.
* **Send command** from the [`bank`](https://github.com/cosmos/cosmos-sdk/tree/master/x/bank/spec) module, which is a transaction that allows accounts to send coins to one another, including gas and fees for transactions.
* **All [module transaction commands](../building-modules/module-interfaces.md#transaction-commands)** the application is dependent on, retrieved by using the [basic module manager's](../building-modules/module-manager.md#basic-manager) `AddTxCommands()` function.
Here is an example of a `txCmd` aggregating these subcommands from the `nameservice` application:
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L97-L118
### Query Commands
[**Queries**](../building-modules/messages-and-queries.md#queries) are objects that allow users to retrieve information about the application's state. To enable the creation of transactions using the CLI interface, a function `txCmd` is generally added to the `rootCmd`:
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L50
This `queryCmd` function adds all the queries available to end-users for the application. This typically includes:
* **QueryTx** and/or other transaction query commands] from the `auth` module which allow the user to search for a transaction by inputting its hash, a list of tags, or a block height. These queries allow users to see if transactions have been included in a block.
* **Account command** from the `auth` module, which displays the state (e.g. account balance) of an account given an address.
* **Validator command** from the SDK rpc client tools, which displays the validator set of a given height.
* **Block command** from the SDK rpc client tools, which displays the block data for a given height.
* **All [module query commands](../building-modules/module-interfaces.md#query-commands)** the application is dependent on, retrieved by using the [basic module manager's](../building-modules/module-manager.md#basic-manager) `AddQueryCommands()` function.
Here is an example of a `queryCmd` aggregating subcommands from the `nameservice` application:
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L74-L95
## Flags
Flags are used to modify commands; developers can include them in a `flags.go` file with their CLI. Users can explicitly include them in commands or pre-configure them by entering a command in the format `appcli config <flag> <value>` into their command line. Commonly pre-configured flags include the `--node` to connect to and `--chain-id` of the blockchain the user wishes to interact with.
A *persistent* flag (as opposed to a _local_ flag) added to a command transcends all of its children: subcommands will inherit the configured values for these flags. Additionally, all flags have default values when they are added to commands; some toggle an option off but others are empty values that the user needs to override to create valid commands. A flag can be explicitly marked as _required_ so that an error is automatically thrown if the user does not provide a value, but it is also acceptable to handle unexpected missing flags differently.
Flags are added to commands directly (generally in the [module's CLI file](../building-modules/module-interfaces.md#flags) where module commands are defined) and no flag except for the `rootCmd` persistent flags has to be added at application level. It is common to add a _persistent_ flag for `--chain-id`, the unique identifier of the blockchain the application pertains to, to the root command. Adding this flag can be done in the `main()` function. Adding this flag makes sense as the chain ID should not be changing across commands in this application CLI. Here is an example from the `nameservice` application:
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L41
## Configurations
The last function to define in `main.go` is `initConfig`, which does exactly what it sounds like - initialize configurations. To call this function, set it as a `PersistentPreRunE` function for the root command, so that it always executes before the main execution of the root command and any of its subcommands. `initConfig()` does the following:
1. Read in the `config.toml` file. This same file is edited through `config` commands.
2. Use the [Viper](https://github.com/spf13/viper) to read in configurations from the file and set them.
3. Set any persistent flags defined by the user: `--chain-id`, `--encoding`, `--output`, etc.
Here is an example of an `initConfig()` function from the [nameservice tutorial CLI](https://cosmos.network/docs/tutorial/entrypoint.html#nscli):
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L120-L141
And an example of how to add `initConfig` as a `PersistentPreRunE` to the root command:
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/cmd/nscli/main.go#L42-L44
-26
View File
@@ -1,26 +0,0 @@
# Clients
This section explains contains information on clients for SDK based blockchain.
>*NOTE*: This section is a WIP.
## Light-client
Light-clients enable users to interact with your application without having to download the entire state history but with a good level of security.
- [Overview of light clients](./lite/README.md)
- [Starting a light-client server](./lite/getting_started.md)
- [Light-client specification](./lite/specification.md)
## Other clients
- [Command-Line interface for SDK-based blockchain](./cli.md)
- [Service provider doc](./service-providers.md)
## Genesis upgrade
If you need to upgrade your node you could export the genesis and migrate it to the new version through this script:
```bash
<appbinary> migrate v0.36 genesis_0_34.json [--time "2019-04-22T17:00:11Z"] [--chain-id test] > ~/.gaiad/genesis.json
```
+43
View File
@@ -0,0 +1,43 @@
---
order: 1
synopsis: Typically, SDK applications include interfaces to let end-users interact with the application. This document introduces the different types of interfaces for SDK applications.
---
# Interfaces
## Pre-requisite Readings {hide}
* [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq}
* [Lifecycle of a Transaction](../basics/tx-lifecycle.md) {prereq}
## Types of Application Interfaces
SDK applications generally have a Command-Line Interface (CLI) and REST Interface to support interactions with a [full-node](../core/node.md). The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux). The CLI and REST Interface are conventionally defined in the application `./app/cmd/cli` folder.
## Module vs Application Interfaces
The process of creating an application interface is distinct from creating a [module interface](../building-modules/module-interfaces.md), though the two are closely intertwined. As expected, module interfaces handle the bulk of the underlying logic, defining ways for end-users to create [messages](../building-modules/messages-and-queries.md#messages) and [queries](../building-modules/messages-and-queries.md#queries) to the subset of application state within their scope. On the other hand, application interfaces aggregate module-level interfaces in order to route `messages` and `queries` to the appropriate modules. Application interfaces also handle root-level responsibilities such as signing and broadcasting [transactions](../core/transactions.md) that wrap messages.
### Module Developer Responsibilities
With regards to interfaces, module developers need to include the following definitions:
* **CLI commands:** Specifically, [Transaction commands](../building-modules/module-interfaces.md#transaction-commands) and [Query commands](../building-modules/module-interfaces.md#query-commands). These are commands that users will invoke when interacting with the application to create transactions and queries. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, users will create `tx auth send` transactions.
* **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/module-interfaces.md#request-types) in addition to [Request Handlers](../building-modules/module-interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices).
* **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/module-interfaces.md#request-handlers) for each type of request.
Module interfaces are designed to be generic. Both commands and request types include required user input (through flags or request body) which are different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/module-interfaces.md).
### Application Developer Responsibilities
With regards to interfaces, application developers need to include:
* **CLI Root Command:** The [root command](./cli.md#root-command) adds subcommands to include all of the functionality for the application, mainly module [transaction](./cli.md#transaction-commands) and [query](./cli.md#query-commands) commands from the application's module(s).
* **App Configurations:** All application-specific values are the responsibility of the application developer, including the [`codec`](../core/encoding.md) used to marshal requests before relaying them to a node.
* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to. The CLI has a [configurations](./cli.md#configurations) function to set these values.
* **RegisterRoutes Function:** [Routes](./rest.md#registerroutes) must be registered and passed to an instantiated [REST server](./rest.md#rest-server) so that it knows how to route requests for this particular application.
## Next {hide}
Read about the [Lifecycle of a Query](./query-lifecycle.md) {hide}
+5
View File
@@ -1,3 +1,8 @@
---
parent:
order: false
---
# Light Client Overview
**See the Cosmos SDK Light Client RPC documentation [here](https://cosmos.network/rpc/)**
+1 -1
View File
@@ -14,7 +14,7 @@ tree is the AppHash which will be included in block header.
![Simple Merkle Tree](./pics/simpleMerkleTree.png)
As we have discussed in [LCD trust-propagation](https://github.com/irisnet/cosmos-sdk/tree/bianjie/lcd_spec/docs/spec/lcd#trust-propagation),
As we have discussed in LCD trust-propagation,
the AppHash can be verified by checking voting power against a trusted validator set. Here we just
need to build proof from ABCI state to AppHash. The proof contains two parts:
+161
View File
@@ -0,0 +1,161 @@
---
order: 2
synopsis: "This document describes the lifecycle of a query in a SDK application, from the user interface to application stores and back. The query will be referred to as `Query`."
---
# Query Lifecycle
## Pre-requisite Readings {hide}
* [Introduction to Interfaces](./interfaces-intro.md) {prereq}
## Query Creation
A [**query**](../building-modules/messages-and-queries.md#queries) is a request for information made by end-users of applications through an interface and processed by a full-node. Users can query information about the network, the application itself, and application state directly from the application's stores or modules. Note that queries are different from [transactions](../core/transactions.md) (view the lifecycle [here](../basics/tx-lifecycle.md)), particularly in that they do not require consensus to be processed (as they do not trigger state-transitions); they can be fully handled by one full-node.
For the purpose of explaining the query lifecycle, let's say `Query` is requesting a list of delegations made by a certain delegator address in the application called `app`. As to be expected, the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module handles this query. But first, there are a few ways `Query` can be created by users.
### CLI
The main interface for an application is the command-line interface. Users connect to a full-node and run the CLI directly from their machines - the CLI interacts directly with the full-node. To create `Query` from their terminal, users type the following command:
```bash
appcli query staking delegations <delegatorAddress>
```
This query command was defined by the [`staking`](https://github.com/cosmos/cosmos-sdk/tree/master/x/staking/spec) module developer and added to the list of subcommands by the application developer when creating the CLI. The code for this particular command is the following:
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/client/cli/query.go#L250-L293
Note that the general format is as follows:
```bash
appcli query [moduleName] [command] <arguments> --flag <flagArg>
```
To provide values such as `--node` (the full-node the CLI connects to), the user can use the `config` command to set themn or provide them as flags.
The CLI understands a specific set of commands, defined in a hierarchical structure by the application developer: from the [root command](./cli.md#root-command) (`appcli`), the type of command (`query`), the module that contains the command (`staking`), and command itself (`delegations`). Thus, the CLI knows exactly which module handles this command and directly passes the call there.
### REST
Another interface through which users can make queries is through HTTP Requests to a [REST server](./rest.md#rest-server). The REST server contains, among other things, a [`CLIContext`](#clicontext) and [mux](./rest.md#gorilla-mux) router. The request looks like this:
```bash
GET http://localhost:{PORT}/staking/delegators/{delegatorAddr}/delegations
```
To provide values such as `--node` (the full-node the CLI connects to) that are required by [`baseReq`](../building-modules/module-interfaces.md#basereq), the user must configure their local REST server with the values or provide them in the request body.
The router automatically routes the `Query` HTTP request to the staking module `delegatorDelegationsHandlerFn()` function.
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/client/rest/query.go#L103-L106
Since this function is defined within the module and thus has no inherent knowledge of the application `Query` belongs to, it takes in the application `codec` and `CLIContext` as parameters.
To summarize, when users interact with the interfaces, they create a CLI command or HTTP request. `Query` now exists in one of these two forms, but needs to be transformed into an object understood by a full-node.
## Query Preparation
The interactions from the users' perspective are a bit different, but the underlying functions are almost identical because they are implementations of the same command defined by the module developer. This step of processing happens within the CLI or REST server and heavily involves a `CLIContext`.
### CLIContext
The first thing that is created in the execution of a CLI command is a `CLIContext`, while the REST Server directly provides a `CLIContext` for the REST Request handler. A [Context](../core/context.md) is an immutable object that stores all the data needed to process a request on the user side. In particular, a `CLIContext` stores the following:
* **Codec**: The [encoder/decoder](../core/encoding.md) used by the application, used to marshal the parameters and query before making the Tendermint RPC request and unmarshal the returned response into a JSON object.
* **Account Decoder**: The account decoder from the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/master/x/auth/spec) module, which translates `[]byte`s into accounts.
* **RPC Client**: The Tendermint RPC Client, or node, to which the request will be relayed to.
* **Keybase**: A [Key Manager](../basics/accounts.md#keybase) used to sign transactions and handle other operations with keys.
* **Output Writer**: A [Writer](https://golang.org/pkg/io/#Writer) used to output the response.
* **Configurations**: The flags configured by the user for this command, including `--height`, specifying the height of the blockchain to query and `--indent`, which indicates to add an indent to the JSON response.
The `CLIContext` also contains various functions such as `Query()` which retrieves the RPC Client and makes an ABCI call to relay a query to a full-node.
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/context/context.go#L23-L47
The `CLIContext`'s primary role is to store data used during interactions with the end-user and provide methods to interact with this data - it is used before and after the query is processed by the full-node. Specifically, in handling `Query`, the `CLIContext` is utilized to encode the query parameters, retrieve the full-node, and write the output. Prior to being relayed to a full-node, the query needs to be encoded into a `[]byte` form, as full-nodes are application-agnostic and do not understand specific types. The full-node (RPC Client) itself is retrieved using the `CLIContext`, which knows which node the user CLI is connected to. The query is relayed to this full-node to be processed. Finally, the `CLIContext` contains a `Writer` to write output when the response is returned. These steps are further described in later sections.
### Arguments and Route Creation
At this point in the lifecycle, the user has created a CLI command or HTTP Request with all of the data they wish to include in their `Query`. A `CLIContext` exists to assist in the rest of the `Query`'s journey. Now, the next step is to parse the command or request, extract the arguments, create a `queryRoute`, and encode everything. These steps all happen on the user side within the interface they are interacting with.
#### Encoding
In this case, `Query` contains an [address](../basics/accounts.md#addresses) `delegatorAddress` as its only argument. However, the request can only contain `[]byte`s, as it will be relayed to a consensus engine (e.g. Tendermint Core) of a full-node that has no inherent knowledge of the application types. Thus, the `codec` of `CLIContext` is used to marshal the address.
Here is what the code looks like for the CLI command:
```go
delAddr, err := sdk.AccAddressFromBech32(args[0])
bz, err := cdc.MarshalJSON(types.NewQueryDelegatorParams(delAddr))
```
Here is what the code looks like for the HTTP Request:
```go
vars := mux.Vars(r)
bech32delegator := vars["delegatorAddr"]
delegatorAddr, err := sdk.AccAddressFromBech32(bech32delegator)
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
if !ok {
return
}
params := types.NewQueryDelegatorParams(delegatorAddr)
```
#### Query Route Creation
Important to note is that there will never be a "query" object created for `Query`; the SDK actually takes a simpler approach. Instead of an object, all the full-node needs to process a query is its `route` which specifies exactly which module to route the query to and the name of this query type. The `route` will be passed to the application `baseapp`, then module, then [querier](../building-modules/querier.md), and each will understand the `route` and pass it to the appropriate next step. [`baseapp`](../core/baseapp.md#query-routing) will understand this query to be a `custom` query in the module `staking`, and the `staking` module querier supports the type `QueryDelegatorDelegations`. Thus, the route will be `"custom/staking/delegatorDelegations"`.
Here is what the code looks like:
```go
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryDelegatorDelegations)
```
Now, `Query` exists as a set of encoded arguments and a route to a specific module and its query type. It is ready to be relayed to a full-node.
#### ABCI Query Call
The `CLIContext` has a `Query()` function used to retrieve the pre-configured node and relay a query to it; the function takes the query `route` and arguments as parameters. It first retrieves the RPC Client (called the [**node**](../core/node.md)) configured by the user to relay this query to, and creates the `ABCIQueryOptions` (parameters formatted for the ABCI call). The node is then used to make the ABCI call, `ABCIQueryWithOptions()`.
Here is what the code looks like:
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/context/query.go#L75-L112
## RPC
With a call to `ABCIQueryWithOptions()`, `Query` is received by a [full-node](../core/encoding.md) which will then process the request. Note that, while the RPC is made to the consensus engine (e.g. Tendermint Core) of a full-node, queries are not part of consensus and will not be broadcasted to the rest of the network, as they do not require anything the network needs to agree upon.
Read more about ABCI Clients and Tendermint RPC in the Tendermint documentation [here](https://tendermint.com/rpc).
## Application Query Handling
When a query is received by the full-node after it has been relayed from the underlying consensus engine, it is now being handled within an environment that understands application-specific types and has a copy of the state. [`baseapp`](../core/baseapp.md) implements the ABCI [`Query()`](../core/baseapp.md#query) function and handles four different types of queries: `app`, `store`, `p2p`, and `custom`. The `queryRoute` is parsed such that the first string must be one of the four options, then the rest of the path is parsed within the subroutines handling each type of query. The first three types (`app`, `store`, `p2p`) are purely application-level and thus directly handled by `baseapp` or the stores, but the `custom` query type requires `baseapp` to route the query to a module's [querier](../building-modules/querier.md).
Since `Query` is a custom query type from the `staking` module, `baseapp` first parses the path, then uses the `QueryRouter` to retrieve the corresponding querier, and routes the query to the module. The querier is responsible for recognizing this query, retrieving the appropriate values from the application's stores, and returning a response. Read more about queriers [here](../building-modules/querier.md).
Once a result is received from the querier, `baseapp` begins the process of returning a response to the user.
## Response
Since `Query()` is an ABCI function, `baseapp` returns the response as an [`abci.ResponseQuery`](https://tendermint.com/docs/spec/abci/abci.html#messages) type. The `CLIContext` `Query()` routine receives the response and, if `--trust-node` is toggled to `false` and a proof needs to be verified, the response is verified with the `CLIContext` `verifyProof()` function before the response is returned.
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/client/context/query.go#L127-L165
### CLI Response
The application [`codec`](../core/encoding.md) is used to unmarshal the response to a JSON and the `CLIContext` prints the output to the command line, applying any configurations such as `--indent`.
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/client/cli/query.go#L252-L293
### REST Response
The [REST server](./rest.md#rest-server) uses the `CLIContext` to format the response properly, then uses the HTTP package to write the appropriate response or error.
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/staking/client/rest/utils.go#L115-L148
## Next {hide}
Read about how to build a [Command-Line Interface](./cli.md), or a [REST Interface](./rest.md) {hide}
+60
View File
@@ -0,0 +1,60 @@
---
order: 4
synopsis: "This document describes how to create a REST interface for an SDK **application**. A separate document for creating a [**module**](../building-modules/intro.md) REST interface can be found [here](#../module-interfaces.md#rest)."
---
# REST Interface
## Prerequisites {hide}
* [Query Lifecycle](./query-lifecycle.md) {prereq}
* [Application CLI](./cli.md) {prereq}
## Application REST Interface
Building the REST Interface for an application is done by [aggregating REST Routes](#registering-routes) defined in the application's modules. This interface is served by a REST Server [REST server](#rest-server), which route requests and output responses in the application itself. The SDK comes with its own REST Server by default. To enable it, the `rest.ServeCommand` command needs to be added as a subcommand of the `rootCmd` in the `main()` function of the [CLI interface](./cli.md):
```go
rootCmd.AddCommand(rest.ServeCommand(cdc, registerRoutes))
```
Users will then be able to use the application CLI to start a new REST server, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this:
```bash
appcli rest-server --chain-id <chainID> --trust-node
```
Note that if `trust-node` is set to `false`, the REST server will verify the query proof against the merkle root (contained in the block header).
## REST Server
A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return a response to the user. The REST Server defined by the SDK `rest` package contains the following:
* **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux).
* **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction.
* **Keybase:** A [Keybase](../basics/accounts.md#keybase) is a key manager.
* **Logger:** A logger from Tendermint `Log`, a log package structured around key-value pairs that allows logging level to be set differently for different keys. The logger takes `Debug()`, `Info()`, and `Error()`s.
* **Listener:** A [listener](https://golang.org/pkg/net/#Listener) from the net package.
Of the five, the only attribute that application developers need interact with is the `router`: they need to add routes to it so that the REST server can properly handle queries. See the next section for more information on registering routes.
In order to enable the REST Server in an SDK application, the `rest.ServeCommand` needs to be added to the application's command-line interface. See the [above section](#application-rest-interface) for more information.
## Registering Routes
To include routes for each module in an application, the CLI must have some kind of function to register routes in its REST Server. This function is called `RegisterRoutes()`, and is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules/module-interfaces.md#rest) function, application developers simply use the [Module Manager](../building-modules/module-manager.md) to call this function for each module (this is done in the [application's constructor](../basics/app-anatomy.md#constructor-function)).
At the bare minimum, a `RegisterRoutes()` function should use the SDK client package `RegisterRoutes()` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes()` for all of its modules. This is done in the `main.go` file of the CLI (typically located in `./cmd/appcli/main.go`).
```go
func registerRoutes(rs *rest.RestServer) {
client.RegisterRoutes(rs.CliCtx, rs.Mux)
app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux)
}
```
This function is specific to the application and passed in to the `ServeCommand`, which should be added to the `rootCmd` as such:
```go
rootCmd.AddCommand(rest.ServeCommand(cdc, registerRoutes))
```
-196
View File
@@ -1,196 +0,0 @@
# Service Providers
We define 'service providers' as entities providing services for end-users that involve some form of interaction with a Cosmos-SDK based blockchain (this includes the Cosmos Hub). More specifically, this document will be focused around interactions with tokens.
This section does not concern wallet builders that want to provide [Light-Client](https://github.com/cosmos/cosmos-sdk/tree/master/docs/interfaces/lite) functionalities. Service providers are expected to act as trusted point of contact to the blockchain for their end-users.
## High-level description of the architecture
There are three main pieces to consider:
- Full-nodes: To interact with the blockchain.
- Rest Server: This acts as a relayer for HTTP calls.
- Rest API: Define available endpoints for the Rest Server.
## Running a Full-Node
### Installation and configuration
We will describe the steps to run and interact with a full-node for the Cosmos Hub. For other SDK-based blockchain, the process should be similar.
First, you need to [install the software](../cosmos-hub/installation.md).
Then, you can start [running a full-node](../cosmos-hub/join-testnet.md).
### Command-Line interface
Next you will find a few useful CLI commands to interact with the Full-Node.
#### Creating a key-pair
To generate a new key (default secp256k1 elliptic curve):
```bash
gaiacli keys add <your_key_name>
```
The key-pair will be created in your system's password store. This will return the information listed below:
- `NAME`: Name of your key
- `TYPE`: Type of your key, always `local`.
- `ADDRESS`: Your address. Used to receive funds.
- `PUBKEY`: Your public key. Useful for validators.
- `MNEMONIC`: 24-words phrase. **Save this mnemonic somewhere safe**. It is used to recover your
private key in case you forget the password to unlock your system's credentials store.
You can see all your available keys by typing:
```bash
gaiacli keys list
```
#### Checking your balance
After receiving tokens to your address, you can view your account's balance by typing:
```bash
gaiacli account <YOUR_ADDRESS>
```
*Note: When you query an account balance with zero tokens, you will get this error: No account with address <YOUR_ADDRESS> was found in the state. This is expected! We're working on improving our error messages.*
#### Sending coins via the CLI
Here is the command to send coins via the CLI:
```bash
gaiacli tx send <from_key_or_address> <to_address> <amount> \
--chain-id=<name_of_testnet_chain>
```
Parameters:
- `<from_key_or_address>`: Key name or address of sending account.
- `<to_address>`: Address of the recipient.
- `<amount>`: This parameter accepts the format `<value|coinName>`, such as `10faucetToken`.
Flags:
- `--chain-id`: This flag allows you to specify the id of the chain. There will be different ids for different testnet chains and main chain.
#### Help
If you need to do something else, the best command you can run is:
```bash
gaiacli
```
It will display all the available commands. For each command, you can use the `--help` flag to get further information.
## Setting up the Rest Server
The Rest Server acts as an intermediary between the front-end and the full-node. You don't need to run the Rest Server on the same machine as the full-node.
To start the Rest server:
```bash
gaiacli rest-server --node=<full_node_address:full_node_port>
```
Flags:
- `--trust-node`: A boolean. If `true`, light-client verification is disabled. If `false`, it is disabled. For service providers, this should be set to `true`. By default, it set to `true`.
- `--node`: This is where you indicate the address and the port of your full-node. The format is `<full_node_address:full_node_port>`. If the full-node is on the same machine, the address should be `tcp://localhost:26657`.
- `--laddr`: This flag allows you to specify the address and port for the Rest Server (default `1317`). You will mostly use this flag only to specify the port, in which case just input "localhost" for the address. The format is <rest_server_address:port>.
### Listening for incoming transaction
The recommended way to listen for incoming transaction is to periodically query the blockchain through the following endpoint of the LCD:
[`/bank/balance/{address}`](https://cosmos.network/rpc/#/ICS20/get_bank_balances__address_)
## Rest API
The Rest API documents all the available endpoints that you can use to interact
with your full node. It can be found [here](https://cosmos.network/rpc/).
The API is divided into ICS standards for each category of endpoints. For
example, the [ICS20](https://cosmos.network/rpc/#/ICS20/) describes the API to
interact with tokens.
To give more flexibility to developers, we have included the ability to
generate unsigned transactions, [sign](https://cosmos.network/rpc/#/ICS20/post_tx_sign)
and [broadcast](https://cosmos.network/rpc/#/ICS20/post_tx_broadcast) them with
different API endpoints. This allows service providers to use their own signing
mechanism for instance.
In order to generate an unsigned transaction (example with
[coin transfer](https://cosmos.network/rpc/#/ICS20/post_bank_accounts__address__transfers)),
you need to use the field `generate_only` in the body of `base_req`.
## Cosmos SDK Transaction Signing
Cosmos SDK transaction signing is a fairly simple process.
Every Cosmos SDK transaction has a canonical JSON representation. The `gaiacli`
and Stargate REST interfaces provide canonical JSON representations of transactions
and their "broadcast" functions will provide compact Amino (a protobuf-like wire format)
encoding translations.
Things to know when signing messages:
The format is as follows
```json
{
"account_number": XXX,
"chain_id": XXX,
"fee": XXX,
"sequence": XXX,
"memo": XXX,
"msgs": XXX
}
```
The signer must supply `"chain_id"`, `"account number"` and `"sequence number"`.
The `"fee"`, `"msgs"` and `"memo"` fields will be supplied by the transaction
composer interface.
The `"account_number"` and `"sequence"` fields can be queried directly from the
blockchain or cached locally. Getting these numbers wrong, along with the chainID,
is a common cause of invalid signature error. You can load the mempool of a full
node or validator with a sequence of uncommitted transactions with incrementing
sequence numbers and it will mostly do the correct thing.
Before signing, all keys are lexicographically sorted and all white space is
removed from the JSON output.
The signature encoding is the 64-byte concatenation of ECDSArands (i.e. `r || s`),
where `s` is lexicographically less than its inverse in order to prevent malleability.
This is like Ethereum, but without the extra byte for PubKey recovery, since
Tendermint assumes the PubKey is always provided anyway.
Signatures and public key examples in a signed transaction:
``` json
{
"type": "cosmos-sdk/StdTx",
"value": {
"msg": [...],
"signatures": [
{
"pub_key": {
"type": "tendermint/PubKeySecp256k1",
"value": XXX
},
"signature": XXX
}
],
}
}
```
Once signatures are properly generated, insert the JSON into into the generated
transaction and then use the broadcast endpoint.