Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Update "Basics" section #7416

Merged
merged 26 commits into from
Oct 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
2a44adf
Prettier
amaury1093 Sep 30, 2020
9dd18e9
docs: Update "Basics" section
amaury1093 Sep 30, 2020
fb27d5d
appcli -> appd
amaury1093 Sep 30, 2020
a0479ae
Better wording
amaury1093 Sep 30, 2020
b06ca72
Fix to appCodec
amaury1093 Sep 30, 2020
004a87a
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Oct 1, 2020
f7513f0
Add gRPC mention
amaury1093 Oct 1, 2020
abe3433
Add grpc
amaury1093 Oct 1, 2020
291f969
Reference simapp code
amaury1093 Oct 1, 2020
ec03152
Merge branch 'master' into am-6953-basic
amaury1093 Oct 1, 2020
9a39807
Merge branch 'master' into am-6953-basic
amaury1093 Oct 5, 2020
c00ef48
Merge branch 'master' into am-6953-basic
amaury1093 Oct 6, 2020
5779cda
Update docs/basics/accounts.md
amaury1093 Oct 7, 2020
6a0192d
Add section about gRPC query services
amaury1093 Oct 7, 2020
9b29d10
Merge branch 'am-6953-basic' of ssh://github.com/cosmos/cosmos-sdk in…
amaury1093 Oct 7, 2020
97035de
Optional LegacyQuerierHandler
amaury1093 Oct 7, 2020
8083ebd
Clearer docs
amaury1093 Oct 7, 2020
0038246
Update docs/basics/app-anatomy.md
amaury1093 Oct 8, 2020
69b4c87
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Oct 12, 2020
66cf3ce
Update docs/basics/app-anatomy.md
amaury1093 Oct 12, 2020
048a28d
Address comments
amaury1093 Oct 12, 2020
da83743
Merge branch 'am-6953-basic' of ssh://github.com/cosmos/cosmos-sdk in…
amaury1093 Oct 12, 2020
4873551
Address comments
amaury1093 Oct 12, 2020
933ca8d
Merge branch 'master' of ssh://github.com/cosmos/cosmos-sdk into am-6…
amaury1093 Oct 12, 2020
8362324
Update docs/basics/accounts.md
fedekunze Oct 12, 2020
da629d0
Merge branch 'master' into am-6953-basic
fedekunze Oct 12, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/basics/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ parent:

# Basics

This repository contains reference documentation on the basic concepts of the Cosmos SDK.
This repository contains reference documentation on the basic concepts of the Cosmos SDK.

1. [Anatomy of an SDK Application](./app-anatomy.md)
2. [Lifecycle of a transaction](./tx-lifecycle.md)
3. [Accounts](./accounts.md)
4. [Gas and Fees](./gas-fees.md)

After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material.
After reading the basics, head on to the [Core Reference](../core/README.md) for more advanced material.
72 changes: 36 additions & 36 deletions docs/basics/accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
order: 3
-->

# Accounts
# Accounts

This document describes the in-built accounts system of the Cosmos SDK. {synopsis}

Expand All @@ -12,9 +12,9 @@ This document describes the in-built accounts system of the Cosmos SDK. {synopsi

## Account Definition

In the Cosmos SDK, an *account* designates a pair of *public key* `PubKey` and *private key* `PrivKey`. The `PubKey` can be derived to generate various `Addresses`, which are used to identify users (among other parties) in the application. `Addresses` are also associated with [`message`s](../building-modules/messages-and-queries.md#messages) to identify the sender of the `message`. The `PrivKey` is used to generate [digital signatures](#signatures) to prove that an `Address` associated with the `PrivKey` approved of a given `message`.
In the Cosmos SDK, an _account_ designates a pair of _public key_ `PubKey` and _private key_ `PrivKey`. The `PubKey` can be derived to generate various `Addresses`, which are used to identify users (among other parties) in the application. `Addresses` are also associated with [`message`s](../building-modules/messages-and-queries.md#messages) to identify the sender of the `message`. The `PrivKey` is used to generate [digital signatures](#signatures) to prove that an `Address` associated with the `PrivKey` approved of a given `message`.

To derive `PubKey`s and `PrivKey`s, the Cosmos SDK uses a standard called [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). This standard defines how to build an HD wallet, where a wallet is a set of accounts. At the core of every account, there is a seed, which takes the form of a 12 or 24-words mnemonic. From this mnemonic, it is possible to derive any number of `PrivKey`s using one-way cryptographic function. Then, a `PubKey` can be derived from the `PrivKey`. Naturally, the mnemonic is the most sensitive information, as private keys can always be re-generated if the mnemonic is preserved.
To derive `PubKey`s and `PrivKey`s, the Cosmos SDK uses a standard called [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki). This standard defines how to build an HD wallet, where a wallet is a set of accounts. At the core of every account, there is a seed, which takes the form of a 12 or 24-words mnemonic. From this mnemonic, it is possible to derive any number of `PrivKey`s using one-way cryptographic function. Then, a `PubKey` can be derived from the `PrivKey`. Naturally, the mnemonic is the most sensitive information, as private keys can always be re-generated if the mnemonic is preserved.

```
Account 0 Account 1 Account 2
Expand Down Expand Up @@ -56,65 +56,65 @@ To derive `PubKey`s and `PrivKey`s, the Cosmos SDK uses a standard called [BIP32
+-------------------+
```

In the Cosmos SDK, accounts are stored and managed via an object called a [`Keybase`](#keybase).
In the Cosmos SDK, accounts are stored and managed via an object called a [`Keyring`](#keyring).

## Keybase
## Keyring

A `Keybase` is an object that stores and manages accounts. In the Cosmos SDK, a `Keybase` implementation follows the `Keybase` interface:
A `Keyring` is an object that stores and manages accounts. In the Cosmos SDK, a `Keyring` implementation follows the `Keyring` interface:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/types.go#L13-L86
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keyring/keyring.go#L50-L88

The default implementation of `Keybase` of the Cosmos SDK is `dbKeybase`.
The default implementation of `Keyring` comes from the third-party [`99designs/keyring`](https://github.com/99designs/keyring) library.

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/keybase.go
A few notes on the `Keyring` methods:

A few notes on the `Keybase` methods as implemented in `dbKeybase`:
- `Sign(uid string, msg []byte) ([]byte, tmcrypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form, and this is done in the `GetSignBytes` method. See an example of `message` preparation from the `x/bank` module. Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler).
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/x/bank/types/msgs.go#L51-L54
- `NewAccount(uid, mnemonic, bip39Passwd, hdPath string, algo SignatureAlgo) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `NewAccount` method derives keys and addresses using the algorithm specified in the last argument `algo`. Currently, the SDK supports two public key algorithms:
- `secp256k1`, as implemented in the [SDK's `crypto/keys/secp256k1` package](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/secp256k1/secp256k1.go),
- `ed25519`, as implemented in the [SDK's `crypto/keys/ed25519` package](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/ed25519/ed25519.go).
- `ExportPrivKeyArmor(uid, encryptPassphrase string) (armor string, err error)` exports a private key in ASCII-armored encrypted format, using the given passphrase. You can then either import it again into the keyring using the `ImportPrivKey(uid, armor, passphrase string)` function, or decrypt it into a raw private key using the `UnarmorDecryptPrivKey(armorStr string, passphrase string)` function.

- `Sign(name, passphrase string, msg []byte) ([]byte, crypto.PubKey, error)` strictly deals with the signature of the `message` bytes. Some preliminary work should be done beforehand to prepare and encode the `message` into a canonical `[]byte` form. See an example of `message` preparation from the `auth` module. Note that signature verification is not implemented in the SDK by default. It is deferred to the [`anteHandler`](#antehandler).
+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/txbuilder.go#L176-L209
- `CreateMnemonic(name string, language Language, passwd string, algo SigningAlgo) (info Info, seed string, err error)` creates a new mnemonic and prints it in the logs, but it **does not persist it on disk**.
- `CreateAccount(name, mnemonic, bip39Passwd, encryptPasswd string, account uint32, index uint32) (Info, error)` creates a new account based on the [`bip44 path`](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) and persists it on disk (note that the `PrivKey` is [encrypted with a passphrase before being persisted](https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/mintkey/mintkey.go), it is **never stored unencrypted**). In the context of this method, the `account` and `address` parameters refer to the segment of the BIP44 derivation path (e.g. `0`, `1`, `2`, ...) used to derive the `PrivKey` and `PubKey` from the mnemonic (note that given the same mnemonic and `account`, the same `PrivKey` will be generated, and given the same `account` and `address`, the same `PubKey` and `Address` will be generated). Finally, note that the `CreateAccount` method derives keys and addresses using `secp256k1` as implemented in the [Tendermint library](https://github.com/tendermint/tendermint/tree/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1). As a result, it only works for creating account keys and addresses, not consensus keys. See [`Addresses`](#addresses) for more.

The current implementation of `dbKeybase` is basic and does not offer on-demand locking. If an instance of `dbKeybase` is created, the underlying `db` is locked meaning no other process can access it besides the one in which it was instantiated. This is the reason why the default SDK client uses another implementation of the `Keybase` interface called `lazyKeybase`:


+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/lazy_keybase.go

`lazyKeybase` is simple wrapper around `dbKeybase` which locks the database only when operations are to be performed and unlocks it immediately after. With the `lazyKeybase`, it is possible for the [command-line interface](../interfaces/cli.md) to create a new account while the [rest server](../interfaces/rest.md) is running. It is also possible to pipe multiple CLI commands.
amaury1093 marked this conversation as resolved.
Show resolved Hide resolved
Also see the [`Addresses`](#addresses) section for more information.

## Addresses and PubKeys

`Addresses` and `PubKey`s are both public information that identify actors in the application. There are 3 main types of `Addresses`/`PubKeys` available by default in the Cosmos SDK:

- Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`secp256k1`** curve.
- Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`secp256k1`** curve.
- Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`secp256k1`** curve.
- Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`secp256k1`** curve.
- Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve.

| | Address bech32 Prefix | Pubkey bech32 Prefix | Curve | Address byte length | Pubkey byte length |
|--------------------|-----------------------|----------------------|-------------|---------------------|--------------------|
| ------------------ | --------------------- | -------------------- | ----------- | ------------------- | ------------------ |
| Accounts | cosmos | cosmospub | `secp256k1` | `20` | `33` |
| Validator Operator | cosmosvaloper | cosmosvaloperpub | `secp256k1` | `20` | `33` |
| Consensus Nodes | cosmosvalcons | cosmosvalconspub | `ed25519` | `20` | `32` |
| Consensus Nodes | cosmosvalcons | cosmosvalconspub | `ed25519` | `20` | `32` |

### PubKeys

`PubKey`s used in the Cosmos SDK follow the `Pubkey` interface defined in tendermint's `crypto` package:
`PubKey`s used in the Cosmos SDK are Protobuf messages and extend the `Pubkey` interface defined in tendermint's `crypto` package:

+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/types/types.go#L8-L13

+++ https://github.com/tendermint/tendermint/blob/01c32c62e8840d812359c9e87e9c575aa67acb09/crypto/crypto.go#L22-L28

+++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/crypto.go#L22-L27
- For `secp256k1` keys, the actual implementation can be found [here](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/secp256k1/secp256k1.go).
- For `ed25519` keys, it can be found [here](https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/crypto/keys/ed25519/ed25519.go).

For `secp256k1` keys, the actual implementation can be found [here](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/secp256k1/secp256k1.go#L140). For `ed25519` keys, it can be found [here](https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/ed25519/ed25519.go#L135).
In both case, the actual key (as raw bytes) is the compressed form of the pubkey. The first byte is a `0x02` byte if the `y`-coordinate is the lexicographically largest of the two associated with the `x`-coordinate. Otherwise the first byte is a `0x03`. This prefix is followed with the `x`-coordinate.

Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw form. Instead, they are double encoded using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`.
Note that in the Cosmos SDK, `Pubkeys` are not manipulated in their raw bytes form. Instead, they are encoded to string using [`Amino`](../core/encoding.md#amino) and [`bech32`](https://en.bitcoin.it/wiki/Bech32). In the SDK, it is done by first calling the `Bytes()` method on the raw `Pubkey` (which applies amino encoding), and then the `ConvertAndEncode` method of `bech32`.

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L579-L729
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L579-L729

### Addresses

The Cosmos SDK comes by default with 3 types of addresses:

- `AccAddress` for accounts.
- `ValAddress` for validator operators.
- `ConsAddress` for validator nodes.
- `ValAddress` for validator operators.
- `ConsAddress` for validator nodes.

Each of these address types are an alias for an hex-encoded `[]byte` array of length 20. Here is the standard way to obtain an address `aa` from a `Pubkey pub`:

Expand All @@ -124,12 +124,12 @@ aa := sdk.AccAddress(pub.Address().Bytes())

These addresses implement the `Address` interface:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L71-L80
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L73-L82

Of note, the `Marhsal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuff compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. Next is an example:
Of note, the `Marshal()` and `Bytes()` method both return the same raw `[]byte` form of the address, the former being needed for Protobuf compatibility. Also, the `String()` method is used to return the `bech32` encoded form of the address, which should be the only address format with which end-user interract. Here is an example:

+++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L229-L243
+++ https://github.com/cosmos/cosmos-sdk/blob/d9175200920e96bfa4182b5c8bc46d91b17a28a1/types/address.go#L232-L246

## Next {hide}

Learn about [gas and fees](./gas-fees.md) {hide}
Learn about [gas and fees](./gas-fees.md) {hide}
Loading