# 账户内部模型

## 1 Chain33账户基本模型介绍

### 1.1 Chain33钱包基本属性描述

在chain33钱包中存放着有很多地址，这些地址我们可以理解成账户。每一个账户中存储着很多资产：可以是bty；也可以是某些token；也可以是平行链/跨链的资产

chain33上资产可以在各个合约之间移动、使用， 如果要用一个元素描述资产所在合约，那么这个元素就是“资产现在所在的合约”

chain33上资产有明确的归属， 这个归属的地址就是资产所属的地址(账户)

chain33资产有数量和性质。比如有100个活动的bty，“100”表示这个这种bty资产的数量，“活动”表示这种bty的性质(还有“冻结”这个性质)

> 查看wallet的具体情况
> 输入代码查看account下的所有wallet的所有账号情况，并找到minerAddr的账户情况

```
$ ./chain33-cli account list
```

```
# bty
{
    "wallets": [
        {
            "acc": {
                "balance": "9977.6850",
                "frozen": "0.0000",
                "addr": "12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv"
            },
            "label": "minerAddr"
        }
    ]
}
```

> 查询mineraddr下的所有财产情况

```
$ ./chain33-cli account balance -a 12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv
```
```
# token 资产
{
    "token": "TC",
    "balance": "50.0000",
    "frozen": "0.0000",
    "addr": "12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv"
}
# 平行链资产
{
    "exec": "user.p.para.token",
    "symbol": "GD",
    "amount": 1100000000,
    "addr": "12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv"
}
# 查看跨链资产
{
"exec": "paracross",
    "symbol": "token.TC",
    "balance": "50.0000",
    "frozen": "0.0000",
    "addr": "12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv"
}
```

## 2 Chain33账户介绍

> coins\token

从前面的一小节的输出里面我们可以看到chain33中账户对应一个地址，这个地址由对应的私钥掌握。由于一个地址对应多种资产，那么在chain33内部如何表示呢？

先从存储上看一种资产对应一个状态，存放在状态树上，节点的KEY包含地址和资产信息，如下

```
mavl-{exec}-{symbol}-{addr}
```

> 建立一个普通账户的地址，以bty为例，其状态树KEY表示为

```
exec=coins
symbol=bty
addr=12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv
key=mavl-coins-bty-12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv
```

> 在同样的地址下的不同的资产，它的exec和symbol也会不一样

比如在chain33源代码中的acccount包里有函数`NewCoinsAccount`就是为了方便访问这个状态。通用的访问资产的函数是`NewAccountDB`，代码如下：

```
func NewCoinsAccount() *DB {
    prefix := "mavl-coins-bty-"
    return newAccountDB(prefix)
}
func NewAccountDB(execer string, symbol string, db dbm.KV) (*DB, error) {
    ...
    accDB := newAccountDB(symbolPrefix(execer, symbol))
    ...
    return accDB, nil
}
```

使用`NewAccountDB`我们可以很容易导出想要的资产信息，比如我们想要导出token的资产就可以如下操作（token在AccountDB中的地址是key=mavl-token-TC-12cjnN5D4DPdBQSwh6vjwJbtsW4EJALTMv）

```
NewAccountDB("token", "TC", db)
```

现在有linj的地址12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv，他的地址下有两种资产bty和TC，我们可以看到chain3下的模型如下：

```
└── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
    ├── mavl-coins-bty-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
    └── mavl-token-TC-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
```

## 3 合约账户/合约子帐号

首先介绍合约账号，简单的说合约账号就是对应着一个合约的地址，但是又没有人掌握着它的私钥。合约账号的主要功能是帮助我们完成合约规定的业务。
在这里我们举一个交易合约trade的例子，这个合约主要功能是帮助我们完成资产的交换。

### 3.1 地址情况介绍

比如 linj 想用 2个bty 来换取 10个TC token，正好 alice 愿意进行这场交易
如果要进行这场交易，我们首先要知道它们的地址情况
地址情况如下

```
trade 合约地址：1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
linj  地址： 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
alice 地址： 1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
```

再查看它们在数据库中存储的KEY情况，可以发现它们地址对应的KEY的命名规则和普通地址一样：

```
# trade bty
mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
# trade TC token
mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
```

因为chain33出于安全的考虑，限制了资产的处理，所以合约需要自己去处理名下的资产。
因此 linj 和 alice 要进行交易，先要把资产转到 trade 合约。
下面是合约子帐号的变化：

```
合约子帐号格式 mavl-exec-symbol-exec_addr:user_addr
alice 在 trade 合约中的 bty 和 TC 的子账户 如下
├── label:alice-addr:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
│   ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
```

### 3.2 限制资产处理规则

三条基本规则：
1.合约可以处理自己的帐号
2.合约可以处理自己的帐号里的子帐号
3.合约可以自己合约的记录(包含资产帐号，其他业务相关的记录)
对三条规则进行具体扩展（以trade为例）：
1.coins 合约可以处理 mavl-coins- 开始的状态
2.token 合约可以处理 mavl-token- 开始的状态
3.trade 合约可以处理 mavl-trade- 开始的状态。（这里没有列出来，mavl-trade- 开始的状态是交易相关的订单的记录）
4.trade 可以处理其他合约里自己的帐号/子帐号，满足格式 mavl-exec-symbol-trade_addr/mavl-exec-symbol-trade_addr:user_addr

### 3.3 合约过程演示

我们已经看到了普通用户帐号，合约帐号，合约子帐号的格式情况。
下面演示下完整的交易过程。
例子为 linj 想用 2个bty 换 10个TC token，正好 alice 愿意进行这场交易置换。
我们假设原来 linj 和 alice 都有 100 bty 和 100 TC token。
交易过程：
1.linj 转账 2bty 到 trade 账户; alice转账 10TC 到 trade 账户
2.linj 提出交易（挂单）
3.alice 接受交换
4.linj/alice 在交易完成后，把币提回到自己的帐号

> 初始状态

```
├── label:alice-addr:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0
│   ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0
│   ├── mavl-coins-bty-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        100
│   └── mavl-token-TC-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        100
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-coins-bty-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        100
│   ├── mavl-token-TC-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        100
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0
│   └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0
└── label:trade-addr:1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
    ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        0   
    │   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv    0
    │   └── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d    0
    └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        0
        ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0
        └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0
```

> 当 linj 转账 2bty 到 trade 账户; alice 转账 10TC 到 trade 账户后的情况如下：

```
├── label:alice-addr:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0
│   ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        10    *
│   ├── mavl-coins-bty-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        100
│   └── mavl-token-TC-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        90    *
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-coins-bty-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        98    *
│   ├── mavl-token-TC-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        100
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        2    *
│   └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0
└── label:trade-addr:1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
    ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        2    *
    │   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv    2    *
    │   └── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d    0
    └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        10    *
        ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0
        └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        10    *
```

> 当 linj 提出交易（挂单)时 linj 在 trade 合约的 2bty 会被冻结，资金变化如下：

```
├── label:alice-addr:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0
│   ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        10   
│   ├── mavl-coins-bty-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        100
│   └── mavl-token-TC-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        90   
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-coins-bty-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        98   
│   ├── mavl-token-TC-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        100
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        2    *
│   └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0
└── label:trade-addr:1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
    ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        2   
    │   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv    2    *
    │   └── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d    0
    └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        10   
        ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0
        └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        10
```

> alice 接受交换: alice/linj 在 trade 合约里的子帐号资产互换

```
├── label:alice-addr:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        2    *
│   ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0    *
│   ├── mavl-coins-bty-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        100
│   └── mavl-token-TC-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        90   
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-coins-bty-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        98   
│   ├── mavl-token-TC-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        100
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0    *
│   └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        10    *
└── label:trade-addr:1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
    ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        2   
    │   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv    0    *
    │   └── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d    2    *
    └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        10   
        ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        10    *
        └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0    *
```

> linj/alice 在交易完成后，把币提回到自己的帐号

```
├── label:alice-addr:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0    *
│   ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0    *
│   ├── mavl-coins-bty-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        102    *
│   └── mavl-token-TC-1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d                        90   
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-coins-bty-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        98   
│   ├── mavl-token-TC-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        110    *
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0    *
│   └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0    *
└── label:trade-addr:1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
    ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        0    *   
    │   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv    0   
    │   └── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d    0    *
    └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        0    *
        ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0    *
        └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0
```

## 4 跨链资产

chain33可以通过跨链合约，把资产转移到平行链上。
具体步骤
1.把资产从原始的合约里转到跨链合约
2.在调用跨链合约的跨链操作把资产转移到指定的平行链上

```
# 跨链合约地址
paracross=1HPkPopVe3ERfvaAgedDtJQ792taZFEHCe
# 跨链合约帐号 bty 资产
mavl-coins-bty-1HPkPopVe3ERfvaAgedDtJQ792taZFEHCe  2bty
# linj 在跨链合约帐号 bty 资产
mavl-coins-bty-1HPkPopVe3ERfvaAgedDtJQ792taZFEHCe:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv  2bty
# 在平行链上的 bty 资产，资产原始合约为 paracroos，资产名字为 coins.bty
mavl-paracross-coins.bty-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv  2bty
# 注意这里不要混淆了
# 若将平行链上的 bty 移动到其他平行链上的合约使用，以 exec=paracross，symbol=coins.bty，按上文规则进行组织帐号
# 而平行链上的主币即平行链 coins 合约里的 bty，转移到其他合约 exec=coins，symbol=bty
# 从平行链上的 trade 来看， 他们的 key 的区别
mavl-paracross-coins.bty-1HPkPopVe3ERfvaAgedDtJQ792taZFEHCe  2bty
mavl-coins-bty-1HPkPopVe3ERfvaAgedDtJQ792taZFEHCe  2bty
```

> 如果需要操作其他合约
> 只要把合约地址换掉，带入上面的规则即可完成

## 5 资产存储

在区块链的数据库中账户资产信息是以`Key - Value`成对保存的。在账户模型中介绍了如何用一个帐号的地址对应不同的资产， 下面介绍资产是如何保存的。

### 5.1 资产的存储

Account的proto格式，具体如下

```
// Account 的信息
message Account {
    // coins标识，目前只有0 一个值
    int32 currency = 1;
    //账户可用余额
    int64 balance = 2;
    //账户冻结余额
    int64 frozen = 3;
    //账户的地址
    string addr = 4;
}
// currency = 0 表示可切分资产，后面可能会引入不可切分的资产。
```

### 5.2 合约内的资产操作

合约获得资产的控制权后，可以对资产进行全权控制。合约控制权主要体现在下面这几个操作：

```
//冻结资产
ExecFrozen
//解冻资产
ExecActive
//给账户减少活动资产
ExecWithraw
//给账户增加活动资产
ExecDeposit
//这个可以通过 ExecDeposit 和 ExecWithraw 组合出来，但是因为比较常见，我们也作为一个操作
ExecTransfer
ExecTransferFrozen
```

### 5.3 交易涉及的资产操作

我们这里再以trade合约为例。
以不一样的形式表达在第三节中的例子。
linj 和 alice 都有 100bty 和 100 TC token. linj 想用 2个bty 换 10个 TC token，正好 alice 愿意进行这场交易置换。
交易的过程：
1.linj 转账 2bty 到 trade 账户; alice转账10TC 到 trade 账户
2.linj 提出交易（挂单）
3.alice 接受交换
4.linj/alice 在交易完成后，把币提回到自己的帐号

> linj 转账 2bty 到 trade 账户, alice转账10TC 到 trade 账户，这里的操作变化

```
linj 转账 2bty 到 trade 账户, 涉及三个资产变化， 即三组 Key-Value 对
 1. linj coins 合约 bty 资产: 余额 100,变为 98
 1. trade coins 合约 bty 资产：余额 0, 变为 2
 1. linj 在 trade 里的 bty 资产: 余额 0, 变为 2
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-coins-bty-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        100
        Account {
            currency = 0
            balance = 100  --> 98
            int64 frozen = 0
            addr = 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
        }
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0
        Account {
            currency = 0
            balance = 0 --> 2
            int64 frozen = 0
            addr = 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
        }
└── label:trade-addr:1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
    ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        0   
        Account {
            currency = 0
            balance = 0 --> 2
            int64 frozen = 0
            addr = 1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
        }
对应的资产操作是
 1. 资产控制权转移给合约.
 1. 合约内部ExecDeposit，将资产存入 trade合约子账户
//资产控制权转移给合约
message AssetsTransferToExec {
    cointoken = bty;
    amount    = 2 * 10e8 // 一个bty在内部表示，即精度保留8为小数
    note      = "转账到trade合约，为了换TC token，按自己需要写吧";
    execName  = "trade"
    to        = "1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4" // trade 合约地址
}
//
alice 的资产变化: 资产控制权转移给合约
 1. alice coins 合约 TC资产: 余额 100,变为 10
 1. trade token 合约 TC 资产：余额 0, 变为 10
 1. alice 在 trade 里的 TC 资产: 余额 0, 变为 10
```

> linj 提出交易（挂单）

```
在trade合约里挂单交易， 需要冻结余额预期被交易的资产， 涉及资产为 linj在trade合约里的 bty 资产, 对应操作和合约内冻结操作， 并生成订单(订单状态这里不介绍, 和具体业务有关)
//冻结资产
ExecFrozen
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0    *
        Account {
            currency = 0
            balance = 2 --> 0
            frozen = 0  --> 2
            addr = 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
        }
```

> alice 接受交换

```
接受交换，即可完成交易， 在业务上首先判断alice 是否有足够的TC资产， 看能否完成交易。
完成交易的资产变化
 1. alice 在 trade 合约里的 10 TC，转移到 linj 在 trade 合约里的资产。
 1. linj 在trade 合约里的 2 bty ，转移到 alice 在 trade 合约里的资产
资产在合约内部交易资产，合约自己帐号信息不变
alice 在 trade 合约里的 10 TC，转移到 linj 在 trade 合约里的资产, 涉及操作为 ExecTransfer, ExecTransferFrozen， 4个资产变化。
├── label:alice-addr:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0    *
        Account {
            currency = 0
            balance = 0 --> 2
            frozen = 0
            addr = 1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
        }
│   ├── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d        0    *
        Account {
            currency = 0
            balance = 10 --> 0
            frozen = 0
            addr = 1GaMeW34xAMo27iPEkVLeZenu1MfLAVn8d
        }
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-coins-bty-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0    *
        Account {
            currency = 0
            balance = 0
            frozen = 2  --> 0
            addr = 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
        }
│   └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0    *
        Account {
            currency = 0
            balance = 0 --> 10
            frozen = 0
            addr = 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
        }
```

> linj/alice 在交易完成后，把币提回到自己的帐号

```
linj 将 10 TC 从 trade 合约提币到 token 合约, 涉及操作 AssetsWithdraw
和 ExecWithraw
//从合约中转回资产控制权
message AssetsWithdraw {
    string cointoken = TC;
    int64  amount    = 10* 10e8;
    bytes  note      = "提币";
    string execName  = "trade";
    string to        = "1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4";
}
资产变化涉及3个
├── label:linj-addr:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                           
│   ├── mavl-token-TC-12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv                        110    *
        Account {
            currency = 0
            balance = 100 -> 110
            frozen = 0
            addr = 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
        }
│   └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4:12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv        0    *
        Account {
            currency = 0
            balance = 10 -> 0
            frozen = 0
            addr = 12qyocayNF7Lv6C9qW4avxs2E7U41fKSfv
        }
└── label:trade-addr:1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
    └── mavl-token-TC-1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4                        0    *
        Account {
            currency = 0
            balance = 10 -> 0
            frozen = 0
            addr = 1BXvgjmBw1aBgmGn1hjfGyRkmN3krWpFP4
        }
```

