## Description Closes: #9404 --- ### Author Checklist *All items are required. Please add a note to the item if the item is not applicable and please add links to any relevant follow up issues.* I have... - [x] included the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] added `!` to the type prefix if API or client breaking change - [x] targeted the correct branch (see [PR Targeting](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#pr-targeting)) - [x] provided a link to the relevant issue or specification - [ ] followed the guidelines for [building modules](https://github.com/cosmos/cosmos-sdk/blob/master/docs/building-modules) - [ ] included the necessary unit and integration [tests](https://github.com/cosmos/cosmos-sdk/blob/master/CONTRIBUTING.md#testing) - [ ] added a changelog entry to `CHANGELOG.md` - [ ] included comments for [documenting Go code](https://blog.golang.org/godoc) - [ ] updated the relevant documentation or specification - [x] reviewed "Files changed" and left comments if necessary - [x] confirmed all CI checks have passed ### Reviewers Checklist *All items are required. Please add a note if the item is not applicable and please add your handle next to the items reviewed if you only reviewed selected items.* I have... - [ ] confirmed the correct [type prefix](https://github.com/commitizen/conventional-commit-types/blob/v3.0.0/index.json) in the PR title - [ ] confirmed `!` in the type prefix if API or client breaking change - [ ] confirmed all author checklist items have been addressed - [ ] reviewed state machine logic - [ ] reviewed API design and naming - [ ] reviewed documentation is accurate - [ ] reviewed tests and test coverage - [ ] manually tested (if applicable)
11 KiB
Accounts
This document describes the in-built account and public key system of the Cosmos SDK. {synopsis}
Pre-requisite Readings
- Anatomy of a Cosmos SDK Application {prereq}
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 messages to identify the sender of the message. The PrivKey is used to generate digital signatures to prove that an Address associated with the PrivKey approved of a given message.
For HD key derivation the Cosmos SDK uses a standard called BIP32. The BIP32 allows users to create an HD wallet (as specified in BIP44) - a set of accounts derived from an initial secret seed. A seed is usually created from a 12- or 24-word mnemonic. A single seed can derive any number of PrivKeys using a 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
+------------------+ +------------------+ +------------------+
| | | | | |
| Address 0 | | Address 1 | | Address 2 |
| ^ | | ^ | | ^ |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| + | | + | | + |
| Public key 0 | | Public key 1 | | Public key 2 |
| ^ | | ^ | | ^ |
| | | | | | | | |
| | | | | | | | |
| | | | | | | | |
| + | | + | | + |
| Private key 0 | | Private key 1 | | Private key 2 |
| ^ | | ^ | | ^ |
+------------------+ +------------------+ +------------------+
| | |
| | |
| | |
+--------------------------------------------------------------------+
|
|
+---------+---------+
| |
| Master PrivKey |
| |
+-------------------+
|
|
+---------+---------+
| |
| Mnemonic (Seed) |
| |
+-------------------+
In the Cosmos SDK, keys are stored and managed by using an object called a Keyring.
Keys, accounts, addresses, and signatures
The principal way of authenticating a user is done using digital signatures. Users sign transactions using their own private key. Signature verification is done with the associated public key. For on-chain signature verification purposes, we store the public key in an Account object (alongside other data required for a proper transaction validation).
In the node, all data is stored using Protocol Buffers serialization.
The Cosmos SDK supports the following digital key schemes for creating digital signatures:
secp256k1, as implemented in the Cosmos SDK'scrypto/keys/secp256k1package.secp256r1, as implemented in the Cosmos SDK'scrypto/keys/secp256r1package,tm-ed25519, as implemented in the Cosmos SDKcrypto/keys/ed25519package. This scheme is supported only for the consensus validation.
| Address length in bytes | Public key length in bytes | Used for transaction authentication | Used for consensus (tendermint) | |
|---|---|---|---|---|
secp256k1 |
20 | 33 | yes | no |
secp256r1 |
32 | 33 | yes | no |
tm-ed25519 |
-- not used -- | 32 | no | yes |
Addresses
Addresses and PubKeys are both public information that identifies actors in the application. Account is used to store authentication information. The basic account implementation is provided by a BaseAccount object.
Each account is identified using Address which is a sequence of bytes derived from a public key. In the Cosmos SDK, we define 3 types of addresses that specify a context where an account is used:
AccAddressidentifies users (the sender of amessage).ValAddressidentifies validator operators.ConsAddressidentifies validator nodes that are participating in consensus. Validator nodes are derived using theed25519curve.
These types implement the Address interface:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/types/address.go#L71-L90
Address construction algorithm is defined in ADR-28.
Here is the standard way to obtain an account address from a pub public key:
sdk.AccAddress(pub.Address().Bytes())
Of note, the Marshal() and Bytes() method both return the same raw []byte form of the address. Marshal() is required for Protobuf compatibility.
For user interaction, addresses are formatted using Bech32 and implemented by the String method. The Bech32 method is the only supported format to use when interacting with a blockchain. The Bech32 human-readable part (Bech32 prefix) is used to denote an address type. Example:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/types/address.go#L230-L244
| Address Bech32 Prefix | |
|---|---|
| Accounts | cosmos |
| Validator Operator | cosmosvaloper |
| Consensus Nodes | cosmosvalcons |
Public Keys
Public keys in Cosmos SDK are defined by cryptotypes.PubKey interface. Since public keys are saved in a store, cryptotypes.PubKey extends the proto.Message interface:
+++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/crypto/types/types.go#L8-L17
A compressed format is used for secp256k1 and secp256r1 serialization.
- The first byte is a
0x02byte if they-coordinate is the lexicographically largest of the two associated with thex-coordinate. - Otherwise the first byte is a
0x03.
This prefix is followed by the x-coordinate.
Public Keys are not used to reference accounts (or users) and in general are not used when composing transaction messages (with few exceptions: MsgCreateValidator, Validator and Multisig messages).
For user interactions, PubKey is formatted using Protobufs JSON (ProtoMarshalJSON function). Example:
+++ https://github.com/cosmos/cosmos-sdk/blob/7568b66/crypto/keyring/output.go#L23-L39
Keyring
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/v0.42.1/crypto/keyring/keyring.go#L51-L89
The default implementation of Keyring comes from the third-party 99designs/keyring library.
A few notes on the Keyring methods:
-
Sign(uid string, payload []byte) ([]byte, sdkcrypto.PubKey, error)strictly deals with the signature of thepayloadbytes. You must prepare and encode the transaction into a canonical[]byteform. Because protobuf is not deterministic, it has been decided in ADR-020 that the canonicalpayloadto sign is theSignDocstruct, deterministically encoded using ADR-027. Note that signature verification is not implemented in the Cosmos SDK by default, it is deferred to theanteHandler. +++ https://github.com/cosmos/cosmos-sdk/blob/v0.42.1/proto/cosmos/tx/v1beta1/tx.proto#L47-L64 -
NewAccount(uid, mnemonic, bip39Passwd, hdPath string, algo SignatureAlgo) (Info, error)creates a new account based on thebip44 pathand persists it on disk. ThePrivKeyis never stored unencrypted, instead it is encrypted with a passphrase before being persisted. In the context of this method, the key type and sequence number refer to the segment of the BIP44 derivation path (for example,0,1,2, ...) that is used to derive a private and a public key from the mnemonic. Using the same mnemonic and derivation path, the samePrivKey,PubKeyandAddressis generated. The following keys are supported by the keyring: -
secp256k1 -
ed25519 -
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 the private key again into the keyring using theImportPrivKey(uid, armor, passphrase string)function or decrypt it into a raw private key using theUnarmorDecryptPrivKey(armorStr string, passphrase string)function.
Next {hide}
Learn about gas and fees {hide}