Abstract
This document specifies the bank module of the Cosmos SDK. The bank module is responsible for handling multi-asset coin transfers between accounts and tracking special-case pseudo-transfers which must work differently with particular kinds of accounts (notably delegating/undelegating for vesting accounts). It exposes several interfaces with varying capabilities for secure interaction with other modules which must alter user balances. In addition, the bank module tracks and provides query support for the total supply of all assets used in the application. This module is used in the Cosmos Hub.Contents
Supply
Thesupply
functionality:
- passively tracks the total supply of coins within a chain,
- provides a pattern for modules to hold/interact with
Coins
, and - introduces the invariant check to verify a chain’s total supply.
Total Supply
The totalSupply
of the network is equal to the sum of all coins from the account. The total supply is updated every time a Coin
is minted (eg: as part of the inflation mechanism) or burned (eg: due to slashing or if a governance proposal is vetoed).
Module Accounts
The supply functionality introduces a new type ofauth.Account
which can be used by modules to allocate tokens and in special cases mint or burn tokens. At a base level these module accounts are capable of sending/receiving tokens to and from auth.Account
s and other module accounts. This design replaces previous alternative designs where, to hold tokens, modules would burn the incoming tokens from the sender account, and then track those tokens internally. Later, in order to send tokens, the module would need to effectively mint tokens within a destination account. The new design removes duplicate logic between modules to perform this accounting.
The ModuleAccount
interface is defined as follows:
WARNING! Any module or message handler that allows either direct or indirect sending of funds must explicitly guarantee those funds cannot be sent to module accounts (unless allowed).The supply
Keeper
also introduces new wrapper functions for the auth Keeper
and the bank Keeper
that are related to ModuleAccount
s in order to be able to:
- Get and set
ModuleAccount
s by providing theName
. - Send coins from and to other
ModuleAccount
s or standardAccount
s (BaseAccount
orVestingAccount
) by passing only theName
. Mint
orBurn
coins for aModuleAccount
(restricted to its permissions).
Permissions
EachModuleAccount
has a different set of permissions that provide different object capabilities to perform certain actions. Permissions need to be registered upon the creation of the supply Keeper
so that every time a ModuleAccount
calls the allowed functions, the Keeper
can lookup the permissions to that specific account and perform or not perform the action.
The available permissions are:
Minter
: allows for a module to mint a specific amount of coins.Burner
: allows for a module to burn a specific amount of coins.Staking
: allows for a module to delegate and undelegate a specific amount of coins.
State
Thex/bank
module keeps state of the following primary objects:
- Account balances
- Denomination metadata
- The total supply of all balances
- Information on which denominations are allowed to be sent.
x/bank
module keeps the following indexes to manage the aforementioned state:
- Supply Index:
0x0 | byte(denom) -> byte(amount)
- Denom Metadata Index:
0x1 | byte(denom) -> ProtocolBuffer(Metadata)
- Balances Index:
0x2 | byte(address length) | []byte(address) | []byte(balance.Denom) -> ProtocolBuffer(balance)
- Reverse Denomination to Address Index:
0x03 | byte(denom) | 0x00 | []byte(address) -> 0
Params
The bank module stores it’s params in state with the prefix of0x05
, it can be updated with governance or the address with authority.
- Params:
0x05 | ProtocolBuffer(Params)
Keepers
The bank module provides these exported keeper interfaces that can be passed to other modules that read or update account balances. Modules should use the least-permissive interface that provides the functionality they require. Best practices dictate careful review ofbank
module code to ensure that permissions are limited in the way that you expect.
Denied Addresses
Thex/bank
module accepts a map of addresses that are considered blocklisted from directly and explicitly receiving funds through means such as MsgSend
and MsgMultiSend
and direct API calls like SendCoinsFromModuleToAccount
.
Typically, these addresses are module accounts. If these addresses receive funds outside the expected rules of the state machine, invariants are likely to be broken and could result in a halted network.
By providing the x/bank
module with a blocklisted set of addresses, an error occurs for the operation if a user or client attempts to directly or indirectly send funds to a blocklisted account, for example, by using IBC.
Common Types
Input
An input of a multiparty transferOutput
An output of a multiparty transfer.BaseKeeper
The base keeper provides full-permission access: the ability to arbitrary modify any account’s balance and mint or burn coins. Restricted permission to mint per module could be achieved by using baseKeeper withWithMintCoinsRestriction
to give specific restrictions to mint (e.g. only minting certain denom).
SendKeeper
The send keeper provides access to account balances and the ability to transfer coins between accounts. The send keeper does not alter the total supply (mint or burn coins).ViewKeeper
The view keeper provides read-only access to account balances. The view keeper does not have balance alteration functionality. All balance lookups areO(1)
.
Messages
MsgSend
Send coins from one address to another. proto/cosmos/bank/v1beta1/tx.proto- The coins do not have sending enabled
- The
to
address is restricted
MsgMultiSend
Send coins from one sender and to a series of different address. If any of the receiving addresses do not correspond to an existing account, a new account is created. proto/cosmos/bank/v1beta1/tx.proto- Any of the coins do not have sending enabled
- Any of the
to
addresses are restricted - Any of the coins are locked
- The inputs and outputs do not correctly correspond to one another
MsgUpdateParams
Thebank
module params can be updated through MsgUpdateParams
, which can be done using governance proposal. The signer will always be the gov
module account address.
proto/cosmos/bank/v1beta1/tx.proto
- signer is not the gov module account address.
MsgSetSendEnabled
Used with the x/gov module to set create/edit SendEnabled entries. proto/cosmos/bank/v1beta1/tx.proto- The authority is not a bech32 address.
- The authority is not x/gov module’s address.
- There are multiple SendEnabled entries with the same Denom.
- One or more SendEnabled entries has an invalid Denom.
Events
The bank module emits the following events:Message Events
MsgSend
Type | Attribute Key | Attribute Value |
---|---|---|
transfer | recipient | {recipientAddress} |
transfer | amount | {amount} |
message | module | bank |
message | action | send |
message | sender | {senderAddress} |
MsgMultiSend
Type | Attribute Key | Attribute Value |
---|---|---|
transfer | recipient | {recipientAddress} |
transfer | amount | {amount} |
message | module | bank |
message | action | multisend |
message | sender | {senderAddress} |
Keeper Events
In addition to message events, the bank keeper will produce events when the following methods are called (or any method which ends up calling them)MintCoins
BurnCoins
addCoins
subUnlockedCoins/DelegateCoins
Parameters
The bank module contains the following parametersSendEnabled
The SendEnabled parameter is now deprecated and not to be use. It is replaced with state store records.DefaultSendEnabled
The default send enabled value controls send transfer capability for all coin denominations unless specifically included in the array ofSendEnabled
parameters.
Client
CLI
A user can query and interact with thebank
module using the CLI.
Query
Thequery
commands allow users to query bank
state.
balances
Thebalances
command allows users to query account balances by address.
denom-metadata
Thedenom-metadata
command allows users to query metadata for coin denominations. A user can query metadata for a single denomination using the --denom
flag or all denominations without it.
total
Thetotal
command allows users to query the total supply of coins. A user can query the total supply for a single coin using the --denom
flag or all coins without it.
send-enabled
Thesend-enabled
command allows users to query for all or some SendEnabled entries.
Transactions
Thetx
commands allow users to interact with the bank
module.
send
Thesend
command allows users to send funds from one account to another.
gRPC
A user can query thebank
module using gRPC endpoints.
Balance
TheBalance
endpoint allows users to query account balance by address for a given denomination.
AllBalances
TheAllBalances
endpoint allows users to query account balance by address for all denominations.
DenomMetadata
TheDenomMetadata
endpoint allows users to query metadata for a single coin denomination.
DenomsMetadata
TheDenomsMetadata
endpoint allows users to query metadata for all coin denominations.
DenomOwners
TheDenomOwners
endpoint allows users to query metadata for a single coin denomination.
TotalSupply
TheTotalSupply
endpoint allows users to query the total supply of all coins.
SupplyOf
TheSupplyOf
endpoint allows users to query the total supply of a single coin.
Params
TheParams
endpoint allows users to query the parameters of the bank
module.
SendEnabled
TheSendEnabled
enpoints allows users to query the SendEnabled entries of the bank
module.
Any denominations NOT returned, use the Params.DefaultSendEnabled
value.