> ## Documentation Index
> Fetch the complete documentation index at: https://stablelabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 银行模块

> 提供 ERC-20 兼容代币转账、授权与委托功能的 Bank 预编译合约。

## 概述

Stable SDK 中的 `x/bank` 模块仅提供基本的代币管理功能。
每个代币都可以无限制地转移到任何账户，用户无法委托其他账户代为转移其代币到其他账户。
因此，`bank` 预编译合约在 Stable SDK 现有的 `x/bank` 模块基础上提供了额外的授权和委托功能。

## 目录

1. **[概念](#concepts)**
2. **[配置](#configuration)**
3. **[方法](#methods)**
4. **[事件](#events)**

## 概念

该预编译合约提供 ERC20 标准方法 - 如用于转账的 `transfer` 和 `balanceOf`，以及用于委托的 `transferFrom`、`approve` 和 `allowance`。这些方法可以直接调用，无需注册合约地址。

然而，`mint` 和 `burn` 方法需要合约地址被列入白名单，通过 `x/precompile` 模块注册。

```go theme={"dark"}
func (p *Precompile) mint(
  ctx sdk.Context,
  contract *vm.Contract,
  denom string,
  method *abi.Method,
  stateDB vm.StateDB,
  args []interface{},
) ([]byte, error) {
  // ...

  // mint method is only allowed for the registered caller contract
  if _, err := precompilecommon.CheckPermissions(ctx, p.precompileKeeper, contract.CallerAddress, CallerPermissions); err != nil {
    return nil, err
  }
```

额外的验证过程可以保证调用此预编译合约的代币合约是经过授权的。

需要通过治理提案来注册代币合约地址及其denomination到 `x/precompile` 模块的白名单中。

## 配置

合约地址和gas费用已预定义。

### 合约地址

* `0x0000000000000000000000000000000000001003` STABLE (用于治理代币)

## 方法

### `mint`

铸造请求数量的新代币并转移到账户。
要铸造的代币数量必须大于零。

当代币成功铸造并转移到账户时，会发出 `PrecompiledBankMint` 事件。

注意：

* 禁止铸造治理代币。
* 调用铸造方法的合约必须在 x/precompile 模块中注册。

#### 输入参数

| 名称     | 类型      | 描述        |
| ------ | ------- | --------- |
| to     | address | 接收铸造代币的地址 |
| amount | uint256 | 要铸造的代币数量  |

#### 输出参数

| 名称      | 类型   | 描述                    |
| ------- | ---- | --------------------- |
| success | bool | 如果代币成功铸造并转移到账户，则为true |

### `burn`

从账户中销毁请求数量的代币。
要销毁的代币数量必须大于零。

当代币成功销毁时，会发出 `PrecompiledBankBurn` 事件。

注意：

* 禁止销毁治理代币。
* 调用铸造方法的合约必须在 x/precompile 模块中注册。

#### 输入参数

| 名称     | 类型      | 描述       |
| ------ | ------- | -------- |
| from   | address | 销毁代币的地址  |
| amount | uint256 | 要销毁的代币数量 |

#### 输出参数

| 名称      | 类型   | 描述              |
| ------- | ---- | --------------- |
| success | bool | 如果代币成功销毁，则为true |

### `transfer`

将请求数量的代币从发送者转移给接收者。
代币必须设置为可发送。要转移的代币数量必须大于零。

当代币成功转移时，会发出 `PrecompiledBankTransfer` 事件。

#### 输入参数

| 名称     | 类型      | 描述       |
| ------ | ------- | -------- |
| to     | address | 接收代币的地址  |
| amount | uint256 | 要转移的代币数量 |

#### 输出参数

| 名称      | 类型   | 描述              |
| ------- | ---- | --------------- |
| success | bool | 如果代币成功转移，则为true |

### `transferFrom`

由授权的支出者在允许额度范围内将请求数量的代币从所有者转移给接收者。
代币必须设置为可发送。
要转移的代币数量必须大于零并且小于或等于当前允许额度。

当代币成功转移时，会发出 `PrecompiledBankTransfer` 事件。

#### 输入参数

| 名称     | 类型      | 描述       |
| ------ | ------- | -------- |
| from   | address | 转出代币的地址  |
| to     | address | 接收代币的地址  |
| amount | uint256 | 要转移的代币数量 |

#### 输出参数

| 名称      | 类型   | 描述              |
| ------- | ---- | --------------- |
| success | bool | 如果代币成功转移，则为true |

### `multiTransfer`

将代币从单个账户转移到多个账户。
代币必须设置为可发送。
转移给每个接收者的代币数量必须大于零。

当代币成功转移时，每个接收者都会发出 `PrecompiledBankTransfer` 事件。

#### 输入参数

| 名称     | 类型         | 描述            |
| ------ | ---------- | ------------- |
| to     | address\[] | 接收转移代币的地址数组   |
| amount | uint256\[] | 转移给每个接收者的代币数量 |

#### 输出参数

| 名称      | 类型   | 描述                    |
| ------- | ---- | --------------------- |
| success | bool | 如果代币成功转移给每个接收者，则为true |

### `approve`

授权支出者从所有者账户转移代币。
要授权的代币数量必须大于零。

当授权成功设置时，会发出 `PrecompiledBankApproval` 事件。

#### 输入参数

| 名称      | 类型      | 描述       |
| ------- | ------- | -------- |
| spender | address | 要授权的地址   |
| value   | uint256 | 要授权的代币数量 |

#### 输出参数

| 名称      | 类型   | 描述              |
| ------- | ---- | --------------- |
| success | bool | 如果授权成功设置，则为true |

### `revoke`

撤销支出者从所有者转移代币的授权。

当授权成功撤销时，会发出 `PrecompiledBankRevoke` 事件。

#### 输入参数

| 名称      | 类型      | 描述     |
| ------- | ------- | ------ |
| spender | address | 要撤销的地址 |

#### 输出参数

| 名称      | 类型   | 描述              |
| ------- | ---- | --------------- |
| success | bool | 如果授权成功撤销，则为true |

### `balanceOf`

返回账户的代币余额。

#### 输入参数

| 名称      | 类型      | 描述         |
| ------- | ------- | ---------- |
| account | address | 要获取代币余额的地址 |

#### 输出参数

| 名称      | 类型      | 描述       |
| ------- | ------- | -------- |
| balance | uint256 | 账户中的代币数量 |

### `totalSupply`

返回代币的总供应量。

#### 输入参数

无

#### 输出参数

| 名称          | 类型      | 描述     |
| ----------- | ------- | ------ |
| totalSupply | uint256 | 代币的总数量 |

### `allowance`

返回支出者仍可从所有者提取的金额。

#### 输入参数

| 名称      | 类型      | 描述     |
| ------- | ------- | ------ |
| owner   | address | 所有者的地址 |
| spender | address | 支出者的地址 |

#### 输出参数

| 名称     | 类型      | 描述      |
| ------ | ------- | ------- |
| amount | uint256 | 授权的代币数量 |

## 事件

所有从此预编译合约发出的事件都以 `PrecompiledBank` 为前缀。
为了避免歧义，调用此预编译合约的代币合约应避免使用相同前缀的事件名称。

### PrecompiledBankMint

| 名称     | 类型      | 索引 | 描述        |
| ------ | ------- | -- | --------- |
| from   | address | Y  | 铸造代币的地址   |
| to     | address | Y  | 接收铸造代币的地址 |
| amount | uint256 | N  | 铸造的代币数量   |

### PrecompiledBankBurn

| 名称     | 类型      | 索引 | 描述      |
| ------ | ------- | -- | ------- |
| from   | address | Y  | 销毁代币的地址 |
| to     | address | Y  | 此方法中未使用 |
| amount | uint256 | N  | 销毁的代币数量 |

### PrecompiledBankTransfer

| 名称     | 类型      | 索引 | 描述        |
| ------ | ------- | -- | --------- |
| from   | address | Y  | 转移代币的地址   |
| to     | address | Y  | 接收转移代币的地址 |
| amount | uint256 | N  | 转移的代币数量   |

### PrecompiledBankApproval

| 名称      | 类型      | 索引 | 描述      |
| ------- | ------- | -- | ------- |
| owner   | address | Y  | 授权代币的地址 |
| spender | address | Y  | 被授权的地址  |
| value   | uint256 | N  | 授权的代币数量 |

### PrecompiledBankRevoke

| 名称      | 类型      | 索引 | 描述        |
| ------- | ------- | -- | --------- |
| owner   | address | Y  | 撤销代币授权的地址 |
| spender | address | Y  | 被撤销的地址    |
| value   | uint256 | N  | 授权的代币数量   |
