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.
The total Supply 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).
The supply functionality introduces a new type of auth.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.Accounts 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:
type ModuleAccount interface { auth.Account // same methods as the Account interface GetName()string // name of the module; used to obtain the address GetPermissions() []string // permissions of module account HasPermission(string)bool}
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 ModuleAccounts in order to be able
to:
Get and set ModuleAccounts by providing the Name.
Send coins from and to other ModuleAccounts or standard Accounts
(BaseAccount or VestingAccount) by passing only the Name.
Mint or Burn coins for a ModuleAccount (restricted to its permissions).
Each ModuleAccount 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.
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 of bank module code to ensure that
permissions are limited in the way that you expect.
The x/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.
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 with WithMintCoinsRestriction to give specific restrictions to mint (e.g. only minting certain denom).
// Keeper defines a module interface that facilitates the transfer of coins// between accounts.type Keeper interface { SendKeeper WithMintCoinsRestriction(MintingRestrictionFn)BaseKeeper InitGenesis(context.Context, *types.GenesisState)ExportGenesis(context.Context) *types.GenesisState GetSupply(ctx context.Context, denom string)sdk.Coin HasSupply(ctx context.Context, denom string)bool GetPaginatedTotalSupply(ctx context.Context, pagination *query.PageRequest) (sdk.Coins, *query.PageResponse, error)IterateTotalSupply(ctx context.Context, cb func(sdk.Coin)bool)GetDenomMetaData(ctx context.Context, denom string) (types.Metadata, bool)HasDenomMetaData(ctx context.Context, denom string)bool SetDenomMetaData(ctx context.Context, denomMetaData types.Metadata)IterateAllDenomMetaData(ctx context.Context, cb func(types.Metadata)bool)SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins)error SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins)error SendCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins)error DelegateCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins)error UndelegateCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins)error MintCoins(ctx context.Context, moduleName string, amt sdk.Coins)error BurnCoins(ctx context.Context, moduleName string, amt sdk.Coins)error DelegateCoins(ctx context.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins)error UndelegateCoins(ctx context.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins)error // GetAuthority gets the address capable of executing governance proposal messages. Usually the gov module account. GetAuthority()string types.QueryServer}
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).
// SendKeeper defines a module interface that facilitates the transfer of coins// between accounts without the possibility of creating coins.type SendKeeper interface { ViewKeeper InputOutputCoins(ctx context.Context, inputs types.Input, outputs []types.Output)error SendCoins(ctx context.Context, fromAddr sdk.AccAddress, toAddr sdk.AccAddress, amt sdk.Coins)error GetParams(ctx context.Context)types.Params SetParams(ctx context.Context, params types.Params)error IsSendEnabledDenom(ctx context.Context, denom string)bool SetSendEnabled(ctx context.Context, denom string, value bool)SetAllSendEnabled(ctx context.Context, sendEnableds []*types.SendEnabled)DeleteSendEnabled(ctx context.Context, denom string)IterateSendEnabledEntries(ctx context.Context, cb func(denom string, sendEnabled bool) (stop bool))GetAllSendEnabledEntries(ctx context.Context) []types.SendEnabled IsSendEnabledCoin(ctx context.Context, coin sdk.Coin)bool IsSendEnabledCoins(ctx context.Context, coins ...sdk.Coin)error BlockedAddr(addr sdk.AccAddress)bool}
The view keeper provides read-only access to account balances. The view keeper does not have balance alteration functionality. All balance lookups are O(1).
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.
The bank module params can be updated through MsgUpdateParams, which can be done using governance proposal. The signer will always be the gov module account address.
The default send enabled value controls send transfer capability for all
coin denominations unless specifically included in the array of SendEnabled
parameters.
The denom-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.
The total 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.
simd query bank total [flags]
Example:
simd query bank total --denom stake
Example Output:
amount: "10000000000"denom: stake
send-enabled
The send-enabled command allows users to query for all or some SendEnabled entries.
The SendEnabled enpoints allows users to query the SendEnabled entries of the bank module.Any denominations NOT returned, use the Params.DefaultSendEnabled value.