This document describes the in-built account and public key system of the Cosmos SDK.
# Pre-requisite Readings
# Account Definition
In the Cosmos SDK, an account designates a pair of public key
PubKey and private key
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
PrivKey is used to generate digital signatures to prove that an
Address associated with the
PrivKey approved of a given
For HD key derivation the Cosmos SDK uses a standard called BIP32 (opens new window). The BIP32 allows users to create an HD wallet (as specified in BIP44 (opens new window)) - 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.
In the Cosmos SDK, keys are stored and managed by using an object called a
# Keys, accounts, addresses, and signatures
The principal way of authenticating a user is done using digital signatures (opens new window). 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 SDK's
crypto/keys/secp256k1package (opens new window).
secp256r1, as implemented in the SDK's
crypto/keys/secp256r1package (opens new window),
tm-ed25519, as implemented in the SDK
crypto/keys/ed25519package (opens new window). This scheme is supported only for the consensus validation.
| | Address length | Public key length | Used for transaction | Used for consensus |
| | in bytes | in bytes | authentication | (tendermint) |
secp256k1 | 20 | 33 | yes | no |
secp256r1 | 32 | 33 | yes | no |
tm-ed25519 | -- not used -- | 32 | no | yes |
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
Each account is identified using
Address which is a sequence of bytes derived from a public key. In SDK, we define 3 types of addresses that specify a context where an account is used:
AccAddressidentifies users (the sender of a
ValAddressidentifies validator operators.
ConsAddressidentifies validator nodes that are participating in consensus. Validator nodes are derived using the
These types implement the
Address construction algorithm is defined in ADR-28 (opens new window).
Here is the standard way to obtain an account address from a
pub public key:
Of note, the
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 (opens new window) 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:
|Address Bech32 Prefix|
# 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
A compressed format is used for
- The first byte is a
0x02byte if the
y-coordinate is the lexicographically largest of the two associated with the
- Otherwise the first byte is a
This prefix is followed by the
Public Keys are not used to reference accounts (or users) and in general are not used when composing transaction messages (with few exceptions:
For user interactions,
PubKey is formatted using Protobufs JSON (ProtoMarshalJSON (opens new window) function). Example:
Keyring is an object that stores and manages accounts. In the Cosmos SDK, a
Keyring implementation follows the
The default implementation of
Keyring comes from the third-party
99designs/keyring (opens new window) library.
A few notes on the
Sign(uid string, payload byte) (byte, sdkcrypto.PubKey, error)strictly deals with the signature of the
payloadbytes. 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 canonical
payloadto sign is the
SignDocstruct, deterministically encoded using ADR-027. Note that signature verification is not implemented in the SDK by default, it is deferred to the
NewAccount(uid, mnemonic, bip39Passwd, hdPath string, algo SignatureAlgo) (Info, error)creates a new account based on the
bip44 path(opens new window) and persists it on disk. The
PrivKeyis never stored unencrypted, instead it is encrypted with a passphrase (opens new window) 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,
2, ...) that is used to derive a private and a public key from the mnemonic. Using the same mnemonic and derivation path, the same
Addressis generated. The following keys are supported by the keyring:
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 the
ImportPrivKey(uid, armor, passphrase string)function or decrypt it into a raw private key using the
UnarmorDecryptPrivKey(armorStr string, passphrase string)function.
Learn about gas and fees