如何通过长安链快速部署区块链系统
长安链从零到一源码部署
此处以centos7 chainmaker-v2.1.0 为例
长安链·ChainMaker官方文档:https://docs.chainmaker.org.cn/index.html 长安链·ChainMaker门户网站:https://chainmaker.org.cn/ 长安链·ChainMaker仓库地址:https://git.chainmaker.org.cn/
一、环境及概念
1.1、环境依赖
依赖软件以centos为例:
名称 | 用途 |
---|
git | 下载源码 https://git.chainmaker.org.cn/explore | docker | 智能合约编译环境(tinygo/rust/c++/solidity/golang) | golang | go语言编译环境 | gcc7.3+ | rust编译依赖 | 具有sudo权限的用户 | 安装依赖 |
1.2、相关概念
名称 | 说明 |
---|
区块(Block) | 区块是区块链中存储交易和交易相关的数据的单元,通常由区块头和区块体组成。 | 区块链(Blockchain) | 使用密码技术链接将共识确认过的区块按顺序追加而形成的分布式账本。 | 智能合约(SmartContract) | 以数字形式定义的能够自动执行条款的合约。 | 交易(Transaction) | 也称为事务,区块链上的一次原子性账本数据状态变更及其过程和结果记录。 | 交易哈希(TransactionHash) | 交易上链成功后,产生的唯一哈希值。 | 交易ID(TransactionId) | 交易的唯一ID,可由用户指定。 | | | chainmaker可执行文件 | 长安链项目chainmaker-go源码编译后生成的可执行二进制文件 执行make命令后将生成在chainmaker-go/bin目录下 | 长安链SDK(chainmaker sdk) | 用于与长安链交互(发送交易,订阅等)的软件开发工具 | 合约SDK(contract sdk) | 用于开发智能合约的软件开发工具,使编译的wasm文件可与长安链进行交互 | wasm文件(webassembly file) | 本文指长安链的智能合约编译后生成的文件。 wasm指通过各自符合WebAssembly规范的编译器编译出来的以.wasm结尾的文件。 c++: emmake make rust: wasm-pack build tinygo: tinygo build -no-debug -opt=s -o main.wasm -target wasm | 长安链CA | 指使用长安链配套证书管理工具chainmaker-cryptogen管理的密钥体系 |
二、环境安装
以centos7为例
2.1、配置sudo权限
sudo usermod -G admin -a taifu
2.2、修改源
cat /etc/yum.repos.d/CentOS-Base.repo
cd /etc/yum.repos.d/
sudo mv CentOS-Base.repo CentOS-Base.repo.bak
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sudo yum clean all
sudo yum makecache
2.3、安装git
sudo yum install git -y
git --version
2.4、安装golang
https://studygolang.com/dl
https://golang.org/doc/install
linux
wget https://studygolang.com/dl/golang/go1.16.13.linux-amd64.tar.gz
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.16.13.linux-amd64.tar.gz
sudo vim /etc/profile
export PATH=$PATH:/usr/local/go/bin
export GOROOT=/usr/local/go
export GOPATH=/home/taifu/go
export GOPROXY=https://goproxy.io,direct
source /etc/profile
go version
2.5、安装docker
docker version
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum list docker-ce --showduplicates | sort -r
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
sudo systemctl list-unit-files|grep docker
docker version
sudo groupadd docker
sudo gpasswd -a $USER docker
newgrp docker
sudo yum -y install bash-completion
source /etc/profile.d/bash_completion.sh
2.6、安装GLIBC_2.18【若运行时找不到glibc2.1.8则安装】
linux依赖
注意:GLIBC是GNU发布的libc库,即c运行库。glibc是linux系统中最底层的api,几乎其它任何运行库都会依赖于glibc,一旦安装失败系统将不可用,请谨慎操作。此处仅列举一种安装示例(在CentOS Linux release 7.6.1810安装成功),并不一定使用您的系统,请根据您的系统及gcc环境自行选择相应的安装方法。
ldd --version
strings /lib64/libc.so.6 | grep "^GLIBC_"
cd chainmaker-go/script/3rd
sh install.sh
2.7、安装GCC7.3+【若运行时gcc版本过低则安装】
通过安装devtoolset-7的方式间接升级为gcc7.x版本
gcc --version
yum install centos-release-scl
yum install devtoolset-7
scl enable devtoolset-7 bash
gcc --version
三、单机部署
3.1、下载源码
chainmaker-go官方git仓库:
https://git.chainmaker.org.cn
cd ~/workspace
git clone -b v2.1.0 https://git.chainmaker.org.cn/chainmaker/chainmaker-go.git
git clone -b v2.1.0 https://git.chainmaker.org.cn/chainmaker/chainmaker-cryptogen.git
3.2、编译证书管理工具
cd chainmaker-cryptogen
make
3.3、证书及配置文件生成
cd ../chainmaker-go/tools
ln -s ../../chainmaker-cryptogen/ .
cd ../scripts
pwd
./prepare.sh 4 1 11301 12301
tree -L 2 ../build/
tree -L 3 ../build/
3.4、编译及安装包制作
./build_release.sh
tree ../build/release/
3.5、启动
./cluster_quick_start.sh normal
./cluster_quick_stop.sh
3.6、查看启动情况
ps -ef|grep chainmaker | grep -v grep
netstat -lptn | grep "1230\|1130"
cat ../build/release/chainmaker-*/bin/panic.log
cat ../build/release/chainmaker*/log/system.log|grep "ERROR\|put block\|all necessary"
四、智能合约开发
见官方文档:1. 智能合约 — chainmaker-docs v2.1.0 documentation
4.1、拉取合约环境镜像
docker pull chainmakerofficial/chainmaker-go-contract:2.1.0
docker images
docker run -d --name chainmaker-go-contract -v ~/workspace/chainmaker-go-contract/:/home chainmakerofficial/chainmaker-go-contract:2.1.0 bash -c "while true; do echo hello world; sleep 5;done"
docker run -d --name chainmaker-go-contract -v /data/workspace/chainmaker-go-contract:/home chainmakerofficial/chainmaker-go-contract:2.1.0 bash -c "while true; do echo hello world; sleep 5;done"
4.2、编译合约
docker exec -it chainmaker-go-contract bash
cd /home/
tar xvf /data/contract_go_template.tar.gz
cd contract_tinygo
sh build.sh
/home/contract_tinygo/chainmaker-contract-go.wasm
五、部署合约
5.1、编译命令行工具
见官方文档: https://docs.chainmaker.org.cn/dev/%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7.html
实际生产系统还是用SDK方式:https://docs.chainmaker.org.cn/dev/SDK.html
cd ~/workspace
git clone -b v2.1.0 https://git.chainmaker.org.cn/chainmaker/chainmaker-go.git
cd chainmaker-go/tools/cmc
go mod tidy
go build
cp -r ~/workspace/chainmaker-go/build/crypto-config/ ./testdata
5.2、执行创建合约
./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.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 \
--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 \
--sync-result=true \
--params="{}"
5.3、执行合约方法
./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
5.4、查询合约
./cmc client contract user get \
--contract-name=fact \
--method=find_by_file_hash \
--sdk-conf-path=./testdata/sdk_config.yml \
--params="{\"file_hash\":\"ab3456df5799b87c77e7f88\"}"
六、常见问题
此处介绍部署、运行可能遇到的常见问题
6.1 编译时错误
编译chainmaker-go及chainmaker-cryptogen时可能出现的错误
unknown revision v2.0.0
Q:
go: chainmaker.org/chainmaker/pb-go@v2.0.0+incompatible: reading chainmaker.org/chainmker/pb-go/go.mod at revision v2.0.0: unknown revision v2.0.0
go: chainmaker.org/chainmaker/common@v2.0.0+incompatible: reading chainmaker.org/chainmker/common/go.mod at revision v2.0.0: unknown revision v2.0.0
go: chainmaker.org/chainmaker/protocol@v2.0.0+incompatible: reading chainmaker.org/chainmker/protocol/go.mod at revision v2.0.0: unknown revision v2.0.0
A:
原因:chainmaker.org域名可能记录为其他主机地址了,删除~/.ssh/known_hosts文件 重试即可
misssing go.sum entry
Q:
如果执行 ./build_release.sh 时或者在启动时报错:misssing go.sum entry: to add it,分别在 chainmaker-go chainmaker-go/tools/cmc 下执行 go mod tidy,执行完后再重试
A:
原因:go1.16 版本 执行go build时会自动下载依赖,会更新mod文档,在go 1.16版本这一行为被禁止了。想要安装、更新依赖只能使用go get, go mod download, go mod tidy等命令,go build和go test将不会再做这类工作。
在go1.16版本中,想要自动更新依赖可以使用 go build -mod=mod,
进入对应go.mod 文件所在目录执行go mod download
# chainmaker-go项目
cd chainmaker-go/main
go mod download
cd chainmaker-go/common
go mod download
cd chainmaker-go/tools/cmc
go mod download
# # chainmaker-cryptogen项目
cd chainmaker-cryptogen/src
go mod download
6.2 启动时错误
not found GLIBC_2.18
Q:
若出现错误./chainmaker: /lib64/libc.so.6: version GLIBC_2.18’ not found (required by /root/git-code/chainmaker-go/module/vm/wasmer/wasmer-go/libwasmer.so)`
A:
在linux下可进入chainmaker-go/scripts/3rd目录安装glibc-2.18.tar.gz依赖
# 注:此操作为安装替换GCC版本,请慎重操作。一旦出错系统将不可用。
cd scripts/3rd
sh install.sh
restart.sh 权限不足
Q:
[root@localhost scripts]# ./cluster_quick_start.sh normal ===> Staring chainmaker cluster START ==> /home/wx/chainmaker/chainmaker-go/build/release/chainmaker-v2.0.0-wx-org1.chainmaker.org ./cluster_quick_start.sh: line 51: ./restart.sh: Permission denied
A:
如果启动时出现restart.sh 权限不足问题,给restart.sh 增加执行权限
给项目源文件添加执行权限
cd chainmaker-go/script/bin
chmod +x *.sh
给部署文件添加执行权限
# 进入四个节点的bin目录下 执行下面命令(以第一个节点 org1 为例)
cd chainmaker-go/build/release/chainmaker-V2.0.0-wx-org1.chainmaker.org/bin
chmod +x *.sh
6.3 运行时错误
syscall/js.valueGet not exported
Q:
执行gasm合约时报错:resolve imports: syscall/js.valueGet not exported in module env
A:
tinygo不支持fmt等函数
runtime type error | byte code validation failed
Q:
发送交易成功,但链打印错误信息:contract invoke failed, runtime type error, expect rust:[2], but got 4。同时根据该交易id查询到交易错误信息。
failed to create vm runtime, contract: contract_test, [contract_test], byte code validation failed
A:
执行交易时异步的(查询类交易除外),返回的状态为链成功接收到交易的状态。执行合约是,runtimeType选择错误,需要根据自己的合约语言选择对应的runtimeType。
byte code validation failed:可能原因:1、运行类型错误;2、wasm文件损坏;3、wasm文件非官网指定渠道编译
语言 | 类型 |
---|
系统合约 | RuntimeType_NATIVE = 1 | rust | RuntimeType_WASMER = 2 | c++ | RuntimeType_WXVM = 3 | tinygo | RuntimeType_GASM = 4 | solidity | RuntimeType_EVM = 5 | golang | RuntimeType_DOCKER_GO = 6 |
返回成功,但实际执行失败
Q:
使用sdk执行安装、调用合约时,SDK 返回message为ok,但链和交易显示执行失败
A:
交易的执行是异步的。SDK返回的成功信息指的是链成功接收到该交易。
获取查看交易实际结果的方式:
- 根据txId查询该交易,解析出结果。
- 使用SDK是选择同步发送交易,等待执行结果。
6.4 其他关键信息
出块标记是什么
进入log目录,查看日志文件 筛选 put block 即可
cat system.log|grep "ERROR\|put block"
其中一行解释如下:
2021-11-04 15:55:06.351 [INFO] [Storage] @chain1 blockstore_impl.go:363 chain[chain1]: put block[1] (txs:1 bytes:15946), time used (mashal:0, log:1, blockdb:0, statedb:0, historydb:0, resultdb:0, contractdb:0, batchChan:0, total:1)
时间 [日志级别] [模块] @链名称 文件名.go:行数 链chain[链名称]:put block[区块高度](txs:交易个数 bytes:区块大小), 使用时间毫秒(mashal:0, log:1, blockdb:0, statedb:0, historydb:0, resultdb:0, contractdb:0, batchChan:0, total:1)
组网成功标记是什么
组网成功后,即可发送交易。此时接收到的交易将进入到交易池当中,并且会广播给网络的每一个节点(共识、同步节点、轻节点),随后等待共识成功选举leader开始打包区块。
启动成功日志:init blockchain[chain1] success
多节点时,组网成日志:all necessary peers connected
SOLO共识
cat system.log|grep "init blockchain\[chain1\] success"
其他多节点共识
cat system.log|grep "init blockchain\[chain1\] success\|all necessary peers connected"
七、多机部署
7.1、多机部署与单机部署区别
1、执行prepare.sh之前需要修改
配置指定端口(可不改)
配置指定IP
2、./prepare.sh
3、./build_release.sh
4、后续上传各节点安装包,到指定的服务器上,部署解压后使用。
5、进入解压文件夹 bin目录,执行 ./restart.sh
如果需要配置自拉起方式启动,请参考:【自拉起服务】
配置文件路径:chainmaker-go/config/config_tpl/chainmaker.yml
使用prepare.sh 脚本会自动生成端口号,如果实际环境需要固定端口,可以通过修改下面的配置,将{xxx} 修改为指定的端口,后续执行脚本时,就不会进行端口的修改。
rpc:
port: {rpc_port}
net:
listen_addr: /ip4/0.0.0.0/tcp/{net_port}
配置文件路径:chainmaker-go/config/config_tpl/bc_xxx.yml ,xxx 是节点数,根据需要,选择特定节点数的模板。
将127.0.0.1 修改为集群各个节点实际所在机器的IP地址。也可使用域名
consensus:
type: {consensus_type}
nodes:
- org_id: "{org1_id}"
address:
- "/ip4/127.0.0.1/tcp/{org1_port}/p2p/{org1_peerid}"
- org_id: "{org2_id}"
address:
- "/ip4/127.0.0.1/tcp/{org2_port}/p2p/{org2_peerid}"
- org_id: "{org3_id}"
address:
- "/ip4/127.0.0.1/tcp/{org3_port}/p2p/{org3_peerid}"
- org_id: "{org4_id}"
address:
- "/ip4/127.0.0.1/tcp/{org4_port}/p2p/{org4_peerid}"
7.2、单机&多机部署对照表
操作 | 单机 | 多机 |
---|
同步时间 | / | 手动同步时间,不需要太精确1分钟以内 | 下载源码 | git clone xxx-chainmaer-go git clone xxx-chainmaker-cryptogen | 一致 | 编译证书工具 | cd chainmaker-cryptogen make cd chainmaker-go/tools ln -s …/…/chainmaker-cryptogen/ . | 一致 | 进入脚本目录 | cd chainmaker-go/scripts | 一致 | 生成证书 | ./prepare.sh | chainmaker-go/config/config_tpl/chainmaker.yml 配置指定端口 chainmaker-go/config/config_tpl/bc_xxx.yml 配置指定IP ./prepare.sh | 生成节点安装包 | ./build_release.sh | 一致 | 启动节点 | ./cluster_quick_start.sh normal | 上传chainmaker-xxxx-x86_64.tar.gz到各自服务器 解压缩 进入到chainmaker-xxxx/bin目录 sh restart.sh | | | | | | |
|