Merge branch 'master' into adr_gov_split_vote
This commit is contained in:
@@ -71,3 +71,4 @@ Read about the [PROCESS](./PROCESS.md).
|
||||
- [ADR 028: Public Key Addresses](./adr-028-public-key-addresses.md)
|
||||
- [ADR 031: Protobuf Msg Services](./adr-031-msg-service.md)
|
||||
- [ADR 032: Typed Events](./adr-032-typed-events.md)
|
||||
- [ADR 035: Rosetta API Support](./adr-035-rosetta-api-support.md)
|
||||
|
||||
@@ -0,0 +1,274 @@
|
||||
# ADR 035: Rosetta API Support
|
||||
|
||||
## Authors
|
||||
|
||||
- Jonathan Gimeno (@jgimeno)
|
||||
- David Grierson (@senormonito)
|
||||
- Alessio Treglia (@alessio)
|
||||
|
||||
## Context
|
||||
|
||||
[Rosetta API](https://www.rosetta-api.org/) is an open-source specification and set of tools developed by Coinbase to
|
||||
standardise blockchain interactions.
|
||||
|
||||
Through the use of a standard API for integrating blockchain applications it will
|
||||
|
||||
* Be easier for a user to interact with a given blockchain
|
||||
* Allow exchanges to integrate new blockchains quickly and easily
|
||||
* Enable application developers to build cross-blockchain applications such as block explorers, wallets and dApps at
|
||||
considerably lower cost and effort.
|
||||
|
||||
## Decision
|
||||
|
||||
It is clear that adding Rosetta API support to the Cosmos SDK will bring value to all the developers and
|
||||
Cosmos SDK based chains in the ecosystem. How it is implemented is key.
|
||||
|
||||
The driving principles of the proposed design are:
|
||||
|
||||
1. **Extensibility:** it must be as riskless and painless as possible for application developers to set-up network
|
||||
configurations to expose Rosetta API-compliant services.
|
||||
2. **Long term support:** This proposal aims to provide support for all the supported Cosmos SDK release series.
|
||||
3. **Cost-efficiency:** Backporting changes to Rosetta API specifications from `master` to the various stable
|
||||
branches of Cosmos SDK is a cost that needs to be reduced.
|
||||
|
||||
We will achieve these delivering on these principles by the following:
|
||||
|
||||
1. There will be an external repo called [cosmos-rosetta-gateway](https://github.com/tendermint/cosmos-rosetta-gateway)
|
||||
for the implementation of the core Rosetta API features, particularly:
|
||||
a. The types and interfaces. This separates design from implementation detail.
|
||||
b. Some core implementations: specifically, the `Service` functionality as this is independent of the Cosmos SDK version.
|
||||
2. Due to differences between the Cosmos release series, each series will have its own specific API implementations of `Network` struct and `Adapter` interface.
|
||||
3. There will be two options for starting an API service in applications:
|
||||
a. API shares the application process
|
||||
b. API-specific process.
|
||||
|
||||
|
||||
## Architecture
|
||||
|
||||
### The External Repo
|
||||
|
||||
As section will describe the proposed external library, including the service implementation, plus the defined types and interfaces.
|
||||
|
||||
#### Service
|
||||
|
||||
`Service` is a simple `struct` that is started and listens to the port specified in the options. This is meant to be used across all the Cosmos SDK versions that are actively supported.
|
||||
|
||||
The constructor follows:
|
||||
|
||||
`func New(options Options, network Network) (*Service, error)`
|
||||
|
||||
#### Types
|
||||
|
||||
`Service` accepts an `Options` `struct` that holds service configuration values, such as the port the service would be listening to:
|
||||
|
||||
```golang
|
||||
type Options struct {
|
||||
ListenAddress string
|
||||
}
|
||||
```
|
||||
|
||||
The `Network` type holds network-specific properties (i.e. configuration values) and adapters. Pre-configured concrete types will be available for each Cosmos SDK release. Applications can also create their own custom types.
|
||||
|
||||
```golang
|
||||
type Network struct {
|
||||
Properties rosetta.NetworkProperties
|
||||
Adapter rosetta.Adapter
|
||||
}
|
||||
```
|
||||
|
||||
A `NetworkProperties` `struct` comprises basic values that are required by a Rosetta API `Service`:
|
||||
|
||||
```golang
|
||||
type NetworkProperties struct {
|
||||
// Mandatory properties
|
||||
Blockchain string
|
||||
Network string
|
||||
SupportedOperations []string
|
||||
}
|
||||
```
|
||||
|
||||
Rosetta API services use `Blockchain` and `Network` as identifiers, e.g. the developers of _gaia_, the application that powers the Cosmos Hub, may want to set those to `Cosmos Hub` and `cosmos-hub-3` respectively.
|
||||
|
||||
`SupportedOperations` contains the transaction types that are supported by the library. At the present time,
|
||||
only `cosmos-sdk/MsgSend` is supported in Launchpad. Additional operations will be added in due time.
|
||||
|
||||
For Launchpad we will map the amino type name to the operation supported, in Stargate we will use the protoc one.
|
||||
|
||||
#### Interfaces
|
||||
|
||||
Every SDK version uses a different format to connect (rpc, gRpc, etc), we have abstracted this in what is called the
|
||||
Adapter. This is an interface that defines the methods an adapter implementation must provide in order to be used
|
||||
in the `Network` interface.
|
||||
|
||||
Each Cosmos SDK release series will have their own Adapter implementations.
|
||||
Developers can implement their own custom adapters as required.
|
||||
|
||||
```golang
|
||||
type Adapter interface {
|
||||
DataAPI
|
||||
ConstructionAPI
|
||||
}
|
||||
|
||||
type DataAPI interface {
|
||||
server.NetworkAPIServicer
|
||||
server.AccountAPIServicer
|
||||
server.MempoolAPIServicer
|
||||
server.BlockAPIServicer
|
||||
server.ConstructionAPIServicer
|
||||
}
|
||||
|
||||
type ConstructionAPI interface {
|
||||
server.ConstructionAPIServicer
|
||||
}
|
||||
```
|
||||
|
||||
Example in pseudo-code of an Adapter interface:
|
||||
|
||||
```golang
|
||||
type SomeAdapter struct {
|
||||
cosmosClient client
|
||||
tendermintClient client
|
||||
}
|
||||
|
||||
func NewSomeAdapter(cosmosClient client, tendermintClient client) rosetta.Adapter {
|
||||
return &SomeAdapter{cosmosClient: cosmosClient, tendermintClient: tendermintClient}
|
||||
}
|
||||
|
||||
func (s SomeAdapter) NetworkStatus(ctx context.Context, request *types.NetworkRequest) (*types.NetworkStatusResponse, *types.Error) {
|
||||
resp := s.tendermintClient.CallStatus()
|
||||
// ... Parse status Response
|
||||
// build NetworkStatusResponse
|
||||
return networkStatusResp, nil
|
||||
}
|
||||
|
||||
func (s SomeAdapter) AccountBalance(ctx context.Context, request *types.AccountBalanceRequest) (*types.AccountBalanceResponse, *types.Error) {
|
||||
resp := s.cosmosClient.Account()
|
||||
// ... Parse cosmos specific account response
|
||||
// build AccountBalanceResponse
|
||||
return AccountBalanceResponse, nil
|
||||
}
|
||||
|
||||
// And we repeat for all the methods defined in the interface.
|
||||
```
|
||||
|
||||
For further information about the `Servicer` interfaces, please refer to the [Coinbase's rosetta-sdk-go's documentation](https://pkg.go.dev/github.com/coinbase/rosetta-sdk-go@v0.5.9/server).
|
||||
|
||||
### 2. Cosmos SDK Implementation
|
||||
|
||||
As described, each Cosmos SDK release series will have version specific implementations of `Network` and `Adapter`, as
|
||||
well as a `NewNetwork` constructor.
|
||||
|
||||
Due to separation of interface and implementation, application developers have the option to override as needed,
|
||||
using this code as reference.
|
||||
|
||||
```golang
|
||||
// NewNetwork returns the default application configuration.
|
||||
func NewNetwork(options Options) service.Network {
|
||||
cosmosClient := cosmos.NewClient(fmt.Sprintf("http://%s", options.CosmosEndpoint))
|
||||
tendermintClient := tendermint.NewClient(fmt.Sprintf("http://%s", options.TendermintEndpoint))
|
||||
|
||||
return service.Network{
|
||||
Properties: rosetta.NetworkProperties{
|
||||
Blockchain: options.Blockchain,
|
||||
Network: options.Network,
|
||||
SupportedOperations: []string{OperationTransfer},
|
||||
},
|
||||
Adapter: newAdapter(
|
||||
cosmosClient,
|
||||
tendermintClient,
|
||||
properties{
|
||||
Blockchain: options.Blockchain,
|
||||
Network: options.Network,
|
||||
OfflineMode: options.OfflineMode,
|
||||
},
|
||||
),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. API service invocation
|
||||
|
||||
As stated at the start, application developers will have two methods for invocation of the Rosetta API service:
|
||||
|
||||
1. Shared process for both application and API
|
||||
2. Standalone API service
|
||||
|
||||
#### Shared Process (Only Stargate)
|
||||
|
||||
Rosetta API service could run within the same execution process as the application. New configuration option and
|
||||
command line flags would be provided to support this:
|
||||
|
||||
```golang
|
||||
if config.Rosetta.Enable {
|
||||
....
|
||||
get contecxt, flags, etc
|
||||
...
|
||||
|
||||
h, err := service.New(
|
||||
service.Options{ListenAddress: config.Rosetta.ListenAddress},
|
||||
rosetta.NewNetwork(cdc, options),
|
||||
)
|
||||
if err != nil {
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
go func() {
|
||||
if err := h.Start(config); err != nil {
|
||||
errCh <- err
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Separate API service
|
||||
|
||||
Client application developers can write a new command to launch a Rosetta API server as a separate process too:
|
||||
|
||||
```golang
|
||||
func RosettaCommand(cdc *codec.Codec) *cobra.Command {
|
||||
|
||||
...
|
||||
cmd := &cobra.Command{
|
||||
Use: "rosetta",
|
||||
....
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
....
|
||||
get contecxt, flags, etc
|
||||
...
|
||||
|
||||
h, err := service.New(
|
||||
service.Options{Endpoint: endpoint},
|
||||
rosetta.NewNetwork(cdc, options),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
...
|
||||
|
||||
h.Start()
|
||||
}
|
||||
}
|
||||
...
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## Status
|
||||
|
||||
Proposed
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- Out-of-the-box Rosetta API support within Cosmos SDK.
|
||||
- Blockchain interface standardisation
|
||||
|
||||
## References
|
||||
|
||||
- https://www.rosetta-api.org/
|
||||
- https://github.com/tendermint/cosmos-rosetta-gateway
|
||||
@@ -148,7 +148,8 @@ AppModule 在模块上公开了一组有用的方法,这些方法有助于将
|
||||
模块的`处理程序`通常在名为 `handler.go` 的文件中定义,并包括:
|
||||
|
||||
- NewHandler 将消息发到对应的回调 `handler`。 该函数返回一个 `handler` 函数,此前这个函数在 `AppModule` 中注册,以在应用程序的模块管理器中用于初始化应用程序的路由器。接下来是 [nameservice tutorial](https://github.com/cosmos/sdk-tutorials/tree/master/nameservice) 的一个例子。
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/master/nameservice/x/nameservice/handler.go#L12-L26
|
||||
|
||||
+++ https://github.com/cosmos/sdk-tutorials/blob/86a27321cf89cc637581762e953d0c07f8c78ece/nameservice/x/nameservice/internal/keeper/querier.go#L19-L32
|
||||
|
||||
- 模块定义的每种消息类型的处理函数。开发人员在这些函数中编写消息处理逻辑。这通常包括进行状态检查以确保消息有效,并调用 [`keeper`](https://docs.cosmos.network/master/basics/app-anatomy.html#keeper) 的方法来更新状态。
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 5
|
||||
order: 6
|
||||
-->
|
||||
|
||||
# Interfaces
|
||||
@@ -12,4 +12,3 @@ This repository contains documentation on interfaces for Cosmos SDK applications
|
||||
2. [Lifecycle of a Query](./query-lifecycle.md)
|
||||
3. [Command-Line Interface](./cli.md)
|
||||
4. [Rest Interface](./rest.md)
|
||||
|
||||
|
||||
Generated
+753
-824
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -14,6 +14,6 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"vuepress-theme-cosmos": "^1.0.173"
|
||||
"vuepress-theme-cosmos": "^1.0.175"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<!--
|
||||
order: false
|
||||
parent:
|
||||
order: 5
|
||||
-->
|
||||
|
||||
# Running a Node
|
||||
|
||||
This folder contains documentation on how to run a node and interact with it.
|
||||
|
||||
1. [Setting up the keyring](./keyring.md)
|
||||
2. [Running a Node](./run-node.md)
|
||||
3. [Interacting with a Node](./interact-node.md)
|
||||
@@ -0,0 +1,46 @@
|
||||
<!--
|
||||
order: 3
|
||||
-->
|
||||
|
||||
# Interacting with the Node
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Running a Node](./run-node.md) {prereq}
|
||||
|
||||
## Via CLI
|
||||
|
||||
Now that your chain is running, it is time to try sending tokens from the first account you created to a second account. In a new terminal window, start by running the following query command:
|
||||
|
||||
```bash
|
||||
simd query account $MY_VALIDATOR_ADDRESS --chain-id my-test-chain
|
||||
```
|
||||
|
||||
You should see the current balance of the account you created, equal to the original balance of `stake` you granted it minus the amount you delegated via the `gentx`. Now, create a second account:
|
||||
|
||||
```bash
|
||||
simd keys add recipient --keyring-backend test
|
||||
|
||||
# Put the generated address in a variable for later use.
|
||||
RECIPIENT=$(simd keys show recipient -a --keyring-backend test)
|
||||
```
|
||||
|
||||
The command above creates a local key-pair that is not yet registered on the chain. An account is created the first time it receives tokens from another account. Now, run the following command to send tokens to the `recipient` account:
|
||||
|
||||
```bash
|
||||
simd tx send $MY_VALIDATOR_ADDRESS $RECIPIENT 1000stake --chain-id my-test-chain
|
||||
|
||||
# Check that the recipient account did receive the tokens.
|
||||
simd query account $RECIPIENT --chain-id my-test-chain
|
||||
```
|
||||
|
||||
Finally, delegate some of the stake tokens sent to the `recipient` account to the validator:
|
||||
|
||||
```bash
|
||||
simd tx staking delegate $(simd keys show my_validator --bech val -a --keyring-backend test) 500stake --from recipient --chain-id my-test-chain
|
||||
|
||||
# Query the total delegations to `validator`.
|
||||
simd query staking delegations-to $(simd keys show my_validator --bech val -a --keyring-backend test) --chain-id my-test-chain
|
||||
```
|
||||
|
||||
You should see two delegations, the first one made from the `gentx`, and the second one you just performed from the `recipient` account.
|
||||
@@ -1,28 +1,32 @@
|
||||
<!--
|
||||
order: 3
|
||||
order: 1
|
||||
-->
|
||||
|
||||
# The keyring
|
||||
# Setting up the keyring
|
||||
|
||||
This document describes how to configure and use the keyring and its various backends 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). {synopsis}
|
||||
This document describes how to configure and use the keyring and its various backends for an [**application**](../basics/app-anatomy.md). {synopsis}
|
||||
|
||||
The keyring holds the private/public keypairs used to interact with a node. For instance, a validator key needs to be set up before running the blockchain node, so that blocks can be correctly signed. The private key can be stored in different locations, called "backends", such as a file or the operating system's own key storage.
|
||||
|
||||
## Available backends for the keyring
|
||||
|
||||
Starting with the v0.38.0 release, Cosmos SDK comes with a new keyring implementation
|
||||
that provides a set of commands to manage cryptographic keys in a secure fashion. The
|
||||
new keyring supports multiple storage backends, some of which may not be available on
|
||||
all operating systems.
|
||||
|
||||
## The `os` backend
|
||||
### The `os` backend
|
||||
|
||||
The `os` backend relies on operating system-specific defaults to handle key storage
|
||||
securely. Typically, operating systems credentials sub-systems handle passwords prompt,
|
||||
private keys storage, and user sessions according to their users password policies. Here
|
||||
securely. Typically, an operating system's credential sub-system handles password prompts,
|
||||
private keys storage, and user sessions according to the user's password policies. Here
|
||||
is a list of the most popular operating systems and their respective passwords manager:
|
||||
|
||||
* macOS (since Mac OS 8.6): [Keychain](https://support.apple.com/en-gb/guide/keychain-access/welcome/mac)
|
||||
* Windows: [Credentials Management API](https://docs.microsoft.com/en-us/windows/win32/secauthn/credentials-management)
|
||||
* GNU/Linux:
|
||||
* [libsecret](https://gitlab.gnome.org/GNOME/libsecret)
|
||||
* [kwallet](https://api.kde.org/frameworks/kwallet/html/index.html)
|
||||
- macOS (since Mac OS 8.6): [Keychain](https://support.apple.com/en-gb/guide/keychain-access/welcome/mac)
|
||||
- Windows: [Credentials Management API](https://docs.microsoft.com/en-us/windows/win32/secauthn/credentials-management)
|
||||
- GNU/Linux:
|
||||
- [libsecret](https://gitlab.gnome.org/GNOME/libsecret)
|
||||
- [kwallet](https://api.kde.org/frameworks/kwallet/html/index.html)
|
||||
|
||||
GNU/Linux distributions that use GNOME as default desktop environment typically come with
|
||||
[Seahorse](https://wiki.gnome.org/Apps/Seahorse). Users of KDE based distributions are
|
||||
@@ -34,10 +38,10 @@ client.
|
||||
designed to meet users' most common needs and provide them with a comfortable
|
||||
experience without compromising on security.
|
||||
|
||||
## The `file` backend
|
||||
### The `file` backend
|
||||
|
||||
The `file` backend more closely resembles the keybase implementation used prior to
|
||||
v0.38.1. It stores the keyring encrypted within the apps configuration directory. This
|
||||
v0.38.1. It stores the keyring encrypted within the app's configuration directory. This
|
||||
keyring will request a password each time it is accessed, which may occur multiple
|
||||
times in a single command resulting in repeated password prompts. If using bash scripts
|
||||
to execute commands using the `file` option you may want to utilize the following format
|
||||
@@ -54,7 +58,7 @@ $ echo $KEYPASSWD | gaiacli keys show me # single promp
|
||||
The first time you add a key to an empty keyring, you will be prompted to type the password twice.
|
||||
:::
|
||||
|
||||
## The `pass` backend
|
||||
### The `pass` backend
|
||||
|
||||
The `pass` backend uses the [pass](https://www.passwordstore.org/) utility to manage on-disk
|
||||
encryption of keys' sensitive data and metadata. Keys are stored inside `gpg` encrypted files
|
||||
@@ -78,15 +82,42 @@ $ pass init <GPG_KEY_ID>
|
||||
Replace `<GPG_KEY_ID>` with your GPG key ID. You can use your personal GPG key or an alternative
|
||||
one you may want to use specifically to encrypt the password store.
|
||||
|
||||
## The `test` backend
|
||||
### The `test` backend
|
||||
|
||||
The `test` backend is a password-less variation of the `file` backend. Keys are stored
|
||||
unencrypted on disk. This backend is meant for testing purposes only and **should never be used
|
||||
in production environments**.
|
||||
|
||||
## The `kwallet` backend
|
||||
### The `kwallet` backend
|
||||
|
||||
The `kwallet` backend uses `KDE Wallet Manager`, which comes installed by default on the
|
||||
GNU/Linux distributions that ships KDE as default desktop environment. Please refer to
|
||||
[KWallet Handbook](https://docs.kde.org/stable5/en/kdeutils/kwallet5/index.html) for more
|
||||
information.
|
||||
|
||||
## Adding keys to the keyring
|
||||
|
||||
::: warning
|
||||
Make sure you can build your own binary, and replace `simd` with the name of your binary in the snippets.
|
||||
:::
|
||||
|
||||
Applications developed using the Cosmos SDK come with the `keys` subcommand. For the purpose of this tutorial, we're running the `simd` CLI, which is an application built using the Cosmos SDK for testing and educational purposes. For more information, see [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp).
|
||||
|
||||
You can use `simd keys` for help about the keys command and `simd keys [command] --help` for more information about a particular subcommand.
|
||||
|
||||
::: tip
|
||||
You can also enable auto-completion with the `simd completion` command. For example, at the start of a bash session, run `. <(simd completion)`, and all `simd` subcommands will be auto-completed.
|
||||
:::
|
||||
|
||||
To create a new key in the keyring, run the `add` subcommand with a `<key_name>` argument. For the purpose of this tutorial, we will solely use the `test` backend, and call our new key `my_validator`. This key will be used in the next section.
|
||||
|
||||
```bash
|
||||
$ simd keys add my_validator --keyring-backend test
|
||||
|
||||
# Put the generated address in a variable for later use.
|
||||
MY_VALIDATOR_ADDRESS=$(simd keys show my_validator -a --keyring-backend test)
|
||||
```
|
||||
|
||||
This command generates a new 24-word mnemonic phrase, persists it to the relevant backend, and outputs information about the keypair. If this keypair will be used to hold value-bearing tokens, be sure to write down the mnemonic phrase somewhere safe!
|
||||
|
||||
By default, the keyring generates a `secp256k1` keypair. The keyring also supports `ed25519` keys, which may be created by passing the `--algo ed25519` flag. A keyring can of course hold both types of keys simultaneously, and the Cosmos SDK's `x/auth` module (in particular its [AnteHandlers](../core/baseapp.md#antehandler)) supports natively these two public key algorithms.
|
||||
@@ -0,0 +1,90 @@
|
||||
<!--
|
||||
order: 2
|
||||
-->
|
||||
|
||||
# Running a Node
|
||||
|
||||
Now that the application is ready and the keyring populated, it's time to see how to run the blockchain node. In this section, the application we are running is called [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp), and its corresponding CLI binary `simd`. {synopsis}
|
||||
|
||||
## Pre-requisite Readings
|
||||
|
||||
- [Anatomy of an SDK Application](../basics/app-anatomy.md) {prereq}
|
||||
- [Setting up the keyring](./keyring.md) {prereq}
|
||||
|
||||
## Initialize the Chain
|
||||
|
||||
::: warning
|
||||
Make sure you can build your own binary, and replace `simd` with the name of your binary in the snippets.
|
||||
:::
|
||||
|
||||
Before actually running the node, we need to initialize the chain, and most importantly its genesis file. This is done with the `init` subcommand:
|
||||
|
||||
```bash
|
||||
# The argument <moniker> is the custom username of your node, it should be human-readable.
|
||||
simd init <moniker> --chain-id my-test-chain
|
||||
```
|
||||
|
||||
The command above creates all the configuration files needed for your node to run, as well as a default genesis file, which defines the initial state of the network. All these configuration files are in `~/.simapp` by default, but you can overwrite the location of this folder by passing the `--home` flag.
|
||||
|
||||
The `~/.simapp` folder has the following structure:
|
||||
|
||||
```bash
|
||||
. # ~/.simapp
|
||||
|- data # Contains the databases used by the node.
|
||||
|- config/
|
||||
|- app.toml # Application-related configuration file.
|
||||
|- config.toml # Tendermint-related configuration file.
|
||||
|- genesis.json # The genesis file.
|
||||
|- node_key.json # Private key to use for node authentication in the p2p protocol.
|
||||
|- priv_validator_key.json # Private key to use as a validator in the consensus protocol.
|
||||
```
|
||||
|
||||
Before starting the chain, you need to populate the state with at least one account. To do so, first [create a new account in the keyring](./keyring.md#adding-keys-to-the-keyring) named `my_validator` under the `test` keyring backend (feel free to choose another name and another backend).
|
||||
|
||||
Now that you have created a local account, go ahead and grant it some `stake` tokens in your chain's genesis file. Doing so will also make sure your chain is aware of this account's existence:
|
||||
|
||||
```bash
|
||||
simd add-genesis-account $MY_VALIDATOR_ADDRESS 100000000stake
|
||||
```
|
||||
|
||||
Recall that `$MY_VALIDATOR_ADDRESS` is a variable that holds the address of the `my_validator` key in the [keyring](./keyring.md#adding-keys-to-the-keyring). Also note that the tokens in the SDK have the `{amount}{denom}` format: `amount` is is a 18-digit-precision decimal number, and `denom` is the unique token identifier with its denomination key (e.g. `atom` or `uatom`). Here, we are granting `stake` tokens, as `stake` is the token identifier used for staking in [`simapp`](https://github.com/cosmos/cosmos-sdk/tree/v0.40.0-rc2/simapp). For your own chain with its own staking denom, that token identifier should be used instead.
|
||||
|
||||
Now that your account has some tokens, you need to add a validator to your chain. Validators are special full-nodes that participate in the consensus process (implemented in the [underlying consensus engine](../intro/sdk-app-architecture.md#tendermint)) in order to add new blocks to the chain. Any account can declare its intention to become a validator operator, but only those with sufficient delegation get to enter the active set (for example, only the top 125 validator candidates with the most delegation get to be validators in the Cosmos Hub). For this guide, you will add your local node (created via the `init` command above) as a validator of your chain. Validators can be declared before a chain is first started via a special transaction included in the genesis file called a `gentx`:
|
||||
|
||||
```bash
|
||||
# Create a gentx.
|
||||
simd gentx my_validator --amount 100000stake --chain-id my-test-chain --keyring-backend test
|
||||
|
||||
# Add the gentx to the genesis file.
|
||||
simd collect-gentxs
|
||||
```
|
||||
|
||||
A `gentx` does three things:
|
||||
|
||||
1. Registers the `validator` account you created as a validator operator account (i.e. the account that controls the validator).
|
||||
2. Self-delegates the provided `amount` of staking tokens.
|
||||
3. Link the operator account with a Tendermint node pubkey that will be used for signing blocks. If no `--pubkey` flag is provided, it defaults to the local node pubkey created via the `simd init` command above.
|
||||
|
||||
For more information on `gentx`, use the following command:
|
||||
|
||||
```bash
|
||||
simd gentx --help
|
||||
```
|
||||
|
||||
## Run a Localnet
|
||||
|
||||
Now that everything is set up, you can finally start your node:
|
||||
|
||||
```bash
|
||||
simd start
|
||||
```
|
||||
|
||||
You should see blocks come in.
|
||||
|
||||
The previous command allow you to run a single node. This is enough for the next section on interacting with this node, but you may wish to run multiple nodes at the same time, and see how consensus happens between them.
|
||||
|
||||
The naive way would be to run the same commands again in separate terminal windows. This is possible, however in the SDK, we leverage the power of [Docker Compose](https://docs.docker.com/compose/) to run a localnet. If you need inspiration on how to set up your own localnet with Docker Compose, you can have a look at the SDK's [`docker-compose.yml`](https://github.com/cosmos/cosmos-sdk/blob/v0.40.0-rc2/docker-compose.yml).
|
||||
|
||||
## Next {hide}
|
||||
|
||||
Read about the [Interacting with your Node](./interact-node.md) {hide}
|
||||
@@ -33,7 +33,7 @@ if there was an error.
|
||||
## Data Folder Layout
|
||||
|
||||
`$DAEMON_HOME/cosmovisor` is expected to belong completely to `cosmovisor` and
|
||||
subprocesses the controlled by it. The folder content is organised as follows:
|
||||
subprocesses that are controlled by it. The folder content is organised as follows:
|
||||
|
||||
```
|
||||
.
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
# Quick Start
|
||||
|
||||
This guide serves as a practical introduction to building blockchains with the Cosmos SDK. It shows how to scaffold the code for a basic blockchain node, build and run it. Several important concepts of the Cosmos SDK are introduced along the way.
|
||||
|
||||
## Setup
|
||||
|
||||
::: tip
|
||||
To follow this guide, you need to [install golang](https://golang.org/doc/install) and set [your \$GOPATH environment variable](https://golang.org/doc/code.html#GOPATH)
|
||||
:::
|
||||
|
||||
::: warning
|
||||
Make sure you are using the latest stable version of golang available on https://golang.org/dl/
|
||||
:::
|
||||
|
||||
First, download the [`scaffold`](https://github.com/cosmos/scaffold) tool:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/cosmos/scaffold
|
||||
```
|
||||
|
||||
The `scaffold` tool lets you easily scaffold boilerplate Cosmos SDK applications. Once you have downloaded it, simply install it on your machine:
|
||||
|
||||
```bash
|
||||
cd scaffold
|
||||
make
|
||||
```
|
||||
|
||||
## Create a Basic Cosmos SDK Blockchain
|
||||
|
||||
To create a basic Cosmos SDK application, simply type in the following command:
|
||||
|
||||
```bash
|
||||
scaffold app <lvl> <username|org> <repo>
|
||||
```
|
||||
|
||||
There are multiple levels of apps to choose from, they can be found [here](https://github.com/cosmos/scaffold/blob/master/docs/app.md).
|
||||
|
||||
where `username|org` is the name of your github/gitlab/atlassian username or organisation, and `repo` the name of the distant repository you would push your application too. These arguments are used to configure the imports so that people can easily download and install your application once (if) you upload it.
|
||||
|
||||
The command above creates a starter application in a new folder named after the `repo` argument. This application contains the [basic logic most SDK applications](../intro/sdk-app-architecture.md) need as well as a set of standard [modules](../building-modules/intro.md) already hooked up. You can find which level consists of which modules [here](https://github.com/cosmos/scaffold/blob/master/docs/app.md)
|
||||
|
||||
The structure of the generated app will look like similar to the [recommended folder structure](../building-modules/structure.md). Below you will find a simple break down of some of the files.
|
||||
|
||||
- `app.go` is the [main file](../basics/app-anatomy.md#core-application-file) defining the application logic. This is where the state is instantiated and modules are declared. This is also where the Cosmos SDK is imported as a dependency to help build the application.
|
||||
- `export.go` is a helper file used to export the state of the application into a new genesis file. It is helpful when you want to upgrade your chain to a new (breaking) version.
|
||||
- `acli/main.go` builds the command-line interface for your blockchain application. It enables end-users to create transactions and query the chain for information.
|
||||
- `aud/main.go` builds the main [daemon client](../basics/app-anatomy.md#node-client) of the chain. It is used to run a full-node that will connect to peers and sync its local application state with the latest state of the network.
|
||||
- `go.mod` helps manage dependencies. The two main dependencies used are the Cosmos SDK to help build the application, and Tendermint to replicate it.
|
||||
- `x/` is the folder to place all the custom modules built specifically for the application. In general, most of the modules used in an application have already been built by third-party developers and only need to be imported in `app.go`. These modules do not need to be cloned into the application's `x/` folder. This is why the basic application shown above, which uses several modules, works despite having an empty `x/` folder.
|
||||
|
||||
## Run your Blockchain
|
||||
|
||||
First, install the two main entry points of your blockchain, `aud` and `acli`:
|
||||
|
||||
```bash
|
||||
go mod tidy
|
||||
make install
|
||||
```
|
||||
|
||||
Make sure the clients are properly installed:
|
||||
|
||||
```bash
|
||||
acli --help
|
||||
aud --help
|
||||
```
|
||||
|
||||
Now that you have your daemon client `aud` and your command-line interface `acli` installed, go ahead and initialize your chain:
|
||||
|
||||
```bash
|
||||
aud init <node-moniker> --chain-id test
|
||||
```
|
||||
|
||||
The command above creates all the configuration files needed for your node to run, as well as a default genesis file, which defines the initial state of the network. Before starting the chain, you need to populate the state with at least one account. To do so, first create a new [account](../basics/accounts.md) named `validator` (feel free to choose another name):
|
||||
|
||||
```bash
|
||||
acli keys add validator
|
||||
```
|
||||
|
||||
Now that you have created a local account, go ahead and grant it `stake` tokens in your chain's genesis file. Doing so will also make sure your chain is aware of this account's existence:
|
||||
|
||||
```bash
|
||||
aud add-genesis-account $(acli keys show validator -a) 100000000stake
|
||||
```
|
||||
|
||||
Now that your account has some tokens, you need to add a validator to your chain. Validators are special full-nodes that participate in the consensus process (implemented in the [underlying consensus engine](../intro/sdk-app-architecture.md#tendermint)) in order to add new blocks to the chain. Any account can declare its intention to become a validator operator, but only those with sufficient delegation get to enter the active set (for example, only the top 125 validator candidates with the most delegation get to be validators in the Cosmos Hub). For this guide, you will add your local node (created via the `init` command above) as a validator of your chain. Validators can be declared before a chain is first started via a special transaction included in the genesis file called a `gentx`:
|
||||
|
||||
```bash
|
||||
// create a gentx
|
||||
aud gentx --name validator --amount 100000stake
|
||||
|
||||
// add the gentx to the genesis file
|
||||
aud collect-gentxs
|
||||
```
|
||||
|
||||
A `gentx` does three things:
|
||||
|
||||
1. Makes the `validator` account you created into a validator operator account (i.e. the account that controls the validator).
|
||||
2. Self-delegates the provided `amount` of staking tokens.
|
||||
3. Link the operator account with a Tendermint node pubkey that will be used for signing blocks. If no `--pubkey` flag is provided, it defaults to the local node pubkey created via the `aud init` command above.
|
||||
|
||||
For more on `gentx`, use the following command:
|
||||
|
||||
```bash
|
||||
aud gentx --help
|
||||
```
|
||||
|
||||
Now that everything is set up, you can finally start your node:
|
||||
|
||||
```bash
|
||||
aud start
|
||||
```
|
||||
|
||||
You should see blocks come in.
|
||||
|
||||
## Send Tokens and Increase Delegation
|
||||
|
||||
Now that your chain is running, it is time to try sending tokens from the first account you created to a second account. In a new terminal window, start by running the following query command:
|
||||
|
||||
```bash
|
||||
acli query account $(acli keys show validator -a) --chain-id test
|
||||
```
|
||||
|
||||
You should see the current balance of the account you created, equal to the original balance of `stake` you granted it minus the amount you delegated via the `gentx`. Now, create a second account:
|
||||
|
||||
```bash
|
||||
acli keys add receiver
|
||||
```
|
||||
|
||||
The command above creates a local key-pair that is not yet registered on the chain. An account is registered the first time it receives tokens from another account. Now, run the following command to send tokens to the second account:
|
||||
|
||||
```bash
|
||||
acli tx send $(acli keys show validator -a) $(acli keys show receiver -a) 1000stake --chain-id test
|
||||
```
|
||||
|
||||
Check that the second account did receive the tokens:
|
||||
|
||||
```bash
|
||||
acli query account $(acli keys show receiver -a) --chain-id test
|
||||
```
|
||||
|
||||
Finally, delegate some of the stake tokens sent to the `receiver` account to the validator:
|
||||
|
||||
```bash
|
||||
acli tx staking delegate $(acli keys show validator --bech val -a) 500stake --from receiver --chain-id test
|
||||
```
|
||||
|
||||
Try to query the total delegations to `validator`:
|
||||
|
||||
```bash
|
||||
acli query staking delegations-to $(acli keys show validator --bech val -a) --chain-id test
|
||||
```
|
||||
|
||||
You should see two delegations, the first one made from the `gentx`, and the second one you just performed from the `receiver` account.
|
||||
|
||||
## Next
|
||||
|
||||
Congratulations on making it to the end of this short introduction guide! If you want to learn more, check out the following resources:
|
||||
|
||||
- [How to build a full SDK application from scratch](https://tutorials.cosmos.network/nameservice/tutorial/00-intro.html).
|
||||
- [Read the Cosmos SDK Documentation](../intro/overview.md).
|
||||
Reference in New Issue
Block a user