# 通过命令行体验链 ## 概述 通过本文你可以通过命令行和cmc工具搭建长安链多节点集群和部署智能合约,完成长安链的初步体验。 通过源码搭建长安链并且上链查数据需要以下步骤,本文将一一演示 - 下载长安链及证书管理工具源码 - 编译源码 - 生成节点证书 - 编译及安装包制作 - 启动节点集群 - 查看节点状态 - 使用CMC工具安装、调用、查询一个合约 ## 环境依赖 ### 硬件依赖 | 配置 | 最低配置 | 推荐配置 | | ---- | -------- | -------- | | CPU | 1.5GHz | 2.4GHz | | 内存 | 8GB | 16GB | | 核心 | 4核 | 8核 | | 带宽 | 2Mb | 10Mb | ### 软件依赖 当前文档在centos7.6操作下完成,以下为本次演示所需的依赖 软件列表如下: | 名称 | 版本 | 描述 | 是否必须 | | --------------------------------------------- | ----- | ------------------------------------------------------------ | -------- | | git | / | 源码管理 | 是 | | golang | 1.16-1.19 | 编译环境(需修改国内代理) | 是 | | gcc | 7.3+ | 编译环境依赖 | 是 | | glibc | 2.18 | 智能合约执行环境依赖 | 是 | | tmux | / | 默认快速启动命令依赖 | 否 | | wasmer运行时库 **libwasmer_runtime_c_api.so** | / | https://git.chainmaker.org.cn/chainmaker/vm-wasmer/-/tree/master/wasmer-go/packaged/lib 目录下,找到对应链分支的库,将该库路径添加至系统PATH环境变量下
启动脚本默认包含,单独启动需加上如下配置:
cd deployPath/lib
cp xxx/main/libwasmer_runtime_c_api.so libwasmer.so
export LD_LIBRARY_PATH=deployPath/lib:$LD_LIBRARY_PATH | 是 | #### git 下载地址:[https://git-scm.com/downloads](https://git-scm.com/downloads) 安装步骤,请参看:[https://git-scm.com/book/en/v2/Getting-Started-Installing-Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) #### golang > 版本为1.16-1.19 下载地址:[https://golang.org/dl/](https://golang.org/dl/) 安装步骤,请参看:[https://golang.org/doc/install](https://golang.org/doc/install) #### gcc 1. 检查 gcc 版本 ```bash gcc --version ``` 显示结果若 < 7.3,则执行下面步骤升级 2. 升级 gcc ```bash sudo yum install centos-release-scl sudo yum install devtoolset-7-gcc* scl enable devtoolset-7 bash ``` 注意:第三条指令`scl enable devtoolset-7 bash` 只是在当前会话中升级了gcc,如果想每次登录gcc自动升级,可以把`scl enable devtoolset-7 bash` 放在` ~/.bash_profile` 文件中。 ## 环境搭建 下面将介绍`使用脚本搭建`搭建环境。 ### 使用脚本搭建 > 适用于`Linux`、`MacOS` #### 源码下载 从[长安链官网](https://chainmaker.org.cn/)下载源码:[https://git.chainmaker.org.cn/chainmaker/chainmaker-go](https://git.chainmaker.org.cn/chainmaker/chainmaker-go) > 当前为私有仓库,需要先进行账号注册 - 下载`chainmaker-go`源码到本地 ```bash $ git clone -b v2.3.1 --depth=1 https://git.chainmaker.org.cn/chainmaker/chainmaker-go.git ``` - 下载`证书生成工具`源码到本地 ```bash $ git clone -b v2.3.0 --depth=1 https://git.chainmaker.org.cn/chainmaker/chainmaker-cryptogen.git ``` #### 源码编译 - 编译证书生成工具 ```bash $ cd chainmaker-cryptogen $ make ``` #### 配置文件生成 - 将编译好的`chainmaker-cryptogen`,软连接到`chainmaker-go/tools`目录 ```bash # 进入工具目录 $ cd chainmaker-go/tools # 软连接chainmaker-cryptogen到tools目录下 $ ln -s ../../chainmaker-cryptogen/ . ``` - 2.1版本之后,ChainMaker支持多种身份模式,由于不同身份模式下,配置文件的目录结构和内容差异较大,在此我们选择身份模式PermissionedWithCert(详情见[身份权限管理](../instructions/长安链账户整体介绍.md))作为示例。 ##### PermissionedWithCert 原始的身份模式,即证书模式 进入`chainmaker-go/scripts`目录,执行`prepare.sh`脚本生成单链4节点集群配置,存于路径`chainmaker-go/build`中 > `prepare.sh`脚本支持生成`solo`模式节点证书和配置,以及4/7/10/13/16节点的证书和配置 ```bash # 进入脚本目录 $ cd ../scripts # 查看脚本帮助 $ ./prepare.sh -h Usage: prepare.sh node_cnt(1/4/7/10/13/16) chain_cnt(1-4) p2p_port(default:11301) rpc_port(default:12301) eg1: prepare.sh 4 1 eg2: prepare.sh 4 1 11301 12301 # 生成单链4节点集群的证书和配置 $ ./prepare.sh 4 1 begin check params... begin generate certs, cnt: 4 input consensus type (0-SOLO,1-TBFT(default),3-HOTSTUFF,4-RAFT,5-DPOS): input log level (DEBUG|INFO(default)|WARN|ERROR): enable docker vm (YES|NO(default)) begin generate node1 config... begin generate node2 config... begin generate node3 config... begin generate node4 config... # 查看生成好的节点证书和配置 $ tree -L 3 ../build/ ../build/ ├── config │   ├── node1 │   │   ├── certs │   │   ├── chainconfig │   │   ├── chainmaker.yml │   │   └── log.yml │   ├── node2 │   │   ├── certs │   │   ├── chainconfig │   │   ├── chainmaker.yml │   │   └── log.yml │   ├── node3 │   │   ├── certs │   │   ├── chainconfig │   │   ├── chainmaker.yml │   │   └── log.yml │   └── node4 │   ├── certs │   ├── chainconfig │   ├── chainmaker.yml │   └── log.yml ├── crypto-config │   ├── wx-org1.chainmaker.org │   │   ├── ca │   │   ├── node │   │   └── user │   ├── wx-org2.chainmaker.org │   │   ├── ca │   │   ├── node │   │   └── user │   ├── wx-org3.chainmaker.org │   │   ├── ca │   │   ├── node │   │   └── user │   └── wx-org4.chainmaker.org │   ├── ca │   ├── node │   └── user └── crypto_config.yml ``` - 关于自动生成的端口说明 通过`prepare.sh`脚本生成的配置,默认是在单台服务器上部署,故自动生成的端口号,是从一个起始端口号开始依次递增,可以通过命令行参数修改起始端口号。 主要有2个端口,`p2p`端口(用于节点互联)和`rpc`端口(用于客户端与节点通信),`p2p`起始端口为`11301`,`rpc`起始端口为`12301`。 如果生成4个节点的配置,`p2p`端口分别为:`11301、11302、11303、11304`,`rpc`端口分别为:`12301、12302、12303、12304` 如果是在多机部署,希望生成固定的端口号,请参考:[【多机部署】](../instructions/多机部署) #### 编译及安装包制作 - 生成证书(prepare.sh脚本)后执行`build_release.sh`脚本,将编译`chainmaker-go`模块,并打包生成安装,存于路径`chainmaker-go/build/release`中 ```bash $ ./build_release.sh $ tree ../build/release/ ../build/release/ ├── chainmaker-v2.0.0-wx-org1.chainmaker.org-20210406194833-x86_64.tar.gz ├── chainmaker-v2.0.0-wx-org2.chainmaker.org-20210406194833-x86_64.tar.gz ├── chainmaker-v2.0.0-wx-org3.chainmaker.org-20210406194833-x86_64.tar.gz ├── chainmaker-v2.0.0-wx-org4.chainmaker.org-20210406194833-x86_64.tar.gz └── crypto-config-20210406194833.tar.gz ``` #### 启动节点集群 - 执行`cluster_quick_start.sh`脚本,会解压各个安装包,调用`bin`目录中的`start.sh`脚本,启动`chainmaker`节点 ```bash $ ./cluster_quick_start.sh normal ``` - 启动成功后,将*.tar.gz备份,以免下次启动再次解压缩时文件被覆盖 ```sh $ mkdir -p ../build/bak $ mv ../build/release/*.tar.gz ../build/bak ``` > 若需要关闭集群,使用脚本: > > ```bash > $ ./cluster_quick_stop.sh > ``` #### 查看节点启动使用正常 - 查看进程是否存在 ```bash $ ps -ef|grep chainmaker | grep -v grep 25261 2146 4 19:55 pts/20 00:00:01 ./chainmaker start -c ../config/wx-org1.chainmaker.org/chainmaker.yml 25286 2146 4 19:55 pts/20 00:00:01 ./chainmaker start -c ../config/wx-org2.chainmaker.org/chainmaker.yml 25309 2146 4 19:55 pts/20 00:00:01 ./chainmaker start -c ../config/wx-org3.chainmaker.org/chainmaker.yml 25335 2146 4 19:55 pts/20 00:00:01 ./chainmaker start -c ../config/wx-org4.chainmaker.org/chainmaker.yml ``` - 查看端口是否监听 ```bash $ netstat -lptn | grep 1230 tcp6 0 0 :::12301 :::* LISTEN 25261/./chainmaker tcp6 0 0 :::12302 :::* LISTEN 25286/./chainmaker tcp6 0 0 :::12303 :::* LISTEN 25309/./chainmaker tcp6 0 0 :::12304 :::* LISTEN 25335/./chainmaker ``` - 检查节点是否有`ERROR`日志 ```bash $ cat ../build/release/*/bin/panic.log $ cat ../build/release/*/log/system.log $ cat ../build/release/*/log/system.log |grep "ERROR\|put block\|all necessary" //若看到all necessary peers connected则表示节点已经准备就绪。 ``` ## 使用CMC命令行工具部署、调用合约 为了验证所搭建的链功能是否正常,可以通过`cmc`命令行工具来进行验证。 ### 编译&配置 cmc工具的编译&运行方式如下: > 创建工作目录 $WORKDIR 比如 ~/chainmaker
> 启动测试链 [在工作目录下 使用脚本搭建](../quickstart/通过命令行体验链.md)
```sh # 编译cmc $ cd $WORKDIR/chainmaker-go/tools/cmc $ go build # 配置测试数据 $ cp -rf ../../build/crypto-config ../../tools/cmc/testdata/ # 使用chainmaker-cryptogen生成的测试链的证书 # 查看help $ cd ../../chainmaker-go/tools/cmc $ ./cmc --help ``` ### 部署示例合约 - 创建wasm合约 ```sh $ ./cmc client contract user create \ --contract-name=fact \ --runtime-type=WASMER \ --byte-code-path=./testdata/claim-wasm-demo/rust-fact-2.0.0.wasm \ --version=1.0 \ --sdk-conf-path=./testdata/sdk_config.yml \ --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.key \ --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.sign.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.sign.crt \ --sync-result=true \ --params="{}" ``` > 注:智能合约编写参见:[智能合约开发](../instructions/智能合约开发.md) - 调用wasm合约 ```sh $ ./cmc client contract user invoke \ --contract-name=fact \ --method=save \ --sdk-conf-path=./testdata/sdk_config.yml \ --params="{\"file_name\":\"name007\",\"file_hash\":\"ab3456df5799b87c77e7f88\",\"time\":\"6543234\"}" \ --sync-result=true ``` - 查询合约 ```sh $ ./cmc client contract user get \ --contract-name=fact \ --method=find_by_file_hash \ --sdk-conf-path=./testdata/sdk_config.yml \ --params="{\"file_hash\":\"ab3456df5799b87c77e7f88\"}" ``` ### 查询链上数据 查询链上block和transaction 主要参数说明如下: ```sh --sdk-conf-path:指定cmc使用sdk的配置文件路径 --chain-id:指定链Id ``` - 根据区块高度查询链上未归档区块 ```sh ./cmc query block-by-height [blockheight] \ --chain-id=chain1 \ --sdk-conf-path=./testdata/sdk_config.yml ``` - 根据区块hash查询链上未归档区块 ```sh ./cmc query block-by-hash [blockhash] \ --chain-id=chain1 \ --sdk-conf-path=./testdata/sdk_config.yml ``` - 根据txid查询链上未归档区块 ```sh ./cmc query block-by-txid [txid] \ --chain-id=chain1 \ --sdk-conf-path=./testdata/sdk_config.yml ``` - 根据txid查询链上未归档tx ```sh ./cmc query tx [txid] \ --chain-id=chain1 \ --sdk-conf-path=./testdata/sdk_config.yml ``` #### 查询链配置 ```sh ./cmc client chainconfig query \ --sdk-conf-path=./testdata/sdk_config.yml ``` ## 长安链部署目录说明 此目录为使用: `chainmaker-go/scripts/cluster_quick_start.sh`启动后的的目录结构说明。 ```sh taifu@chainmaker:chainmaker-go/build$ tree . ├── backup # 下次重新prepare.sh时,此次的备份。 ├── config # 使用 prepare.sh 生成的节点配置信息 │   ├── node1 # 节点1-4 │   ├── node2 │   ├── node3 │   └── node4 ├── crypto-config # 使用 prepare.sh 生成的组织证书信息 │   ├── wx-org1.chainmaker.org # 组织名称1-4 │   │   ├── ca # 该组织的根证书 ca │   │   ├── node # 由该组织的根证书签发的节点证书 common/consensus │   │   └── user # 由该组织的根证书签发的用户证书 admin/client/light │   ├── wx-org2.chainmaker.org │   │   ├── ca │   │   ├── node │   │   └── user │   ├── wx-org3.chainmaker.org │   │   ├── ca │   │   ├── node │   │   └── user │   └── wx-org4.chainmaker.org │   ├── ca │   ├── node │   └── user ├── crypto_config.yml # 使用 prepare.sh 生成以上证书的配置文件(扩展组织、证书可使用到) ├── pkcs11_keys.yml # 使用 prepare.sh 生成的硬件加密机相关配置 └── release # 使用 build_release.sh 生成的打包好的部署文件夹 ├── crypto-config-20220720141039.tar.gz # 证书集 即上面的crypto-config文件夹的压缩包 ├── chainmaker-v2.3.0-wx-org2.chainmaker.org # 使用 cluster_quick_start.sh 启动链后,解压缩后的部署文件 │   ├── bin # 操作管理脚本目录 │   ├── config # 配置文件目录 │   ├── data # 数据目录 │   ├── lib # 依赖目录 │   └── log # 日志目录 ├── chainmaker-v2.3.0-wx-org2.chainmaker.org-20220720141039-x86_64.tar.gz # 使用 build_release.sh 生成的打包好的部署文件 ├── chainmaker-v2.3.0-wx-org3.chainmaker.org │   ├── bin │   ├── config │   ├── data │   ├── lib │   └── log ├── chainmaker-v2.3.0-wx-org3.chainmaker.org-20220720141039-x86_64.tar.gz ├── chainmaker-v2.3.0-wx-org4.chainmaker.org │   ├── bin │   ├── config │   ├── data │   ├── lib │   └── log │── chainmaker-v2.3.0-wx-org4.chainmaker.org-20220720141039-x86_64.tar.gz | | | # 以下为部署节点文件详情 ├── chainmaker-v2.3.0-wx-org1.chainmaker.org # 解压缩后的部署文件 │   ├── bin # 操作管理脚本目录 │   │   ├── chainmaker # 二进制文件 │   │   ├── chainmaker.service # 基于 linux 系统的 systemd 自拉起服务 │   │   ├── docker-vm-standalone-start.sh # 独立启动 docker 虚拟机引擎脚本 │   │   ├── docker-vm-standalone-stop.sh # 独立停止 docker 虚拟机引擎脚本 │   │   ├── init.sh # 基于 linux 系统的 systemd 自拉起服务部署脚本 │   │   ├── panic.log # 异常日志输出及控制台输出日志文件 │   │   ├── restart.sh # 重启节点脚本 │   │   ├── run.sh # 基于 linux 系统的 systemd 自拉起服务管理脚本 │   │   ├── start.sh # 启动节点脚本 │   │   └── stop.sh # 停止节点脚本 │   ├── config # 配置文件目录 │   │   └── wx-org1.chainmaker.org │   │   ├── certs # 证书 │   │   │   ├── ca │   │   │   │   ├── wx-org1.chainmaker.org │   │   │   │   │   └── ca.crt │   │   │   ├── node │   │   │   │   |── common1 # 同步节点证书(通过chainmaker.yml配置为节点证书,表示只可同步) │   │   │   │   └── consensus1 # 共识节点证书(通过chainmaker.yml配置为节点证书不代表就可以参与共识,共识管理是在链配置bc.yml中) │   │   │   │   ├── consensus1.nodeid # xxx.sign.crt生成的节点id │   │   │   │   ├── consensus1.sign.crt # 签名证书 │   │   │   │   ├── consensus1.sign.key # 签名key │   │   │   │   ├── consensus1.tls.crt # tls连接证书 │   │   │   │   └── consensus1.tls.key # tls连接key │   │   │   └── user # 用户证书 │   │   │   ├── admin1 # 管理员 │   │   │   │   ├── admin1.sign.crt │   │   │   │   ├── admin1.sign.key │   │   │   │   ├── admin1.tls.crt │   │   │   │   └── admin1.tls.key │   │   │   ├── client1 # 普通客户端 │   │   │   │   ├── client1.addr │   │   │   │   ├── client1.sign.crt │   │   │   │   ├── client1.sign.key │   │   │   │   ├── client1.tls.crt │   │   │   │   └── client1.tls.key │   │   │   └── light1 # 轻节点,只可同步当前组织的数据(区块、交易) │   │   │   ├── light1.sign.crt │   │   │   ├── light1.sign.key │   │   │   ├── light1.tls.crt │   │   │   └── light1.tls.key │   │   ├── chainconfig # 链配置 │   │   │   │── bc1.yml # 第一条链配置 │   │   │   └── bc2.yml # 第二条链配置 │   │   ├── chainmaker.yml # 节点配置 │   │   └── log.yml # 日志配置 │   ├── data # 数据目录 │   │   └── wx-org1.chainmaker.org │   │   ├── block # 区块数据/索引(必须) │   │   │   └── chain1 │   │   │   └── store_block │   │   │   ├── 000001.log │   │   │   ├── CURRENT │   │   │   ├── LOCK │   │   │   ├── LOG │   │   │   └── MANIFEST-000000 │   │   ├── history # 历史数据 │   │   │   └── chain1 │   │   │   └── store_history │   │   │   ├── 000001.log │   │   │   ├── CURRENT │   │   │   ├── LOCK │   │   │   ├── LOG │   │   │   └── MANIFEST-000000 │   │   ├── ledgerData1 # 中间数据(必须) │   │   │   └── chain1 # 链ID │   │   │   ├── bfdb # 区块实际存储数据(文件存储方式) │   │   │   │   └── 00000000000000000001.fdb.END │   │   │   ├── localdb # 中间状态数据 │   │   │   │   ├── 000001.log │   │   │   │   ├── CURRENT │   │   │   │   ├── LOCK │   │   │   │   ├── LOG │   │   │   │   └── MANIFEST-000000 │   │   │   └── wal_QmSQeH1SV65YkafQG6y7uqabF4Xwzn5VoXniFBXrzy4Eqn # 异常恢复临时数据 │   │   │   └── 00001_1.wal │   │   ├── result # 结果集数据 │   │   │   └── chain1 │   │   │   └── store_result │   │   │   ├── 000001.log │   │   │   ├── CURRENT │   │   │   ├── LOCK │   │   │   ├── LOG │   │   │   └── MANIFEST-000000 │   │   └── state # 状态数据(必须) │   │   └── chain1 │   │   └── store_state │   │   ├── 000001.log │   │   ├── CURRENT │   │   ├── LOCK │   │   ├── LOG │   │   └── MANIFEST-000000 │   ├── lib # 依赖目录 │   │   ├── libwasmer.so # wasmer(rust)运行引擎 │   │   └── wxdec # wxvm(c++)运行引擎 │   └── log # 日志目录 │   ├── system.log # 当前1小时的日志 │   └── system.log.2022072014 # 历史日志 └── chainmaker-v2.3.0-wx-org1.chainmaker.org-20220720141039-x86_64.tar.gz # 使用 build_release.sh 生成的打包好的部署文件