# Chain33平台架构的特点

这里我们先引用官网上对于chain33平台架构的介绍： 
```
Chain33平台是一套支持共识，数据库，执行器等可插拔，且易升级的区块链架构。  
Chain33创造性的支持分层的架构，主链负责交易清算，智能合约和虚拟机从主链上分离放到平行链上独立执行，多条平行链并存提升运算效率。且平行链之间通过主链实现链间互联。
```
两个特点的概括，指向了两个方向：  

**1、共识、数据库、执行器（合约），对chain33的纵向扩展；**   
**2、平行链，对chain33的横向扩展。**   

这里主要介绍执行器和平行链的相关内容。  

# chain33系统中的合约 
chain33系统中的**合约**，也可以称为**执行器**（executor），是chain33架构纵向扩展的核心。 

功能上类似于微服务架构，合约相互之间耦合度低，单个合约不依赖于其他合约的功能，插拔使用便捷。 

## chain33合约的一些基础概念  
从外部看，一个合约需要包含以下要素，这里用**挖矿合约**（ticket执行器）举例说明：  

```
1、合约名（执行器名称）： ticket  
2、合约地址：16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp 
```

每个合约拥有一个**唯一**的合约地址，该地址从合约创造出来开始就被固定并唯一，这个合约地址**不存在私钥**；  

对于任何一个已知的合约名，都可以在chain33中查询该合约的合约地址。  
![查询合约地址](https://gitlab.33.cn/flyaway53/test/raw/master/img-folder/8.png)

## chain33合约的使用
对于chain33合约，存在一个**资产控制权**的概念。  
想要使用对应合约的功能，首先需要将资产控制权转移（TransferToExec）给对应合约；从表现上来看，就是将资产转入了对应的合约地址。  

为了合约调用的安全考虑，只允许基础合约**主动**向其他合约转账，而不允许其他合约从基础合约中取款。  
目前对于主链上来说，coins、token、paracross三个合约作为基础合约，支持使用TransferToExec和withdraw。

```
同样以挖矿合约举例，要进行挖矿操作，需要从coins合约中主动向ticket合约转账，之后才允许ticket合约本身，对合约中的资产进行操作。我们钱包中开启自动挖矿的操作已经集成了该步操作。  
再以token C2C举例，想要进行token的C2C交易，需要首先将token合约中的资产，从token合约转入到trade合约，之后才允许trade合约使用；而不允许trade合约调用token合约中的资产。  
```

转移资产控制权后，合约可以任意控制资产，主要包括*冻结、解冻、增加、减少*等操作。  

而对应的，存在转回资产控制权（withdraw）的操作，将资产的控制权限转移回来。之后合约对资产控制权限终止。  


所以chain33的合约系统事实上是扁平化的格局，所有合约在权限上都是平等的，既无权调用其他合约的资产，也无权被其他合约调用；想要使用其他合约的功能，只能先将资产控制权转移给相应合约。  


合约地址中的代币分为两部分：**余额及冻结**，以满足各合约的需求。  
![余额](https://gitlab.33.cn/flyaway53/test/raw/master/img-folder/12.png)

以ticket合约举例，当用户持有11000BTY进行挖矿，资产流转过程如下图所示。  
![余额变化](https://gitlab.33.cn/flyaway53/test/raw/master/img-folder/13.png)



## 如何理解地址和合约之间的关系
前面提到，合约只能操作自己合约中的资产，那么我们需要使用合约的功能的话，必须首先将资产转入该合约。 

chain33系统支持两种方式转入：

**1、直接指定执行器（合约）名称转入；**  
**2、直接向指定合约地址转入。**

```
对挖矿合约来说，可以使用send_exec命令，直接向ticket执行器转入；  
也可以使用普通的transfer命令，向16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp合约地址转入。  
```

要理解的是，向合约地址转入代币以后，该代币实际以两种形态可以被查询：  

1、存在于用户的合约中；  
2、存在于合约地址的余额中。  

但对于用户来说，实际只需关心自己的合约中的余额。  
```
同样以挖矿合约举例，我们在主网浏览器上可以查询到**合约地址16htvcBNSEA7fZhAdLJphDwQRQJaHpyHTp**的余额。  
这个余额代表当下有多少代币正在该合约中，这个值是所有其他地址转入挖矿合约的代币总和。  
```
因为合约地址不存在私钥的原则，该地址中的余额无法被私钥转出，只能以满足合约规则的方式变动。
![合约余额](https://gitlab.33.cn/flyaway53/test/raw/master/img-folder/9.png)



如上面提到的，我转入其他合约的代币，依然是属于我的地址的资产，只是暂时将控制权限转移给了合约；  
当需要的时候，随时可以将其控制权限取回。  

在查询的时候，也可以查询到我的地址在所有合约下的余额。如图可以查询到我的地址在其他合约中的余额。 
![查询余额](https://gitlab.33.cn/flyaway53/test/raw/master/img-folder/10.png)

这里可以做一个类比来更好的理解。

```
我们把地址比做银行账户，地址就是账户名；  
coins、token、paracross这类就是活期储蓄账户，其他合约就是基金账户、理财账户等等；  
转入其他合约的操作就是把钱从活期中转入了其他账户的过程，而实际上这部分钱的户名都是同一个，只是暂时将资产控制权转移出去，属于不同的分类中。  
也可以操作将他们从其他类账户转回活期账户，完成整个操作。
```

## chain33合约的优势
从上面的介绍也可以看到，chain33合约的扩展性非常强。  
因其新合约无需依赖其他合约，调试等等也不与coins以外的其他合约耦合，保持基础框架稳定的情况下，修改、新增其他合约对整个系统的稳定性影响是非常有限的。  
这就对纵向深入扩展整个chain33网络起到了基石性的作用。目前bityuan主网支持的合约有以下这些：  

**ticket**：挖矿合约；  
**hashlock**：哈希锁定合约；  
**multisig**：多重签名合约；  
**retrieve**：钱包找回合约；  
**para**：跨链合约；  
**token**：token代币合约；  
**trade**：token与coins的C2C合约；  
**unfreeze**：冻结解冻合约。  

以上是主链支持的系统合约，其他应用于平行链的合约，在介绍平行链的内容中阐述。

# chain33系统的平行链（Parachain）
合约系统是对chain33的纵向扩展，而平行链就是对系统的横向延伸。 
要理解平行链的功能，我们首先需要了解一下chain33区块链传输时的一些基本信息。 

从其他节点同步一个区块，分为**下载、执行**两个阶段。下载耗时主要依赖于网络环境；**执行**主要依赖于交易内容及本地机器性能。  
目前的区块一般执行时间在几十ms级别。  
当一个区块内交易数量很多或交易内容很大，执行区块的耗时会拉长，可能会达到秒级甚至分钟，导致执行超时，进而影响全网速度及tps。  

而平行链的存在，是将一部分交易的执行由平行链节点完成，**主链只负责打包，而不具体执行**。只打包交易耗时和执行想必几乎可以忽略不计。  
这就等于将部分性能压力分摊在平行链节点上，从而为bityuan网络tps的提升极大地去除了限制，也为横向扩展bityuan网络增加了可能性。  

## 平行链的生态

因为平行链的交易无需在主链执行，因此平行链可以使用未在主链注册过的合约；也就是说每条平行链可以有独一无二的合约使用，而无需经过主链同意。  
目前包括**evm虚拟机、wasm虚拟机、oracle预言机、blackwhite/pokerbull/guess/game等游戏合约**都部署在不同的平行链上，极大丰富了bityuan网络生态。 

而平行链可以作为独立的一条链使用，同时依托于**跨链合约**，也可以将平行链和主链结合起来，通过主链币和平行链币的跨链交换，成为一个整体的生态。这也是之后平行链发展使用的一个方向。 

**主链负责整体框架及基础功能，而平行链执行具体细分领域的实现**，是bityuan网络架构的整体思路。多元化拓展以及受硬件约束较小的特点是独有的优势。  


目前bityuan网络只已经有十几条平行链存在，非常有效地提升了主网的tps及生态。之后随着平行链的扩展越来越多，相信整个网络的生态也会日益完善。  

## 交易组（Txgroup）  
谈到平行链，就无法离开**交易组（原子交易）**使用。  
交易组的概念是，将若干笔交易，目前限制数量是2-20笔，构造成一个交易组。  
组内交易必然按照构造的顺序打包进同一个区块，且该组交易**要么全部成功，要么全部失败**，组内任何一个交易执行校验失败都会让整个交易组的交易**全部失败**。  

在交易组出现之前，chain33全网的交易遵循一个原则：任何交易都需要支付满足消耗的BTY作为手续费。
显然这种设定扩展性较差，因此增加了交易组的设定原则：整个交易组的手续费都由第一笔交易的发送者承担，后面的发送者无需支付手续费。  

而平行链诞生以来，交易组的使用更为频繁：  
平行链的交易虽然不在主链执行，但仍需要在主链完成打包，这笔打包操作就需要消耗BTY作为手续费。  
而平行链的地址作为独立生态，显然并不一定拥有BTY，在这种情况下，更多会使用一个中心地址构造交易组，完成BTY代扣的操作，使平行链的交易无需支付手续费。  
![交易组](https://gitlab.33.cn/flyaway53/test/raw/master/img-folder/11.png)

交易组是对平行链架构的一个有效的补充，在其他场景下的应用也十分有效。



