# 典型场景示例 本章节将介绍“长安链·ChainMaker”在实际使用过程中的一些经典范例。 ## 构造新节点加入网络 假设现在存在一个由4个共识节点组成的链chain1,我们期望构造一个新的节点加入到网络中,在[【加入网络】](./节点管理.md)中详细的描述了一个新的节点加入网络需要的操作步骤,以下是这些步骤以及相关命令行示例 ### 准备节点运行的目录、配置、和执行文件 通过执行以下几个步骤,可以生成新节点的运行目录,目录结构为: ```sh chainmaker-go/build/release]# ll drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org1.chainmaker.org drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org2.chainmaker.org drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org3.chainmaker.org drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org4.chainmaker.org drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org5.chainmaker.org chainmaker-go/build/release]# tree -L 3 chainmaker-v2.2.1-wx-org5.chainmaker.org chainmaker-v2.2.1-wx-org5.chainmaker.org ├── bin │ ├── chainmaker │ ├── chainmaker.service │ ├── docker-vm-standalone-start.sh │ ├── docker-vm-standalone-stop.sh │ ├── init.sh │ ├── panic.log │ ├── restart.sh │ ├── run.sh │ ├── start.sh │ └── stop.sh ├── config │ └── wx-org5.chainmaker.org │ ├── certs │ ├── chainconfig │ ├── chainmaker.yml │ └── log.yml ├── data │ └── wx-org5.chainmaker.org │ ├── block │ ├── history │ ├── ledgerData1 │ ├── result │ └── state ├── lib │ ├── libwasmer.so │ └── wxdec └── log ``` 具体操作步骤如下: - 基于目前的链上已存在的组织和节点扩展出新的证书,参考[【扩展证书】](../dev/证书生成工具.md),示例脚本和说明如下: ```sh current_version="v2.2.1" chainmaker_path="/home/projects/test/chainmaker-go" cryptogen_path="/home/projects/test/chainmaker-cryptogen" gen_new_cert(){ echo "------------在chainmaker-cryptogen下生成org5的节点证书:-------------------" cd "${cryptogen_path}/bin" # 1.备份旧的证书文件 rm -rf crypto-config-bk mv crypto-config crypto-config-bk # 2.复制链上所有节点的证书到bin目录下,适用于在现有组织证书的基础上扩展节点证书 cp -r "${chainmaker_path}/build/crypto-config" ./ # 3. 修改配置文件 # 如果增加一个共识节点,node: -type: consensus 下面的count: 本来是1,改为2就等于增加一个共识节点,适用于在现有组织证书的基础上扩展节点证书 # 如果想增加一个新的组织:修改host_name: wx-org下的count,适用于增加一个新的组织及其节点 vim ../config/crypto_config_template.yml # 请手动编辑后保存。 # 4. 执行命令生成新的证书 ./chainmaker-cryptogen extend -c ../config/crypto_config_template.yml } ``` 方法执行后会在chainmaker-cryptogen/bin目录下生成新节点的证书: ```shell chainmaker-cryptogen/bin]# tree -L 1 crypto-config crypto-config ├── wx-org1.chainmaker.org ├── wx-org2.chainmaker.org ├── wx-org3.chainmaker.org ├── wx-org4.chainmaker.org ├── wx-org5.chainmaker.org ``` - 构建节点的执行目录 ```sh copy_node_file(){ echo "------------复制org5节点的包文件-------------------" cd "${chainmaker_path}/build/release" #1. 复制org1的节点目录 cp -r "chainmaker-$current_version-wx-org1.chainmaker.org" "chainmaker-$current_version-wx-org5.chainmaker.org" #2. 把chainmaker-*-wx-org5.chainmaker.org/bin下所有的.sh脚本中所有wx-org1.chainmaker.org替换为wx-org5.chainmaker.org" cd chainmaker-*-wx-org5.chainmaker.org/ sed -i 's/org1/org5/g' bin/start.sh sed -i 's/org1/org5/g' bin/stop.sh sed -i 's/org1/org5/g' bin/restart.sh sed -i 's/org1/org5/g' bin/run.sh #3.删除data和log rm -rf data/* rm -rf log/* # 4. config/下的org1目录重命名为org5 mv config/wx-org1.chainmaker.org config/wx-org5.chainmaker.org } ``` 以上方法执行后,会在build/release下生成新的节点目录: ```sh chainmaker-go/build/release]# ll drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org1.chainmaker.org drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org2.chainmaker.org drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org3.chainmaker.org drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org4.chainmaker.org drwxr-xr-x 7 root root 4096 Jun 28 20:14 chainmaker-v2.2.1-wx-org5.chainmaker.org ``` - 更新节点目录下的证书: 在第2步中,我们只对节点目录中对应的名称进行了替换,未将org5的证书放在目录 中,因此需要将在第1步生成的org5的证书复制过来 ```sh update_cert(){ # 使用chainmaker-cryptogen生成的wx-org5.chainmaker.org下的node和user分别覆盖掉wx-org5.chainmaker.org/config/wx-org5.chainmaker.org/certs下的node和user" crypto_cert=${cryptogen_path}/bin/crypto-config/wx-org5.chainmaker.org chainmaker_cert=${chainmaker_path}/build/release/chainmaker-*-wx-org5.chainmaker.org/config/wx-org5.chainmaker.org/certs cp -rf $crypto_cert/user $chainmaker_cert cp -rf $crypto_cert/node $chainmaker_cert } ``` - 修改org5的节点配置文件和链配置文件 ```sh update_config(){ echo "----------------修改org5的chainmaker.yml----------------" # 1. 把wx-org5.chainmaker.org/config/wx-org5.chainmaker.org/chainmaker.yml中所有wx-org1.chainmaker.org替换为wx-org5.chainmaker.org sed -i 's/org1/org5/g' config/wx-org5.chainmaker.org/chainmaker.yml # 2. 修改net模块,把 listen_addr: /ip4/0.0.0.0/tcp/11301 修改为 listen_addr: /ip4/0.0.0.0/tcp/11305" old_config="/ip4/0.0.0.0/tcp/11301" new_config="/ip4/0.0.0.0/tcp/11305" sed -i "s%${old_config}\+%${new_config}%g" config/wx-org5.chainmaker.org/chainmaker.yml sed -i 's/12301/12305/g' config/wx-org5.chainmaker.org/chainmaker.yml sed -i 's/14321/14325/g' config/wx-org5.chainmaker.org/chainmaker.yml sed -i 's/24321/24325/g' config/wx-org5.chainmaker.org/chainmaker.yml # 3. 如果是新增同步节点,将consensus证书改成common证书,如果新增的是共识节点,这一步略过。 # sed -i 's/consensus1/common1/g' config/wx-org5.chainmaker.org/chainmaker.yml echo "----------------修改org5的bc1.yml----------------" # 4. 修改chainmaker-*-wx-org5.chainmaker.org/config/wx-org5.chainmaker.org/chainconfig/bc1.yml中的trust_roots模块 # 把所有 ../config/wx-org1.chainmaker.org 修改为 ../config/wx-org5.chainmaker.org sed -i "s/wx-org1.chainmaker.org\/certs\/ca/wx-org5.chainmaker.org\/certs\/ca/g" config/wx-org5.chainmaker.org/chainconfig/bc1.yml } ``` - 如果使用cmc命令行需要更新相应的证书文件 ```sh update_cmc_cert(){ crypto_cert=${cryptogen_path}/bin/crypto-config cmc_cert=${chainmaker_path}/tools/cmc/testdata/ ls $crypto_cert ls $cmc_cert cp -rf $crypto_cert $cmc_cert } ``` - 调用以上方法完成节点目录的生成 ```sh gen_new_cert copy_node_file update_cert update_config update_cmc_cert ``` ### 添加组织根证书 如果新的节点证书是基于新的组织根证书(例如org5的ca证书)签发的,则需要添加组织根证书。 如果新的节点证书是基于旧的组织根证书(例如org1的ca证书)签发的,则不需要这一步。 [使用cmc添加组织根证书](../dev/命令行工具.html#chainConfig.addOrgRootCA) ```shell ./cmc client chainconfig trustroot add \ --sdk-conf-path=./testdata/sdk_config.yml \ --org-id=wx-org1.chainmaker.org \ --user-tlscrt-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \ --user-tlskey-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \ --user-signcrt-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.sign.crt \ --user-signkey-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.sign.key \ --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.tls.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.tls.crt \ --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.tls.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.tls.key \ --trust-root-org-id=wx-org5.chainmaker.org \ --sync-result=true \ --trust-root-path=./testdata/crypto-config/wx-org5.chainmaker.org/ca/ca.crt ``` ### 启动节点 添加trustroot之后,节点就可以做为同步节点加入网络,启动节点使区块同步到最新高度,就可以使用后续的操作步骤加入共识: ```sh chainmaker-go/build/release/chainmaker-v2.2.1-wx-org5.chainmaker.org/bin]# ./start.sh ``` ### 添加共识org: [使用cmc添加共识节点](../dev/命令行工具.html#chainConfig.addConsensusNodeOrg) (为新加入的组织添加共识节点) 添加共识org的作用: 1. 添加参与共识的组织( 即将org5添加到共识组织列表中) 2. 添加org5组织下的节点nodeid 如果是添加了新的组织org5,要将组织以及组织下的节点(org5_node1) 添加到共识当中,则需要执行这一步 如果是在原有组织or1-org4的基础上,扩展新的共识节点(例如org1原来有1个共识节点org1_node1,需要加入org1_node2也做为共识节点,则不需要这一步,直接执行下面步骤。 ```sh ./cmc client chainconfig consensusnodeorg add \ --sdk-conf-path=./testdata/sdk_config.yml \ --org-id=wx-org1.chainmaker.org \ --user-tlscrt-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \ --user-tlskey-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \ --user-signcrt-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.sign.crt \ --user-signkey-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.sign.key \ --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.tls.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.tls.crt \ --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.tls.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.tls.key \ --node-ids=QmaGii9BS7tWpkXTb9Z5Bbvw43bjt1Jnc4C2U68NnAm28b \ --sync-result=true \ --node-org-id=wx-org5.chainmaker.org ``` 添加成功后,可查看log/system.log如下关键信息 ```sh cat system.log |grep "validator.go" cat system.log |grep "new validator set" ``` ### 添加共识节点ID 为已经加入共识的组织,例如or1-org4, 以及执行过和3步的组织,添加更多的共识节点 ```sh ./cmc client chainconfig consensusnodeid add \ --sdk-conf-path=./testdata/sdk_config.yml \ --org-id=wx-org1.chainmaker.org \ --user-tlscrt-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.crt \ --user-tlskey-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.tls.key \ --user-signcrt-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.sign.crt \ --user-signkey-file-path=./testdata/crypto-config/wx-org1.chainmaker.org/user/client1/client1.sign.key \ --admin-crt-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.crt,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.tls.crt,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.tls.crt \ --admin-key-file-paths=./testdata/crypto-config/wx-org1.chainmaker.org/user/admin1/admin1.tls.key,./testdata/crypto-config/wx-org2.chainmaker.org/user/admin1/admin1.tls.key,./testdata/crypto-config/wx-org3.chainmaker.org/user/admin1/admin1.tls.key \ --node-id=QmaGii9BS7tWpkXTb9Z5Bbvw43bjt1Jnc4C2U68NnAm28b \ --sync-result=true \ --node-org-id=wx-org5.chainmaker.org ``` 添加成功后,可查看log/system.log如下关键信息 ```sh cat system.log*|grep "addedValidators" ``` ## 使用docker部署chainmaker并连接docker-vm “长安链·ChainMaker”支持Docker-go合约开发,Docker-go合约运行在独立Docker VM容器中,本文将介绍长安链使用docker方式部署时,与Docker-vm通信的几种部署方式。 ### 使用docker方式部署ChainMaker: ```sh cd chainmaker-go # 清空旧的构建数据 rm -rf build make docker-build docker images ``` ### 准备链需要的配置文件 参考 [在工作目录下 使用脚本搭建](../tutorial/通过命令行工具启动链.html#runUseScripts),使用脚本生成docker需要的节点配置文件 ```sh cd chainmaker-go/scripts ./prepare_pk.sh 4 1 ./build_release.sh ./cluster_quick_start.sh ./cluster_quick_stop.sh ``` ### 复制配置文件到chainmaker docker能读取的位置 docker启动时,默认加载如下路径的配置:chainmaker-go/scripts/docker/config/four-nodes ```sh cd chainmaker-go/scripts/docker/config/four-nodes cp -r ../../../../build/release/chainmaker-v2.2.1-wx-org1.chainmaker.org/config/wx-org1.chainmaker.org ./ cp -r ../../../../build/release/chainmaker-v2.2.1-wx-org2.chainmaker.org/config/wx-org2.chainmaker.org ./ cp -r ../../../../build/release/chainmaker-v2.2.1-wx-org3.chainmaker.org/config/wx-org3.chainmaker.org ./ cp -r ../../../../build/release/chainmaker-v2.2.1-wx-org4.chainmaker.org/config/wx-org4.chainmaker.org ./ ``` ### 修改节点ip地址: - 场景一:一台host启动4个chainmaker docker node 需要将配置文件中的ip换成docker容器的ip - 分别打开四个节点的chainmaker文件: ```sh # 查看容器ip ipv4_address: chainmaker-go/scripts/docker] vim four-nodes.docker-compose.yml # 修改chainmaker.yml的配置 chainmaker-go/scripts/docker/config/four-nodes/wx-org1.chainmaker.org] vim chainmaker.yml ``` - 找到如chainmaker.yml的如下位置 ```yaml seeds: - "/ip4/127.0.0.1/tcp/11301/p2p/XXX" - "/ip4/127.0.0.1/tcp/11302/p2p/XXX" - "/ip4/127.0.0.1/tcp/11303/p2p/XXX" - "/ip4/127.0.0.1/tcp/11304/p2p/XXX" ``` - 两种修改方式任选其一 第一种:使用four-nodes.docker-compose.yml中配置的容器ip ```yaml seeds: - "/ip4/172.48.1.11/tcp/11301/p2p/XXX" - "/ip4/172.48.1.12/tcp/11302/p2p/XXX" - "/ip4/172.48.1.13/tcp/11303/p2p/XXX" - "/ip4/172.48.1.14/tcp/11304/p2p/XXX" ``` 第二种:使用four-nodes.docker-compose.yml中配置的容器名 ```yaml seeds: - "/dns/cm-node1/tcp/11301/p2p/XXX" - "/dns/cm-node2/tcp/11302/p2p/XXX" - "/dns/cm-node3/tcp/11303/p2p/XXX" - "/dns/cm-node4/tcp/11304/p2p/XXX" ``` - 场景二:四台host启动4个chainmaker docker node 参考如上修改方式,ip修改为四台host的ip ### 修改docker-vm相关配置 “长安链·ChainMaker”V2.2.1之后,在节点配置文件chainmaker.yml中关于docker的两种连接方式对应的配置为: 第一种:本地的socket文件 ``` uds_open: true ``` 第二种:tcp , **当chainmaker使用docker方式部署时,推荐使用这种配置** ``` uds_open: false ``` - 场景一:chainmaker以【docker】方式部署,docker-vm与chainmaker-vm部署在【不同的】host : 假设:A(192.168.0.9)机器上启动了chainmaker 的docker容器, B(192.168.0.78)机器上启动了对应的docker-vm ```sh uds_open: false docker_vm_host: 192.168.0.78 docker_vm_port: 22351 ``` - 场景二:chainmaker以【docker】方式部署,docker-vm与chainmaker-vm部署在【同一台】host: 假设:A机器上启动了chainmaker的docker容器,同时启动对应的docker-vm 由于docker-vm和chainmaker在同一台host下,需要保证两个docker环境在使用同一个网桥的情况下ip在同一网段,即处在同一局域网内,例如使用如下命令启动docker-vm ```sh docker run -d -p22351:22359 --network docker_localnet --ip 172.48.1.21 --privileged chainmakerofficial/chainmaker-vm-docker-go:v2.2.1 ``` 配置文件修改时,注意端口号为-p22351:22359中的后者, 并且ip 为上面指定的ip ```sh uds_open: false docker_vm_host: 172.48.1.21 docker_vm_port: 22359 ``` - 场景三:chainmaker以【进程方式】部署,docker-vm与chainmaker部署在【不同的】host: ```shell uds_open: false docker_vm_host: 192.168.0.78 docker_vm_port: 22351 ``` - 场景四:chainmaker以进程方式部署, ocker-vm与chainmaker部署在【同一台】host: ```sh uds_open: false docker_vm_host: 127.0.0.1 docker_vm_port: 22351 ```