# Chain33主链对接交易所流程

## 1 部署主链节点钱包

chain33源码地址：https://github.com/33cn/chain33.git

plugin源码地址：https://github.com/33cn/plugin.git

bityuan源码地址：https://github.com/bityuan/bityuan.git

应用最新版本地址：https://www.bityuan.com/wallet

开发环境：详细过程请看 [开发环境安装](../docs/getBlockchainProgram.md#1-开发环境安装)

```
# 开发环境搭建完毕后，使用git命令下载代码到本地，这里以Linux系统为例
$ mkdir -p $GOPATH/bityuan
$ mkdir -p $GOPATH/src/github.com/bityuan
$ git clone https://github.com/bityuan/bityuan.git $GOPATH/src/github.com/bityuan/bityuan
```

配置文件：详细参数请看 [主链配置文件](https://github.com/bityuan/bityuan/blob/master/bityuan.toml)

```
# 配置文件参数大都使用默认即可，且一般都有介绍，如不清楚用途不要随意修改
# 重点常用可改参数：
# jrpcBindAddr、grpcBindAddr 请求端口，默认8801、8802，如有需要可以改成指定的端口提供服务
# whitelist 白名单，默认本地可以访问，一般钱包创建账户需要设定ip白名单
# dbPath 数据路径，可以改成自己指定的文件路径
# 查看并修改完配置参数后，创建bityuan.toml文件，将参数写入其中，随后复制到$GOPATH/bityuan目录下
$ cp bityuan.toml $GOPATH/bityuan/bityuan.toml
```

编译：

```
$ cd $GOPATH/src/github.com/bityuan/bityuan
# 创建并切换分支
$ git checkout -b bityuan-test
# 开启mod功能
$ export GO111MODULE=on
# 国内用户需要导入一下代理
$ export GOPROXY=https://mirrors.aliyun.com/goproxy
$ make
# 编译完成后，将编译好生成的可执行文件复制到$GOPATH/bityuan目录下
$ cp $GOPATH/src/github.com/bityuan/bityuan/bityuan $GOPATH/bityuan/bityuan
$ cp $GOPATH/src/github.com/bityuan/bityuan/bityuan-cli $GOPATH/bityuan/bityuan-cli
```

启动：

```
$ cd $GOPATH/bityuan
$ nohup ./bityuan -f bityuan.toml >/dev/null 2>log.out &

```

查询是否同步：

```
$ ./bityuan-cli net is_sync --rpc_laddr="http://localhost:8801"  //jrpc端口
# 返回true表示同步完成
# ssd硬盘一般需要6个小时同步完成
# 一般硬盘需要1-2天同步完成
# 硬盘空间需要100G左右
```

## 2 主链节点钱包对接交易所常用接口

备注：以下接口默认都采取jsonrpc post方法，转账支持note附言入账

### 2.1 获取随机种子

接口：Chain33.GenSeed

```
{
    "jsonrpc":"2.0",
    "id":int32,
    "method":"Chain33.SaveSeed",
    "params":[{"seed":"string" ,"passwd":"string"}]
}
```

参数说明

| 参数 | 类型  | 是否必填 | 说明                         |
| :--- | :---- | :------- | :--------------------------- |
| lang | int32 | 是       | lang=0:英语，lang=1:简体汉字 |

响应：

```
{
    "id": 0,
    "result": {
        "seed": "draw used cushion poem fade eyebrow word language claw blame lemon clean host feel degree"
    },
    "error": null
}
```

### 2.2 保存seed并用密码加密 SaveSeed

接口：Chain33.SaveSeed

```
{
    "jsonrpc":"2.0",
    "id":int32,
    "method":"Chain33.SaveSeed",
    "params":[{"seed":"string" ,"passwd":"string"}]
}
```

参数说明

| 参数   | 类型   | 是否必填 | 说明                                                      |
| :----- | :----- | :------- | :-------------------------------------------------------- |
| seed   | string | 是       | 种子要求16个单词或者汉字,参考genseed输出格式,需要空格隔开 |
| passwd | string | 是       | 加密密码 密码为不低于8个字符的数字和字母组合              |

响应：

```
{
    "id": 0,
    "result": {
        "isOK": true,
        "msg": ""
    },
    "error": null
}
```

### 2.3 钱包解锁 Unlock

接口：Chain33.UnLock

```
{
    "jsonrpc":"2.0", 
    "id":int32, 
    "method":"Chain33.UnLock",
    "params":[
        {
            "passwd":"string",
            "walletorticket":bool,
            "timeout":int32
        }
    ]
}
```

参数说明

| 参数           | 类型   | 是否必填 | 说明                                            |
| :------------- | :----- | :------- | :---------------------------------------------- |
| passwd         | string | 是       | 解锁密码                                        |
| walletorticket | bool   | 否       | true，只解锁ticket买票功能，false：解锁整个钱包 |
| timeout        | int32  | 否       | 超时时间                                        |

响应：

```
{
    "id": 0,
    "result": {
        "isOK": true,
        "msg": ""
    },
    "error": null
}

```

使用场景：

```
所有涉及到钱包操作私钥的接口都需要保证钱包已经解锁
```

### 2.4 创建账户 NewAccount

接口：Chain33.NewAccount

```
{
    "jsonrpc":"2.0", 
    "id":int32, 
    "method":"Chain33.NewAccount",
    "params":[
        {
            "label":"string"
        }
    ]
}
```

参数说明

| 参数  | 类型   | 是否必填 | 说明         |
| :---- | :----- | :------- | :----------- |
| label | string | 是       | 待设置的账户 |

响应：

```
{
    "id": 0,
    "result": {
        "acc": {
            "addr": "1JFgYK5QjUqSVxF8Kns6XHymFc3kSWrSx5"
        },
        "label": "test"
    },
    "error": null
}
```

使用场景：

```
交易所给每个用户建立对应代币的充币地址，label可关联对应的用户唯一标识
```

### 2.5 构造并发送交易

第一步：调用Chain33.CreateRawTransaction接口，构造转账交易

```
{
    "jsonrpc":"2.0",
    "id":1,
    "method":"Chain33.CreateRawTransaction",
    "params":[
        {
            "to":"string",
            "amount":10000000,
            "fee":0,
            "note":"test",
            "isToken":false,
            "tokenSymbol":"XXX",
            "execer":"coins" 
        }
    ]
}
```

| 参数        | 类型   | 是否必填 | 说明                                                         |
| :---------- | :----- | :------- | :----------------------------------------------------------- |
| to          | string | 是       | 币的转账目的地址                                             |
| amount      | int64  | 是       | 币的转账数量 * 1e8                                           |
| fee         | int64  | 是       | 币的转账费用，默认100000，可以调用[GetProperFee](./../jsonRPCInterface/transactionAPI.md#9-设置合适单元交易费率-getproperfee)来确定当前链上费用 |
| note        | string | 否       | 附言，支持标签信息入账                                       |
| isToken     | bool   | 否       | 默认false，如果是token设置true                               |
| tokenSymbol | string | 否       | isToken为true 设置币种名称                                   |
| execer      | string | 是       | 执行器名称 bty转账 默认coins                                 |

第二步：调用Chain33.SignRawTx接口 签名交易

```
{
    "jsonrpc":"2.0",
    "id":1,
    "method":"Chain33.SignRawTx",
    "params":[
      {
        "addr":"string",
        "privkey":"string",
        "txHex":"string",
        "expire":"string",
        "index":int32 
      }
    ]
}
```

| 参数    | 类型     | 是否必填 | 说明                                                         |
| :------ | :------- | :------- | :----------------------------------------------------------- |
| addr    | string   | 否       | 发送方地址，地址和私钥2选1，选地址需钱包里有这个账户地址     |
| privkey | string   | 否       | 发送方私钥，地址和私钥2选1，选地址需钱包里有这个账户地址     |
| txHex   | string   | 是       | 上一步构造交易的hex字符串                                    |
| expire  | string   | 否       | 交易过期时间 ”300ms”，”-1.5h”或者”2h45m”的字符串，有效时间单位为”ns”, “us” (or “µs”), “ms”, “s”, “m”, “h |
| index   | 交易序号 | 否       | 平行链代扣签名使用 从1开始，小于等于0则为签名组内全部交易    |

第三步：调用Chain33.SendTransaction接口 广播交易

```
{
    "jsonrpc":"2.0",
    "id":1,
    "method":"Chain33.SendTransaction",
    "params":[
      {
          "data":"string" //上一步签名交易hex字符串
      }
    ]
}
```

返回hash值

### 2.6 钱包转账构造签名广播便捷接口

接口：Chain33.SendToAddress
备注：发送方地址需在钱包账户里面，钱包已解锁 构造签名广播以及费率的适配钱包内置完成

```
{
    "jsonrpc":"2.0",
    "id":1,
    "method":"Chain33.SendToAddress",
    "params":[
      {
          "from":"string",
          "to":"string",
          "amount":int64,
          "note":"string",
          "isToken" : bool,
          "tokenSymbol" : string
      }
    ]
}
```

| 参数        | 类型   | 是否必填 | 说明                           |
| :---------- | :----- | :------- | :----------------------------- |
| from        | string | 是       | 发送方地址                     |
| to          | string | 是       | 转账目的地址                   |
| amount      | int64  | 是       | 币的转账数量 * 1e8             |
| note        | string | 否       | 附言                           |
| isToken     | bool   | 否       | 默认false，如果是token设置true |
| tokenSymbol | string | 否       | token币名称 设置币种名称       |

response

```
{
    "id":int32,
    "result":{"hash":""}
    "error":null
}
```

### 2.7 钱包合并账户余额

接口：Chain33.MergeBalance
备注：钱包解锁状态下，钱包遍历所有有bty余额的地址构造签名交易发送到指定地址，返回所有交易的hash列表

```
{
    "jsonrpc":"2.0",
    "id":1,
    "method":"Chain33.MergeBalance",
    "params":[
      {
          "to":"string"
      }
    ]
}
```

| 参数 | 类型   | 是否必填 | 说明                               |
| :--- | :----- | :------- | :--------------------------------- |
| to   | string | 是       | 合并钱包上的所有余额到一个账户地址 |

response

```
{
    "id":int32,
    "result":{"hashes":["string"]}
}
```

## 3 常见错误原因

### 3.1 ErrSeedExist

节点钱包已经导入seed，如果忘记密码和seed 可以删除wallet文件夹重新启动节点（有余额账户请做好备份）

### 3.2 ErrInvalidParam

一般是参数没传为空，请检查接口参数

### 3.3 ErrWalletIsLocked

一般涉及到钱包私钥的接口都需要先解锁钱包 Unlock

### 3.4 ErrAddrNotExist

一般是 钱包下的账户地址没有此地址，如要使用这个地址 ，需提前导入钱包地址私钥

### 3.5 ErrNoPrivKeyOrAddr

一般是签名传参时，addr和privkey参数都没有设置

### 3.6 ErrNoBalance

一般是地址没有对应币的转账余额或者bty费率不够扣

### 3.7 ErrBalanceLessThanTenTimesFee

签名地址bty余额少于10倍最小费率0.001，也就是转账需要至少0.01bty余额

### 3.8 ErrActionNotSupport

一般是此执行器没有支持此方法的类型

### 3.9 ErrTxFeeTooLow

交易费用设置太低

### 3.10 ErrTxExist

交易已存在不要重复发送

### 3.11 ErrTxExpire

交易已经过期，expire参数可以设置时间长一些

### 3.12 ErrInvalidAddr

地址不可用，请检查地址参数