# 平行链资产转移管理介绍

> 平行链支持主链资产和平行链资产之间的互转，也支持平行链资产间接的转移到另一个平行链。

## 1 chain33和平行链的统一资产表示

[chain33和平行链的统一资产表示](../jsonRPCInterface/paracrossAPI.md#1-chain33和平行链的统一资产表示)

## 2 跨链资产转移的方向

> 新的跨链资产转移接口通过 交易执行器 + 资产合约　+ 资产符号　来唯一确定资产转移的方向: 转移或提回

```
　　　　　　　　　　　　　　　　　交易执行器                    资产合约名                  资产符号名                            目标资产名
主链转移到平行链:　　　　　　　　　user.p.game.paracross　　　  token                      ccny　                               user.p.game.paracross.token.ccny
主链从平行链提回:　　　　　　　　　user.p.game.paracross       user.p.game.paracross      token.ccny　                         主链资产恢复      
平行链转移到主链:　　　　　　　　　user.p.game.paracross       user.p.game.token          ccny                                 paracross.user.p.game.token.ccny
平行链从主链提回:　　　　　　　　　user.p.game.paracross       paracross                  user.p.game.token.ccny               平行链资产恢复
主链跨链资产转移到另一个平行链:　　user.p.test.paracross       paracross               　 user.p.game.token.ccny               user.p.test.paracross.paracross.user.p.game.token.ccny
主链跨链资产从另一个平行链提回:　　user.p.test.paracross       user.p.test.paracross   　 paracross.user.p.game.token.ccny     主链恢复到paracross合约
```

## 3 跨链资产转移步骤

> 准备跨链资产需要先转到本链的paracross合约下，再进行跨链转移交易

- 转账到paracross合约，比如coins, token资产转移到paracross合约,特别的主链上从Ａ平行链转移过来的资产虽然在paracross合约下，也需要一次转账到paracross合约
- 跨链转移交易，同时在主链和平行链执行
- 注意: 当前每个可铸币的原生合约都提供”各自”的存款到目标执行器的接口，比如token有token自己的，　paracross有paracross自己的transfer2Exec接口

## 4 跨链资产转移接口

### 4.1 资产转移接口

**调用接口**

```
rpc CreateTransaction(CreateTxIn) returns (UnsignTx) {}
```

**参数：**

```
message CreateTxIn {
    bytes  execer     = 1;
    string actionName = 2;
    bytes  payload    = 3;
}
message CrossAssetTransfer {
    string assetExec    = 1;
    string assetSymbol  = 2;
    int64  amount       = 3;
    //default signed addr
    string toAddr       = 4;
    string note         = 5;
}
```

**参数说明：**

| 参数        | 类型   | 说明                                                         |
| :---------- | :----- | :----------------------------------------------------------- |
| execer      | bytes  | 执行器名称, 需填具体平行链title+paracross，例如user.p.dog.paracross |
| actionName  | string | CrossAssetTransfer                                           |
| payload     | bytes  | types.Encode(&CrossAssetTransfer)                            |
| assetExec   | string | 资产原生合约，比如coins,token                                |
| assetSymbol | string | 资产符号，比如bty, ccny                                      |
| amount      | int64  | 转移资产数量，精确到10^8                                     |
| toAddr      | string | 可选，目标地址，缺省为交易签名地址                           |
| note        | string | 可选，转移备注                                               |

**返回数据：**

```
message UnsignTx {    bytes data = 1;}
```

**参数说明：**

| 参数 | 类型  | 说明                     |
| :--- | :---- | :----------------------- |
| data | bytes | 交易十六进制编码后的数据 |

### 4.2 查询资产转移是否成功接口

> 只能在主链上查询

**调用接口**

```
rpc QueryChain(ChainExecutor) returns (Reply) {}
```

**参数：**

```
message ChainExecutor {
    string driver    = 1;
    string funcName  = 2;
    bytes  stateHash = 3;
    bytes  param     = 4;
    bytes  extra     = 5;
}
message ReqString {
    string data = 1;
}
```

**参数说明：**

| 参数      | 类型   | 说明                                                         |
| :-------- | :----- | :----------------------------------------------------------- |
| driver    | bytes  | 执行器名称, 这里固定为 paracross                             |
| funcName  | string | 操作名称, 这里固定为 GetAssetTxResult                        |
| stateHash | bytes  | 所有交易在对应的执行器执行后写入KVDB中重新计算得到的新state的哈希值 |
| param     | bytes  | types.Encode(&ReqString)                                     |
| extra     | bytes  | 扩展字段，用于额外的用途                                     |
| data      | string | 跨链交易hash                                                 |

**响应数据：**

```
message ParacrossAsset {
    // input
    string from       = 1;
    string to         = 2;
    bool   isWithdraw = 3;
    string txHash     = 4;
    int64  amount     = 5;
    string exec       = 6;
    string symbol     = 7;
    //跨链类型　0:to para, 1:to main
    uint32 crossType       = 8;
    // 主链部分
    int64 height = 10;
    // 平行链部分
    int64 commitDoneHeight = 21;
    int64 paraHeight       = 22;
    bool  success          = 23;
}
```

**参数说明：**

| 参数             | 类型   | 说明                   |
| :--------------- | :----- | :--------------------- |
| from             | string | 跨链转移交易签名地址   |
| to               | string | 跨链转移内部合约地址   |
| isWithdraw       | bool   | 旧接口，弃用           |
| crossType        | int    | 旧接口，弃用           |
| height           | string | 交易主链执行高度       |
| commitDoneHeight | string | 交易在主链共识成功高度 |
| paraHeight       | string | 交易在平行链执行高度   |
| success          | string | 跨链转移交易是否成功   |

### 4.3 平行链跨资产转到合约接口

> 跨链转移进来的资产放在paracross合约下，默认为原生合约

**调用接口**

```
rpc CreateTransaction(CreateTxIn) returns (UnsignTx) {}
```

**参数：**

```
message CreateTxIn {
    bytes  execer     = 1;
    string actionName = 2;
    bytes  payload    = 3;
}
message AssetsTransferToExec {
    string cointoken = 1;
    int64  amount    = 2;
    bytes  note      = 3;
    string execName  = 4;
    string to        = 5;
}
```

**参数说明：**

| 参数       | 类型   | 说明                                                     |
| :--------- | :----- | :------------------------------------------------------- |
| execer     | bytes  | 执行器名称, 主链填paracross，平行链需要把title加上       |
| actionName | string | TransferToExec                                           |
| payload    | bytes  | types.Encode(&AssetsTransferToExec)                      |
| execName   | string | 目标合约名称，如果平行链上转需要填平行链的执行器名字     |
| to         | string | 目标合约地址，示例是user.p.dog.trade的地址               |
| amount     | int    | 转移数量                                                 |
| cointoken  | string | 转移资产符号,默认原生合约就是paracross，所以只填符号即可 |

**返回数据：**

```
message UnsignTx {
    bytes data = 1;
}
```

**参数说明：**

| 参数 | 类型  | 说明                     |
| :--- | :---- | :----------------------- |
| data | bytes | 交易十六进制编码后的数据 |

### 4.4 查询平行链共识高度

**调用接口**

```
rpc QueryChain(ChainExecutor) returns (Reply) {}
```

**参数：**

```
message ChainExecutor {
    string driver    = 1;
    string funcName  = 2;
    bytes  stateHash = 3;
    bytes  param     = 4;
    bytes  extra     = 5;
}
message ReqString {
    string data = 1;
}
```

**参数说明：**

| 参数      | 类型   | 说明                                                         |
| :-------- | :----- | :----------------------------------------------------------- |
| driver    | bytes  | 执行器名称, 这里固定为 paracross                             |
| funcName  | string | 操作名称, 这里固定为 GetTitle                                |
| stateHash | bytes  | 所有交易在对应的执行器执行后写入KVDB中重新计算得到的新state的哈希值 |
| param     | bytes  | types.Encode(&ReqString)                                     |
| extra     | bytes  | 扩展字段，用于额外的用途                                     |

**响应数据：**

```
message ParacrossStatus {
    string title      = 1;
    int64  height     = 2;
    bytes  blockHash  = 3;
    int64  mainHeight = 4;
    bytes  mainHash   = 5;
}
```

### 4.5 查询平行链某高度共识情况

> 可以查看平行链某高度超级节点提交共识情况，查看哪些账户提交了共识，共识hash是否相同，若某高度未达成共识，可以用此接口查询提交情况

**调用接口**

```
rpc QueryChain(ChainExecutor) returns (Reply) {}
```

**参数：**

```
message ChainExecutor {
    string driver    = 1;
    string funcName  = 2;
    bytes  stateHash = 3;
    bytes  param     = 4;
    bytes  extra     = 5;
}
message ReqParacrossTitleHeight {
    string title  = 1;
    int64  height = 2;
}
```

**参数说明：**

| 参数      | 类型   | 说明                                                         |
| :-------- | :----- | :----------------------------------------------------------- |
| driver    | bytes  | 执行器名称, 这里固定为 paracross                             |
| funcName  | string | 操作名称, 这里固定为 GetTitleHeight                          |
| stateHash | bytes  | 所有交易在对应的执行器执行后写入KVDB中重新计算得到的新state的哈希值 |
| param     | bytes  | types.Encode(&ReqParacrossTitleHeight)                       |
| extra     | bytes  | 扩展字段，用于额外的用途                                     |

**响应数据：**

```
message ParacrossHeightStatusRsp {
    int32    status                            = 1;
    string   title                             = 2;
    int64    height                            = 3;
    int64    mainHeight                        = 4;
    string   mainHash                          = 5;
    repeated string commitAddrs                = 6;
    repeated string commitBlockHash            = 7;
    repeated string commitSupervisionAddrs     = 8;
    repeated string commitSupervisionBlockHash = 9;
}
```

**参数说明：**

| 参数            | 类型   | 说明                 |
| :-------------- | :----- | :------------------- |
| status          | int    | 1:成功，0:未共识成功 |
| commitAddrs     | string | 超级节点投票账户     |
| commitBlockHash | string | 超级节点提交块hash   |

### 4.6 查询平行链高度和共识高度

> 可以在主链或平行链上查询平行链当前高度和共识高度，在主链上查的链高度就是平行链的共识高度

**调用接口**

```
rpc QueryChain(ChainExecutor) returns (Reply) {}
```

**参数：**

```
message ChainExecutor {
    string driver    = 1;
    string funcName  = 2;
    bytes  stateHash = 3;
    bytes  param     = 4;
    bytes  extra     = 5;
}
message ReqString {
    string data = 1;
}
```

**参数说明：**

| 参数      | 类型   | 说明                                                         |
| :-------- | :----- | :----------------------------------------------------------- |
| driver    | bytes  | 执行器名称, 这里固定为 paracross                             |
| funcName  | string | 操作名称, 这里固定为 GetHeight                               |
| stateHash | bytes  | 所有交易在对应的执行器执行后写入KVDB中重新计算得到的新state的哈希值 |
| param     | bytes  | types.Encode(&ReqString)                                     |
| extra     | bytes  | 扩展字段，用于额外的用途                                     |
| data      | string | 主链上查询需要填，平行链上可以不填                           |

**响应数据**

```
message ParacrossConsensusStatus {
    string title            = 1;
    int64  chainHeight      = 2;
    int64  consensHeight    = 3;
    string consensBlockHash = 4;
}
```

### 4.7 查询平行链高度和主链匹配高度

> 在平行链上查询具体平行链区块高度hash和对应主链区块的高度和hash

**调用接口**

```
rpc QueryChain(ChainExecutor) returns (Reply) {}
```

**参数：**

```
message ChainExecutor {
    string driver    = 1;
    string funcName  = 2;
    bytes  stateHash = 3;
    bytes  param     = 4;
    bytes  extra     = 5;
}
message ReqBlocks {
    int64    start      = 1;
    int64    end        = 2;
    bool     isDetail   = 3;
    repeated string pid = 4;
}
```

**参数说明：**

| 参数      | 类型   | 说明                                                         |
| :-------- | :----- | :----------------------------------------------------------- |
| driver    | bytes  | 执行器名称, 这里固定为 paracross                             |
| funcName  | string | 操作名称, 这里固定为 GetBlock2MainInfo                       |
| stateHash | bytes  | 所有交易在对应的执行器执行后写入KVDB中重新计算得到的新state的哈希值 |
| param     | bytes  | types.Encode(&ReqBlocks)                                     |
| extra     | bytes  | 扩展字段，用于额外的用途                                     |

**响应数据**

```
message ParaBlock2MainInfo {
    repeated ParaBlock2MainMap items = 1;
}
message ParaBlock2MainMap {
    int64  height     = 1;
    string blockHash  = 2;
    int64  mainHeight = 3;
    string mainHash   = 4;
}
```

