github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/docs/basics/accounts.md (about) 1 <!-- 2 order: 3 3 synopsis: This document describes the in-built accounts system of the Cosmos SDK. 4 --> 5 6 # Accounts 7 8 ## Pre-requisite Readings {hide} 9 10 - [Anatomy of an SDK Application](./app-anatomy.md) {prereq} 11 12 ## Account Definition 13 14 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`. 15 16 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. 17 18 ``` 19 Account 0 Account 1 Account 2 20 21 +------------------+ +------------------+ +------------------+ 22 | | | | | | 23 | Address 0 | | Address 1 | | Address 2 | 24 | ^ | | ^ | | ^ | 25 | | | | | | | | | 26 | | | | | | | | | 27 | | | | | | | | | 28 | + | | + | | + | 29 | Public key 0 | | Public key 1 | | Public key 2 | 30 | ^ | | ^ | | ^ | 31 | | | | | | | | | 32 | | | | | | | | | 33 | | | | | | | | | 34 | + | | + | | + | 35 | Private key 0 | | Private key 1 | | Private key 2 | 36 | ^ | | ^ | | ^ | 37 +------------------+ +------------------+ +------------------+ 38 | | | 39 | | | 40 | | | 41 +--------------------------------------------------------------------+ 42 | 43 | 44 +---------+---------+ 45 | | 46 | Master PrivKey | 47 | | 48 +-------------------+ 49 | 50 | 51 +---------+---------+ 52 | | 53 | Mnemonic (Seed) | 54 | | 55 +-------------------+ 56 ``` 57 58 In the Cosmos SDK, accounts are stored and managed via an object called a [`Keybase`](#keybase). 59 60 ## Keybase 61 62 A `Keybase` is an object that stores and manages accounts. In the Cosmos SDK, a `Keybase` implementation follows the `Keybase` interface: 63 64 +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/types.go#L13-L86 65 66 The default implementation of `Keybase` of the Cosmos SDK is `dbKeybase`. 67 68 +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/keybase.go 69 70 A few notes on the `Keybase` methods as implemented in `dbKeybase`: 71 72 - `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). 73 +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/x/auth/types/txbuilder.go#L176-L209 74 - `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**. 75 - `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. 76 77 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`: 78 79 80 +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/crypto/keys/lazy_keybase.go 81 82 `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. 83 84 ## Addresses and PubKeys 85 86 `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: 87 88 - Addresses and Keys for **accounts**, which identify users (e.g. the sender of a `message`). They are derived using the **`secp256k1`** curve. 89 - Addresses and Keys for **validator operators**, which identify the operators of validators. They are derived using the **`secp256k1`** curve. 90 - Addresses and Keys for **consensus nodes**, which identify the validator nodes participating in consensus. They are derived using the **`ed25519`** curve. 91 92 | | Address bech32 Prefix | Pubkey bech32 Prefix | Curve | Address byte length | Pubkey byte length | 93 |--------------------|-----------------------|----------------------|-------------|---------------------|--------------------| 94 | Accounts | cosmos | cosmospub | `secp256k1` | `20` | `33` | 95 | Validator Operator | cosmosvaloper | cosmosvaloperpub | `secp256k1` | `20` | `33` | 96 | Consensus Nodes | cosmosvalcons | cosmosvalconspub | `ed25519` | `20` | `32` | 97 98 ### PubKeys 99 100 `PubKey`s used in the Cosmos SDK follow the `Pubkey` interface defined in tendermint's `crypto` package: 101 102 +++ https://github.com/tendermint/tendermint/blob/bc572217c07b90ad9cee851f193aaa8e9557cbc7/crypto/crypto.go#L22-L27 103 104 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). 105 106 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`. 107 108 +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L579-L729 109 110 ### Addresses 111 112 The Cosmos SDK comes by default with 3 types of addresses: 113 114 - `AccAddress` for accounts. 115 - `ValAddress` for validator operators. 116 - `ConsAddress` for validator nodes. 117 118 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`: 119 120 ```go 121 aa := sdk.AccAddress(pub.Address().Bytes()) 122 ``` 123 124 These addresses implement the `Address` interface: 125 126 +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L71-L80 127 128 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: 129 130 +++ https://github.com/cosmos/cosmos-sdk/blob/7d7821b9af132b0f6131640195326aa02b6751db/types/address.go#L229-L243 131 132 ## Next {hide} 133 134 Learn about [gas and fees](./gas-fees.md) {hide}