{"content":{"title":"COSMOSSDK BANK模块中文文档","body":"---\r\nsidebar_position: 1\r\n---\r\n\r\n# `x/bank`\r\n\r\n## 摘要\r\n\r\n本文档对Cosmos SDK的bank模块进行说明。\r\n\r\nbank模块负责账户间的各种代币资产转账以及追踪特殊情况下必须以不同方式工作的特殊账号的伪转账（特别是vesting账户的代理/取消代理）。此模块暴露了几个不同权限的接口用于安全地与其他模块进行那些必须改变用户余额的交互。\r\n\r\n另外，银行模块追踪并可以查询所有资产的总供应量。\r\n\r\n此模块也被应用于Cosmos Hub中。\r\n\r\n## 内容\r\n\r\n* [代币供应](#supply)\r\n    * [总供应量](#total-supply)\r\n* [Module Accounts](#module-accounts)\r\n    * [Permissions](#permissions)\r\n* [State](#state)\r\n* [Params](#params)\r\n* [Keepers](#keepers)\r\n* [Messages](#messages)\r\n* [Events](#events)\r\n    * [Message Events](#message-events)\r\n    * [Keeper Events](#keeper-events)\r\n* [Parameters](#parameters)\r\n    * [SendEnabled](#sendenabled)\r\n    * [DefaultSendEnabled](#defaultsendenabled)\r\n* [Client](#client)\r\n    * [CLI](#cli)\r\n    * [Query](#query)\r\n    * [Transactions](#transactions)\r\n* [gRPC](#grpc)\r\n\r\n## 代币供应\r\n\r\n代币供应`supply`功能：\r\n\r\n* 被动追踪链上所有代币的总供应量，\r\n* 为所有模块提供了持有/操作代币的模式，并且\r\n* 引入了不变量检查来验证链上的代币总供应量。\r\n\r\n### 总供应量\r\n\r\n网络的总供应量等于账户的所有代币总和。总供应量会随着代币`Coin`的铸造（比如使用铸造从技术上实现通胀）和燃烧（由于被惩罚或者治理模块被废弃时造成的燃烧）实时更新。\r\n\r\n## 模块账户\r\n\r\n代币供应功能性地引入了一个新的类型`auth.Account`，被模块用来分配代币以及特殊应用场景下铸造或燃烧代币。这些模块账户能够彼此发送和接收代币。这个设计取代了之前的设计——模块需要接收代币时，需要将发送者的代币燃烧掉，需要发送代币时，再在目标账户内铸造出新的代币。这个新设计移除了模块间的重复逻辑。\r\n\r\n模块账户`ModuleAccount`接口定义如下：\r\n\r\n```go\r\ntype ModuleAccount interface {\r\n  auth.Account               // same methods as the Account interface\r\n\r\n  GetName() string           // name of the module; used to obtain the address\r\n  GetPermissions() []string  // permissions of module account\r\n  HasPermission(string) bool\r\n}\r\n```\r\n\r\n> **注意!**\r\n> 任何允许直接或间接发送资金的模块或者消息处理函数必须确保这些资金不能发送到模块账户（除非是有意为之）\r\n\r\n为了以下目的，代币供应的`Keeper`也为auth模块的`Keeper`和bank模块的`Keeper`引入了和模块账户`ModuleAccount`有关的新的包装函数：\r\n\r\n* 根据提供的`Name`获取或设置模块账户`ModuleAccount`.\r\n* 只通过`Name`就可以接收和发送代币到别的模块账户`ModuleAccount`或者标准账户`Account`（`BaseAccount`或者`VestingAccount`）\r\n* 为模块账户`ModuleAccount`铸造`Mint`或烧毁`Burn`代币（受权限限制）。\r\n\r\n### 权限\r\n\r\n每个模块账户`ModuleAccount`都有一套不同的权限来提供不同的能力去执行特定的动作。权限需要在创建代币供应`Keeper`时注册以便每次`ModuleAccount`调用授权函数时查询，`Keeper`能查够查询具体账户的权限来决定是否执行该动作。\r\n\r\n可用的权限有以下三个：\r\n\r\n* `Minter`：允许模块铸造具体数量的代币。\r\n* `Burner`: 允许模块烧毁具体数量的代币。\r\n* `Staking`: 允许模块代理或取消代理具体数量的代币。\r\n\r\n## 状态\r\n\r\n`x/bank`模块主要拥有以下几个对象的状态：\r\n\r\n1. 账户余额\r\n2. 代币的元信息\r\n3. 代币的总供应量\r\n4. 代币转账信息\r\n\r\n另外，`x/bank`模块拥有下列索引用来管理上述状态：\r\n\r\n* 代币供应索引: `0x0 | byte(denom) -> byte(amount)`\r\n* 代币元数据索引：`0x1 | byte(denom) -> ProtocolBuffer(Metadata)`\r\n* 余额索引：`0x2 | byte(address length) | []byte(address) | []byte(balance.Denom) -> ProtocolBuffer(balance)`\r\n* 代币->账户地址索引：`0x03 | byte(denom) | 0x00 | []byte(address) -> 0`\r\n\r\n## 参数\r\n\r\n银行模块以`0x05`为前缀把自己的参数存储在状态中，通过治理模块或者权威账户地址可以更改这些参数。\r\n\r\n* 参数：`0x05 | ProtocolBuffer(Params)`\r\n\r\n```protobuf reference\r\nhttps://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/bank.proto#L12-L23\r\n```\r\n\r\n## Keepers\r\n\r\n银行模块提供暴露了有一些keeper接口，可以传递给其他模块以便读取或者更改账户的余额。\r\n其他模块应当按需引入这些接口，避免滥用。\r\n\r\n\r\n在实际生产中需要仔细阅读`bank`模块的代码以确保权限限制规则是符合你预期的。\r\n\r\n\r\n\r\n### 禁用账户地址\r\n\r\n`x/bank`模块可以接受一个账户地址的字典作为黑名单，可以禁止这些账户地址通过`MsgSend`，`MsgMultiSend`以及像`SendCoinsFromModuleToAccount`直接调用的api来接收代币。\r\n\r\n典型的，这些地址为模块账户地址。如果这些地址以状态机规则以外的方式接接收资金，不变量可能会受到破坏，这将可能导致网络宕机。\r\n\r\n`x/bank`提供了一个地址的黑名单，如果向黑名单内的地址发送资金会发生错误，例如，使用[IBC](https://ibc.cosmos.network).\r\n\r\n### 通用类型\r\n\r\n#### Input\r\n\r\n多方转账交易的输入。\r\n\r\n```protobuf\r\n// Input models transaction input.\r\nmessage Input {\r\n  string   address                        = 1;\r\n  repeated cosmos.base.v1beta1.Coin coins = 2;\r\n}\r\n```\r\n\r\n#### Output\r\n\r\n多方转账交易的输出。\r\n\r\n```protobuf\r\n// Output models transaction outputs.\r\nmessage Output {\r\n  string   address                        = 1;\r\n  repeated cosmos.base.v1beta1.Coin coins = 2;\r\n}\r\n```\r\n\r\n### BaseKeeper\r\n\r\n基础keeper提供了所有的权限，可以任意更改账户的余额，铸造代币或是销毁代币。\r\n\r\n要限制每个模块铸造代币的权限，可以通过baseKeeper的`WithMintCoinsRestriction` 来给予具体的铸造限制（例如：只能铸造特定的代币）。\r\n\r\n```go\r\n// Keeper defines a module interface that facilitates the transfer of coins\r\n// between accounts.\r\ntype Keeper interface {\r\n    SendKeeper\r\n    WithMintCoinsRestriction(MintingRestrictionFn) BaseKeeper\r\n\r\n    InitGenesis(context.Context, *types.GenesisState)\r\n    ExportGenesis(context.Context) *types.GenesisState\r\n\r\n    GetSupply(ctx context.Context, denom string) sdk.Coin\r\n    HasSupply(ctx context.Context, denom string) bool\r\n    GetPaginatedTotalSupply(ctx context.Context, pagination *query.PageRequest) (sdk.Coins, *query.PageResponse, error)\r\n    IterateTotalSupply(ctx context.Context, cb func(sdk.Coin) bool)\r\n    GetDenomMetaData(ctx context.Context, denom string) (types.Metadata, bool)\r\n    HasDenomMetaData(ctx context.Context, denom string) bool\r\n    SetDenomMetaData(ctx context.Context, denomMetaData types.Metadata)\r\n    IterateAllDenomMetaData(ctx context.Context, cb func(types.Metadata) bool)\r\n\r\n    SendCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error\r\n    SendCoinsFromModuleToModule(ctx context.Context, senderModule, recipientModule string, amt sdk.Coins) error\r\n    SendCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error\r\n    DelegateCoinsFromAccountToModule(ctx context.Context, senderAddr sdk.AccAddress, recipientModule string, amt sdk.Coins) error\r\n    UndelegateCoinsFromModuleToAccount(ctx context.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins) error\r\n    MintCoins(ctx context.Context, moduleName string, amt sdk.Coins) error\r\n    BurnCoins(ctx context.Context, moduleName string, amt sdk.Coins) error\r\n\r\n    DelegateCoins(ctx context.Context, delegatorAddr, moduleAccAddr sdk.AccAddress, amt sdk.Coins) error\r\n    UndelegateCoins(ctx context.Context, moduleAccAddr, delegatorAddr sdk.AccAddress, amt sdk.Coins) error\r\n\r\n    // GetAuthority gets the address capable of executing governance proposal messages. Usually the gov module account.\r\n    GetAuthority() string\r\n\r\n    types.QueryServer\r\n}\r\n```\r\n\r\n### SendKeeper\r\n\r\nsend keeper提供了访问账户并在账户间转账的权限。send keeper不会改变代币的总供应量（不涉及铸造或销毁代币）。\r\n\r\n```go\r\n// SendKeeper defines a module interface that facilitates the transfer of coins\r\n// between accounts without the possibility of creating coins.\r\ntype SendKeeper interface {\r\n    ViewKeeper\r\n\r\n    AppendSendRestriction(restriction SendRestrictionFn)\r\n    PrependSendRestriction(restriction SendRestrictionFn)\r\n    ClearSendRestriction()\r\n\r\n    InputOutputCoins(ctx context.Context, input types.Input, outputs []types.Output) error\r\n    SendCoins(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error\r\n\r\n    GetParams(ctx context.Context) types.Params\r\n    SetParams(ctx context.Context, params types.Params) error\r\n\r\n    IsSendEnabledDenom(ctx context.Context, denom string) bool\r\n    SetSendEnabled(ctx context.Context, denom string, value bool)\r\n    SetAllSendEnabled(ctx context.Context, sendEnableds []*types.SendEnabled)\r\n    DeleteSendEnabled(ctx context.Context, denom string)\r\n    IterateSendEnabledEntries(ctx context.Context, cb func(denom string, sendEnabled bool) (stop bool))\r\n    GetAllSendEnabledEntries(ctx context.Context) []types.SendEnabled\r\n\r\n    IsSendEnabledCoin(ctx context.Context, coin sdk.Coin) bool\r\n    IsSendEnabledCoins(ctx context.Context, coins ...sdk.Coin) error\r\n\r\n    BlockedAddr(addr sdk.AccAddress) bool\r\n}\r\n```\r\n\r\n#### Send Restrictions\r\n\r\n`SendKeeper`在转账前会执行`SendRestrictionFn`函数。\r\n\r\n```golang\r\n// 一个SendRestrictionFn可以限制和/或提供一个新的接收地址。\r\ntype SendRestrictionFn func(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) (newToAddr sdk.AccAddress, err error)\r\n```\r\n\r\n在`SendKeeper`（或`BaseKeeper`）创建之后，可以通过`AppendSendRestriction`或者`PrependSendRestriction`函数来添加转账限制。\r\n两个函数和之前已提供的限制共同组成了转账限制。`AppendSendRestriction`添加的限制条件会在之前的条件执行后再执行。\r\n`PrependSendRestriction`添加的条件会在之前的条件执行前先执行。这些限制条件在发生错误时会依照短路逻辑处理，例如如果第一个条件返回了一个错误，则第二个条件不会执行。\r\n\r\n在`SendCoins`期间，限制条件会在代币从转账账户扣除以及添加到被转账账户之前执行。\r\n在`InputOutputCoins`期间，限制条件会在代币从转账账户扣除以及添加到被转账账户之后执行。\r\n\r\nA send restriction function should make use of a custom value in the context to allow bypassing that specific restriction.\r\n一个转账限制函数\r\n\r\nSend Restrictions are not placed on `ModuleToAccount` or `ModuleToModule` transfers. This is done due to modules needing to move funds to user accounts and other module accounts. This is a design decision to allow for more flexibility in the state machine. The state machine should be able to move funds between module accounts and user accounts without restrictions.\r\n\r\nSecondly this limitation would limit the usage of the state machine even for itself. users would not be able to receive rewards, not be able to move funds between module accounts. In the case that a user sends funds from a user account to the community pool and then a governance proposal is used to get those tokens into the users account this would fall under the discretion of the app chain developer to what they would like to do here. We can not make strong assumptions here.\r\nThirdly, this issue could lead into a chain halt if a token is disabled and the token is moved in the begin/endblock. This is the last reason we see the current change and more damaging then beneficial for users.\r\n\r\nFor example, in your module's keeper package, you'd define the send restriction function:\r\n\r\n```golang\r\nvar _ banktypes.SendRestrictionFn = Keeper{}.SendRestrictionFn\r\n\r\nfunc (k Keeper) SendRestrictionFn(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) (sdk.AccAddress, error) {\r\n\t// Bypass if the context says to.\r\n\tif mymodule.HasBypass(ctx) {\r\n\t\treturn toAddr, nil\r\n\t}\r\n\r\n\t// Your custom send restriction logic goes here.\r\n\treturn nil, errors.New(\"not implemented\")\r\n}\r\n```\r\n\r\nThe bank keeper should be provided to your keeper's constructor so the send restriction can be added to it:\r\n\r\n```golang\r\nfunc NewKeeper(cdc codec.BinaryCodec, storeKey storetypes.StoreKey, bankKeeper mymodule.BankKeeper) Keeper {\r\n\trv := Keeper{/*...*/}\r\n\tbankKeeper.AppendSendRestriction(rv.SendRestrictionFn)\r\n\treturn rv\r\n}\r\n```\r\n\r\nThen, in the `mymodule` package, define the context helpers:\r\n\r\n```golang\r\nconst bypassKey = \"bypass-mymodule-restriction\"\r\n\r\n// WithBypass returns a new context that will cause the mymodule bank send restriction to be skipped.\r\nfunc WithBypass(ctx context.Context) context.Context {\r\n\treturn sdk.UnwrapSDKContext(ctx).WithValue(bypassKey, true)\r\n}\r\n\r\n// WithoutBypass returns a new context that will cause the mymodule bank send restriction to not be skipped.\r\nfunc WithoutBypass(ctx context.Context) context.Context {\r\n\treturn sdk.UnwrapSDKContext(ctx).WithValue(bypassKey, false)\r\n}\r\n\r\n// HasBypass checks the context to see if the mymodule bank send restriction should be skipped.\r\nfunc HasBypass(ctx context.Context) bool {\r\n\tbypassValue := ctx.Value(bypassKey)\r\n\tif bypassValue == nil {\r\n\t\treturn false\r\n\t}\r\n\tbypass, isBool := bypassValue.(bool)\r\n\treturn isBool && bypass\r\n}\r\n```\r\n\r\nNow, anywhere where you want to use `SendCoins` or `InputOutputCoins`, but you don't want your send restriction applied:\r\n\r\n```golang\r\nfunc (k Keeper) DoThing(ctx context.Context, fromAddr, toAddr sdk.AccAddress, amt sdk.Coins) error {\r\n\treturn k.bankKeeper.SendCoins(mymodule.WithBypass(ctx), fromAddr, toAddr, amt)\r\n}\r\n```\r\n\r\n### ViewKeeper\r\n\r\nThe view keeper provides read-only access to account balances. The view keeper does not have balance alteration functionality. All balance lookups are `O(1)`.\r\n\r\n```go\r\n// ViewKeeper defines a module interface that facilitates read only access to\r\n// account balances.\r\ntype ViewKeeper interface {\r\n    ValidateBalance(ctx context.Context, addr sdk.AccAddress) error\r\n    HasBalance(ctx context.Context, addr sdk.AccAddress, amt sdk.Coin) bool\r\n\r\n    GetAllBalances(ctx context.Context, addr sdk.AccAddress) sdk.Coins\r\n    GetAccountsBalances(ctx context.Context) []types.Balance\r\n    GetBalance(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin\r\n    LockedCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins\r\n    SpendableCoins(ctx context.Context, addr sdk.AccAddress) sdk.Coins\r\n    SpendableCoin(ctx context.Context, addr sdk.AccAddress, denom string) sdk.Coin\r\n\r\n    IterateAccountBalances(ctx context.Context, addr sdk.AccAddress, cb func(coin sdk.Coin) (stop bool))\r\n    IterateAllBalances(ctx context.Context, cb func(address sdk.AccAddress, coin sdk.Coin) (stop bool))\r\n}\r\n```\r\n\r\n## Messages\r\n\r\n### MsgSend\r\n\r\nSend coins from one address to another.\r\n\r\n```protobuf reference\r\nhttps://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L38-L53\r\n```\r\n\r\nThe message will fail under the following conditions:\r\n\r\n* The coins do not have sending enabled\r\n* The `to` address is restricted\r\n\r\n### MsgMultiSend\r\n\r\nSend 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.\r\n\r\n```protobuf reference\r\nhttps://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L58-L69\r\n```\r\n\r\nThe message will fail under the following conditions:\r\n\r\n* Any of the coins do not have sending enabled\r\n* Any of the `to` addresses are restricted\r\n* Any of the coins are locked\r\n* The inputs and outputs do not correctly correspond to one another\r\n\r\n### MsgUpdateParams\r\n\r\nThe `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. \r\n\r\n```protobuf reference\r\nhttps://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L74-L88\r\n```\r\n\r\nThe message handling can fail if:\r\n\r\n* signer is not the gov module account address.\r\n\r\n### MsgSetSendEnabled\r\n\r\nUsed with the x/gov module to set create/edit SendEnabled entries.\r\n\r\n```protobuf reference\r\nhttps://github.com/cosmos/cosmos-sdk/blob/v0.47.0-rc1/proto/cosmos/bank/v1beta1/tx.proto#L96-L117\r\n```\r\n\r\nThe message will fail under the following conditions:\r\n\r\n* The authority is not a decodable address.\r\n* The authority is not x/gov module's address.\r\n* There are multiple SendEnabled entries with the same Denom.\r\n* One or more SendEnabled entries has an invalid Denom.\r\n\r\n### MsgBurn \r\n\r\nUsed to burn coins from an account. The coins are removed from the account and the total supply is reduced.\r\n\r\n```protobuf reference\r\nhttps://github.com/cosmos/cosmos-sdk/blob/1af000b3ef6296f9928caf494fe5bb812990f22d/proto/cosmos/bank/v1beta1/tx.proto#L131-L148\r\n```\r\n\r\nThis message will fail under the following conditions:\r\n\r\n* The signer is not present\r\n* The coins are not spendable\r\n* The coins are not positive\r\n* The coins are not valid\r\n\r\n## Events\r\n\r\nThe bank module emits the following events:\r\n\r\n### Message Events\r\n\r\n#### MsgSend\r\n\r\n| Type     | Attribute Key | Attribute Value    |\r\n| -------- | ------------- | ------------------ |\r\n| transfer | recipient     | {recipientAddress} |\r\n| transfer | amount        | {amount}           |\r\n| message  | module        | bank               |\r\n| message  | action        | send               |\r\n| message  | sender        | {senderAddress}    |\r\n\r\n#### MsgMultiSend\r\n\r\n| Type     | Attribute Key | Attribute Value    |\r\n| -------- | ------------- | ------------------ |\r\n| transfer | recipient     | {recipientAddress} |\r\n| transfer | amount        | {amount}           |\r\n| message  | module        | bank               |\r\n| message  | action        | multisend          |\r\n| message  | sender        | {senderAddress}    |\r\n\r\n### Keeper Events\r\n\r\nIn addition to message events, the bank keeper will produce events when the following methods are called (or any method which ends up calling them)\r\n\r\n#### MintCoins\r\n\r\n```json\r\n{\r\n  \"type\": \"coinbase\",\r\n  \"attributes\": [\r\n    {\r\n      \"key\": \"minter\",\r\n      \"value\": \"{{sdk.AccAddress of the module minting coins}}\",\r\n      \"index\": true\r\n    },\r\n    {\r\n      \"key\": \"amount\",\r\n      \"value\": \"{{sdk.Coins being minted}}\",\r\n      \"index\": true\r\n    }\r\n  ]\r\n}\r\n```\r\n\r\n```json\r\n{\r\n  \"type\": \"coin_received\",\r\n  \"attributes\": [\r\n    {\r\n      \"key\": \"receiver\",\r\n      \"value\": \"{{sdk.AccAddress of the module minting coins}}\",\r\n      \"index\": true\r\n    },\r\n    {\r\n      \"key\": \"amount\",\r\n      \"value\": \"{{sdk.Coins being received}}\",\r\n      \"index\": true\r\n    }\r\n  ]\r\n}\r\n```\r\n\r\n#### BurnCoins\r\n\r\n```json\r\n{\r\n  \"type\": \"burn\",\r\n  \"attributes\": [\r\n    {\r\n      \"key\": \"burner\",\r\n      \"value\": \"{{sdk.AccAddress of the module burning coins}}\",\r\n      \"index\": true\r\n    },\r\n    {\r\n      \"key\": \"amount\",\r\n      \"value\": \"{{sdk.Coins being burned}}\",\r\n      \"index\": true\r\n    }\r\n  ]\r\n}\r\n```\r\n\r\n```json\r\n{\r\n  \"type\": \"coin_spent\",\r\n  \"attributes\": [\r\n    {\r\n      \"key\": \"spender\",\r\n      \"value\": \"{{sdk.AccAddress of the module burning coins}}\",\r\n      \"index\": true\r\n    },\r\n    {\r\n      \"key\": \"amount\",\r\n      \"value\": \"{{sdk.Coins being burned}}\",\r\n      \"index\": true\r\n    }\r\n  ]\r\n}\r\n```\r\n\r\n#### addCoins\r\n\r\n```json\r\n{\r\n  \"type\": \"coin_received\",\r\n  \"attributes\": [\r\n    {\r\n      \"key\": \"receiver\",\r\n      \"value\": \"{{sdk.AccAddress of the address beneficiary of the coins}}\",\r\n      \"index\": true\r\n    },\r\n    {\r\n      \"key\": \"amount\",\r\n      \"value\": \"{{sdk.Coins being received}}\",\r\n      \"index\": true\r\n    }\r\n  ]\r\n}\r\n```\r\n\r\n#### subUnlockedCoins/DelegateCoins\r\n\r\n```json\r\n{\r\n  \"type\": \"coin_spent\",\r\n  \"attributes\": [\r\n    {\r\n      \"key\": \"spender\",\r\n      \"value\": \"{{sdk.AccAddress of the address which is spending coins}}\",\r\n      \"index\": true\r\n    },\r\n    {\r\n      \"key\": \"amount\",\r\n      \"value\": \"{{sdk.Coins being spent}}\",\r\n      \"index\": true\r\n    }\r\n  ]\r\n}\r\n```\r\n\r\n## Parameters\r\n\r\nThe bank module contains the following parameters\r\n\r\n### SendEnabled\r\n\r\nThe SendEnabled parameter is now deprecated and not to be use. It is replaced\r\nwith state store records.\r\n\r\n\r\n### DefaultSendEnabled\r\n\r\nThe default send enabled value controls send transfer capability for all\r\ncoin denominations unless specifically included in the array of `SendEnabled`\r\nparameters.\r\n\r\n## Client\r\n\r\n### CLI\r\n\r\nA user can query and interact with the `bank` module using the CLI.\r\n\r\n#### Query\r\n\r\nThe `query` commands allow users to query `bank` state.\r\n\r\n```shell\r\nsimd query bank --help\r\n```\r\n\r\n##### balances\r\n\r\nThe `balances` command allows users to query account balances by address.\r\n\r\n```shell\r\nsimd query bank balances [address] [flags]\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\nsimd query bank balances cosmos1..\r\n```\r\n\r\nExample Output:\r\n\r\n```yml\r\nbalances:\r\n- amount: \"1000000000\"\r\n  denom: stake\r\npagination:\r\n  next_key: null\r\n  total: \"0\"\r\n```\r\n\r\n##### denom-metadata\r\n\r\nThe `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.\r\n\r\n```shell\r\nsimd query bank denom-metadata [flags]\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\nsimd query bank denom-metadata --denom stake\r\n```\r\n\r\nExample Output:\r\n\r\n```yml\r\nmetadata:\r\n  base: stake\r\n  denom_units:\r\n  - aliases:\r\n    - STAKE\r\n    denom: stake\r\n  description: native staking token of simulation app\r\n  display: stake\r\n  name: SimApp Token\r\n  symbol: STK\r\n```\r\n\r\n##### total\r\n\r\nThe `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.\r\n\r\n```shell\r\nsimd query bank total [flags]\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\nsimd query bank total --denom stake\r\n```\r\n\r\nExample Output:\r\n\r\n```yml\r\namount: \"10000000000\"\r\ndenom: stake\r\n```\r\n\r\n##### send-enabled\r\n\r\nThe `send-enabled` command allows users to query for all or some SendEnabled entries.\r\n\r\n```shell\r\nsimd query bank send-enabled [denom1 ...] [flags]\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\nsimd query bank send-enabled\r\n```\r\n\r\nExample output:\r\n\r\n```yml\r\nsend_enabled:\r\n- denom: foocoin\r\n  enabled: true\r\n- denom: barcoin\r\npagination:\r\n  next-key: null\r\n  total: 2 \r\n```\r\n\r\n#### Transactions\r\n\r\nThe `tx` commands allow users to interact with the `bank` module.\r\n\r\n```shell\r\nsimd tx bank --help\r\n```\r\n\r\n##### send\r\n\r\nThe `send` command allows users to send funds from one account to another.\r\n\r\n```shell\r\nsimd tx bank send [from_key_or_address] [to_address] [amount] [flags]\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\nsimd tx bank send cosmos1.. cosmos1.. 100stake\r\n```\r\n\r\n## gRPC\r\n\r\nA user can query the `bank` module using gRPC endpoints.\r\n\r\n### Balance\r\n\r\nThe `Balance` endpoint allows users to query account balance by address for a given denomination.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/Balance\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    -d '{\"address\":\"cosmos1..\",\"denom\":\"stake\"}' \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/Balance\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"balance\": {\r\n    \"denom\": \"stake\",\r\n    \"amount\": \"1000000000\"\r\n  }\r\n}\r\n```\r\n\r\n### AllBalances\r\n\r\nThe `AllBalances` endpoint allows users to query account balance by address for all denominations.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/AllBalances\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    -d '{\"address\":\"cosmos1..\"}' \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/AllBalances\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"balances\": [\r\n    {\r\n      \"denom\": \"stake\",\r\n      \"amount\": \"1000000000\"\r\n    }\r\n  ],\r\n  \"pagination\": {\r\n    \"total\": \"1\"\r\n  }\r\n}\r\n```\r\n\r\n### DenomMetadata\r\n\r\nThe `DenomMetadata` endpoint allows users to query metadata for a single coin denomination.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/DenomMetadata\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    -d '{\"denom\":\"stake\"}' \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/DenomMetadata\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"metadata\": {\r\n    \"description\": \"native staking token of simulation app\",\r\n    \"denomUnits\": [\r\n      {\r\n        \"denom\": \"stake\",\r\n        \"aliases\": [\r\n          \"STAKE\"\r\n        ]\r\n      }\r\n    ],\r\n    \"base\": \"stake\",\r\n    \"display\": \"stake\",\r\n    \"name\": \"SimApp Token\",\r\n    \"symbol\": \"STK\"\r\n  }\r\n}\r\n```\r\n\r\n### DenomsMetadata\r\n\r\nThe `DenomsMetadata` endpoint allows users to query metadata for all coin denominations.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/DenomsMetadata\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/DenomsMetadata\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"metadatas\": [\r\n    {\r\n      \"description\": \"native staking token of simulation app\",\r\n      \"denomUnits\": [\r\n        {\r\n          \"denom\": \"stake\",\r\n          \"aliases\": [\r\n            \"STAKE\"\r\n          ]\r\n        }\r\n      ],\r\n      \"base\": \"stake\",\r\n      \"display\": \"stake\",\r\n      \"name\": \"SimApp Token\",\r\n      \"symbol\": \"STK\"\r\n    }\r\n  ],\r\n  \"pagination\": {\r\n    \"total\": \"1\"\r\n  }\r\n}\r\n```\r\n\r\n### DenomOwners\r\n\r\nThe `DenomOwners` endpoint allows users to query metadata for a single coin denomination.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/DenomOwners\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    -d '{\"denom\":\"stake\"}' \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/DenomOwners\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"denomOwners\": [\r\n    {\r\n      \"address\": \"cosmos1..\",\r\n      \"balance\": {\r\n        \"denom\": \"stake\",\r\n        \"amount\": \"5000000000\"\r\n      }\r\n    },\r\n    {\r\n      \"address\": \"cosmos1..\",\r\n      \"balance\": {\r\n        \"denom\": \"stake\",\r\n        \"amount\": \"5000000000\"\r\n      }\r\n    },\r\n  ],\r\n  \"pagination\": {\r\n    \"total\": \"2\"\r\n  }\r\n}\r\n```\r\n\r\n### TotalSupply\r\n\r\nThe `TotalSupply` endpoint allows users to query the total supply of all coins.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/TotalSupply\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/TotalSupply\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"supply\": [\r\n    {\r\n      \"denom\": \"stake\",\r\n      \"amount\": \"10000000000\"\r\n    }\r\n  ],\r\n  \"pagination\": {\r\n    \"total\": \"1\"\r\n  }\r\n}\r\n```\r\n\r\n### SupplyOf\r\n\r\nThe `SupplyOf` endpoint allows users to query the total supply of a single coin.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/SupplyOf\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    -d '{\"denom\":\"stake\"}' \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/SupplyOf\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"amount\": {\r\n    \"denom\": \"stake\",\r\n    \"amount\": \"10000000000\"\r\n  }\r\n}\r\n```\r\n\r\n### Params\r\n\r\nThe `Params` endpoint allows users to query the parameters of the `bank` module.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/Params\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/Params\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"params\": {\r\n    \"defaultSendEnabled\": true\r\n  }\r\n}\r\n```\r\n\r\n### SendEnabled\r\n\r\nThe `SendEnabled` endpoints allows users to query the SendEnabled entries of the `bank` module.\r\n\r\nAny denominations NOT returned, use the `Params.DefaultSendEnabled` value.\r\n\r\n```shell\r\ncosmos.bank.v1beta1.Query/SendEnabled\r\n```\r\n\r\nExample:\r\n\r\n```shell\r\ngrpcurl -plaintext \\\r\n    localhost:9090 \\\r\n    cosmos.bank.v1beta1.Query/SendEnabled\r\n```\r\n\r\nExample Output:\r\n\r\n```json\r\n{\r\n  \"send_enabled\": [\r\n    {\r\n      \"denom\": \"foocoin\",\r\n      \"enabled\": true\r\n    },\r\n    {\r\n      \"denom\": \"barcoin\"\r\n    }\r\n  ],\r\n  \"pagination\": {\r\n    \"next-key\": null,\r\n    \"total\": 2\r\n  }\r\n}\r\n```"},"author":{"user":"https://learnblockchain.cn/people/19936","address":"0xbabb650e9755e6d0f6197a4ed013ec5732795709"},"history":"bafkreiadgvm5vwvlbjosjuc2iyvbsoqhg7c2altfa4vksb5f5dpklvjosa","timestamp":1722157590,"version":1}