工作原因需要调研一下chainmaker官网https://www.chainmaker.org
优势
- 社会背景复杂,传说中的国家队
- 有一个在使用的案例《北京冷链》
- TPS过万满足绝大使用场景,得益于DAG 并发交易执行
- 架构简约,功能简单利益学习
- 开源
不足点
- 起步相对较晚,配套工具不完善,缺少CA服务(官方不久后会发布CA服务)
- 完善技术文档
由于刚开源所以有些文档描述并不正确,所以主要从SDK角度来学习一下chainmaker
先看官方架构介绍https://git.chainmaker.org.cn/chainmaker/chainmaker-docs/-/blob/master/ChainMaker_User_Manual.md#user-content-整体架构
chainmaker共识目前具有solo,TBFT。solo模式用于测试,这里主要以TBFT为主
证书生成
chainmaker用户体系采用CA证书,
-
下载工具
git clone --recursive https://git.chainmaker.org.cn/chainmaker/chainmaker-cryptogen.git
chainmaker-cryptogen是证书生成工具 -
进入
cd chainmaker-cryptogen/src
执行go build
编译,编译成功如图
使用./chainmaker-cryptogen generate -c ../config/crypto_config_template.yml
生成的证书文件在crypto-config
,其中crypto_config_template.yml为配置文件,修改如下我们生成5个组织
最终生成的证书集合如下
打开一个文件看下
其中ca文件夹里存放的是ca证书,user文件夹主要是放着普通用户和管理员用户,node文件夹分为2种,common是node作为同步节点时使用的证书,consensus是node作为参与共识的节点时使用的证书,其中nodeid为libp2p格式下面会用到
注 当前项目还不能新增组织,只能通过chainmaker-cryptogen extend
来新增用户,所以需要等官方出CA服务
配置创世块
- 配置创世块的文件夹结构不是唯一的 ,这里主要是我为了方便docker-compose使用采用的项目结构
-
certs 证书
- ca 文件夹存放所有参与共识的节点的ca
- node user 文件夹就是工具生成的文件夹
-
chainconfig 里bc1.yml为创世块配置文件 里面的讲解看注释好了
#
# Copyright (C) BABEC. All rights reserved.
# Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
chain_id: chain1 # 链标识
version: v1.0.0 # 链版本
sequence: 1 # 配置版本
auth_type: "identity" # 认证类型
crypto:
hash: SHA256
# 交易、区块相关配置
block:
tx_timestamp_verify: true # 是否需要开启交易时间戳校验
tx_timeout: 600 # 交易时间戳的过期时间(秒)
block_tx_capacity: 100 # 区块中最大交易数
block_size: 10 # 区块最大限制,单位MB
block_interval: 2000 # 出块间隔,单位:ms
# core模块
core:
tx_scheduler_timeout: 10 # [0, 60] 交易调度器从交易池拿到交易后, 进行调度的时间
tx_scheduler_validate_timeout: 10 # [0, 60] 交易调度器从区块中拿到交易后, 进行验证的超时时间
#共识配置
consensus:
# 共识类型(0-SOLO,1-TBFT,2-MBFT,3-HOTSTUFF,4-RAFT,10-POW)
type: 1
# 共识节点列表,组织必须出现在trust_roots的org_id中,每个组织可配置多个共识节点,节点地址采用libp2p格式
# 10.190.28.222 是我本机IP 这里采用4个节点的TBFT共识
nodes:
- org_id: "wx-org1.chainmaker.org"
address:
- "/ip4/10.190.28.222/tcp/11301/p2p/QmeXXfQgh3yAyA7gvHut3fR96GTucZZsTg92SC64WnV2WX"
- org_id: "wx-org2.chainmaker.org"
address:
- "/ip4/10.190.28.222/tcp/11302/p2p/QmfBAtFNRdiFSGM6mLU1eir7TUA2YtQT5sxBLdWKeZ9vCY"
- org_id: "wx-org3.chainmaker.org"
address:
- "/ip4/10.190.28.222/tcp/11303/p2p/QmX12zQJgWjtKuwZbLgi1Ub6udYKBqWonQZz9uKzaDyTY5"
- org_id: "wx-org4.chainmaker.org"
address:
- "/ip4/10.190.28.222/tcp/11304/p2p/QmWSCTAnJz3mgz6WVWUknFFVpNmQmGGupwBDYii4adUn56"
ext_config: # 扩展字段,记录难度、奖励等其他类共识算法配置
- key: aa
value: chain01_ext11
# 信任组织和根证书 只有参与共识的节点才需要,同步节点不需要
trust_roots:
- org_id: "wx-org1.chainmaker.org"
root: "./certs/ca/wx-org1.chainmaker.org/ca.crt"
- org_id: "wx-org2.chainmaker.org"
root: "./certs/ca/wx-org2.chainmaker.org/ca.crt"
- org_id: "wx-org3.chainmaker.org"
root: "./certs/ca/wx-org3.chainmaker.org/ca.crt"
- org_id: "wx-org4.chainmaker.org"
root: "./certs/ca/wx-org4.chainmaker.org/ca.crt"
# 权限配置(只能整体添加、修改、删除)
resource_policies:
- resource_name: NODE_ADDR_UPDATE
policy:
rule: SELF # 规则(ANY,MAJORITY...,全部大写,自动转大写)
org_list: # 组织名称(组织名称,区分大小写)
role_list: # 角色名称(role,自动转大写)
- admin
- resource_name: TRUST_ROOT_UPDATE
policy:
rule: SELF # 规则(ANY,MAJORITY...,全部大写)
org_list: # 组织名称(组织名称)
role_list: # 角色名称(role,自动转大写)
- admin
- resource_name: CONSENSUS_EXT_DELETE
policy:
rule: MAJORITY
org_list:
role_list:
- admin
- resource_name: BLOCK_UPDATE
policy:
rule: ANY
org_list:
role_list:
- admin
- client
- resource_name: INIT_CONTRACT
policy:
rule: ANY
org_list:
role_list:
- resource_name: UPGRADE_CONTRACT
policy:
rule: ANY
org_list:
role_list:
- resource_name: FREEZE_CONTRACT
policy:
rule: ANY
org_list:
role_list:
- resource_name: UNFREEZE_CONTRACT
policy:
rule: ANY
org_list:
role_list:
- resource_name: REVOKE_CONTRACT
policy:
rule: ANY
org_list:
role_list:
- chainmaker.yml 链配置文件
#
# Copyright (C) BABEC. All rights reserved.
# Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
log:
config_file: ./log.yml # config file of logger configuration.
blockchain:
- chainId: chain1 # 链名称
genesis: ./chainconfig/bc1.yml # 他的创世块配置
node:
# 节点类型:full、spv
type: full
org_id: wx-org1.chainmaker.org
priv_key_file: ./certs/node/consensus1/consensus1.sign.key # 节点私钥
cert_file: ./certs/node/consensus1/consensus1.sign.crt #节点证书
signer_cache_size: 1000
cert_cache_size: 1000
pkcs11:
enabled: false
library: # path to the so file of pkcs11 interface
label: # label for the slot to be used
password: # password to logon the HSM
session_cache_size: 10 # size of HSM session cache, default to 10
hash: "SHA256" # hash algorithm used to compute SKI
net:
provider: LibP2P
listen_addr: /ip4/0.0.0.0/tcp/11301
tls:
enabled: true
priv_key_file: ./certs/node/consensus1/consensus1.tls.key
cert_file: ./certs/node/consensus1/consensus1.tls.crt
txpool:
max_txpool_size: 50000 # 普通交易池上限
max_config_txpool_size: 10 # config交易池的上限
full_notify_again_time: 30 # 交易池溢出后,再次通知的时间间隔(秒)
batch_max_size: 30000 # 批次最大大小
batch_create_timeout: 200 # 创建批次超时时间,单位毫秒
rpc:
provider: grpc
port: 12301
# 检查链配置TrustRoots证书变化时间间隔,单位:s,最小值为10s
check_chain_conf_trust_roots_change_interval: 60
ratelimit:
# 每秒补充令牌数,取值:-1-不受限;0-默认值(10000)
token_per_second: -1
# 令牌桶大小,取值:-1-不受限;0-默认值(10000)
token_bucket_size: -1
subscriber:
# 历史消息订阅流控,实时消息订阅不会进行流控
ratelimit:
# 每秒补充令牌数,取值:-1-不受限;0-默认值(1000)
token_per_second: 100
# 令牌桶大小,取值:-1-不受限;0-默认值(1000)
token_bucket_size: 100
tls:
# TLS模式:
# disable - 不启用TLS
# oneway - 单向认证
# twoway - 双向认证
#mode: disable
#mode: oneway
mode: twoway
priv_key_file: ./certs/node/consensus1/consensus1.tls.key
cert_file: ./certs/node/consensus1/consensus1.tls.crt
monitor:
enabled: true
port: 14321
pprof:
enabled: false
port: 24321
storage: # 区块链数据存放路径
provider: LevelDB
store_path: ./data/ledgerData
debug:
# 是否开启CLI功能,过度期间使用
is_cli_open: true
is_http_open: false
use_batch_tx_pool: false
is_extreme: false
use_net_msg_compression: false
is_net_insecurity: false
- log.yml 日志配置文件
#
# Copyright (C) BABEC. All rights reserved.
# Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
log:
system:
log_level_default: INFO
log_levels:
core: INFO
net: INFO
file_path: ./log/system.log
max_age: 365 # 日志最长保存时间,单位:天
rotation_time: 1 # 日志滚动时间,单位:小时
log_in_console: true # 是否展示日志到终端,仅限于调试使用
show_color: true # 是否打印颜色日志
brief:
log_level_default: INFO
file_path: ./log/brief.log
max_age: 365 # 日志最长保存时间,单位:天
rotation_time: 1 # 日志滚动时间,单位:小时
log_in_console: true # 是否展示日志到终端,仅限于调试使用
show_color: true # 是否打印颜色日志
event:
log_level_default: INFO
file_path: ./log/event.log
max_age: 365 # 日志最长保存时间,单位:天
rotation_time: 1 # 日志滚动间隔,单位:小时
log_in_console: true # 是否展示日志到终端,仅限于调试使用
show_color: true # 是否打印颜色日志
- docker-compose.yml 配置文件
#
# Copyright IBM Corp All Rights Reserved
#
# SPDX-License-Identifier: Apache-2.0
#
version: '2'
networks:
basic:
services:
chainmaker5:
# restart: on-failure #on-failure:5 最多重启5次
image: littlegirlpppp/chainmaker:v0.5.0
tty: true
container_name: chainmaker5
working_dir: /chainmaker-go
command: chainmaker start
volumes:
- ./certs/:/chainmaker-go/certs
- ./chainconfig/:/chainmaker-go/chainconfig
- ./chainmaker.yml:/chainmaker-go/chainmaker.yml
- ./log.yml:/chainmaker-go/log.yml
- ./data/:/chainmaker-go/data
networks:
- basic
ports:
- 11305:11305
- 12305:12305
- 14325:14325
- start.sh 启动docker-compose
#!/bin/bash
set -ev
export MSYS_NO_PATHCONV=1
docker-compose -f docker-compose.yml up -d chainmaker
docker ps
其他几个组织依次配置,端口号不能冲突
注意 所有参与共识的创世块配置必须一致,因为只要相同的创世块才能加入到同一条链中 即所有的bc1.yml复制成一样的
- 下载镜像
docker pull littlegirlpppp/chainmaker:v0.5.0
分别进入
依次执行./start 启动docker-compose。同过docker ps 会发现已经启动四个node节点如图
随便进入一个镜像 你会看到all necessary peers connected
2021-04-09 07:54:44.328 [INFO] [Net] p2p/libp2p_connection_supervisor.go:91 [ConnSupervisor] all necessary peers connected.
则表示基于TBFT的四个共识节点的 区块链网络搭建完成
使用SDK访问区块
如果你了解过fabric go SDK, 那么chainmaker SDK使用就非常简单,注释也非常详细 看一下是DEMO就可以了 感觉比文档更方便,当前文档还有很多是用旧版本的会报错,这里只有等官方更新文档了 ,SDK下载https://git.chainmaker.org.cn/chainmaker/chainmaker-sdk-go.git
//创建SDK客户端
client, err := createClientWithCertBytes()
if err!=nil{
}
//获取组织admin用户
admin1, err := createAdmin(orgId1)
admin2, err := createAdmin(orgId2)
admin3, err := createAdmin(orgId3)
admin4, err := createAdmin(orgId4)
contractName := "counter-go-11"
version := "1.0.0"
byteCodePath := "./main1.wasm"
//创建合约
UserContractCounterGoCreate(client, admin1, admin2, admin3, admin4, contractName,version,byteCodePath,true)
//调用合约
params:=make(map[string]string)
params["key"]="22222"
UserContractCounterGoInvoke(client,contractName,"add",params,true)
//查询合约
UserContractCounterGoQuery(client,contractName,"getdata",params)
这里说明一下 如果你使用go get
的方式安装SDK可能会遇到问题,我这里没有解决 所以我是把SDK clone到本地 用replace
方式去引用 具体使用可以看一下demo https://github.com/littlegirlpppp/chainmakerDemo.git
智能合约编写
智能合约我个人觉得 还是有很多需要改善的地方,下面说目前的智能合约编写和部署。
-
目前智能合约只支持wasm方式部署,chainmaker生成wasm方式是采用TinyGo第三方工具来生成,所以导致无法Debug,并且使用方法受到限制 比如不能使用json 因为TinyGo不支持,当然还有很多go功能TinyGo不支持
-
为了方便使用 官方提供了一个docker 镜像来方便我们使用TinyGo
拉镜像docker pull huzhenyuan/chainmaker-go-contract:1.0.0
-
创建目录用来存放合约
mkdir docker-go-contract
-
启动镜像
export work_path=/Users/sunbo/Desktop/ChainMaker/src/docker-go-contract docker run -it --name chainmaker-go-contract -v $work_path:/home huzhenyuan/chainmaker-go-contract:1.0.0 bash cd home tar xvf /data/contract_go_template.tar.gz cd contract_tinygo
- 此时回到本地 使用goland 打开docker-go-contract/contract_tinygo 如图
-
此时我们就可以编辑
main.go
了 其中chainmaker.go
就是能使用的合约方法,easycodec.go
提供一个简单的 输入json 转化的方法。所以合约功能目前很有限 -
编辑完成后,回到刚才运行的Docker容器里,
cd contract_tinygo/
此时能看到项目文件 如图tinygo build -no-debug -opt=s -o main.wasm -target wasm
使用tinygo 生成main.wasm
- 此时唯一的测试就是使用gasm命令的模拟一下invoke,让后靠输出来测试模式
gasm wasm名 方法名 参数 值 参数1 值1
如下
gasm main2.wasm add key 1111
ReadBytes len=559662021-04-09 09:52:44.829 [DEBUG] [Vm] waci/waci.go:41 waci log>> [1234567890123456789012345678901234567890123456789012345678901234] ssssssssss1111
2021-04-09 09:52:44.918 [DEBUG] [Vm] gasm/runtime.go:192 invoke gasm success, tx id:1234567890123456789012345678901234567890123456789012345678901234, gas cost 3400503,[IGNORE: ret [], retTypes []]
2021-04-09 09:52:44.930 [INFO] [Vm] @chain01 main/mian.go:28 contractResult :gas_used:3400503
其中 ssssssssss1111
就是输出
- 我使用的是go 所以在安装SDK 安装合约的时候 需要设置一下类型
//common.RuntimeType_GASM 为go Wasm 安装 官方demo使用的是rust安装
resp, err := createUserContract(client, admin1, admin2, admin3, admin4,
contractName, version, byteCodePath, common.RuntimeType_GASM, []*common.KeyValuePair{}, withSyncResult)
return resp,err
至此chainmaker SDK 入门基本完成,等chainmaker完成CA服务 和合约功能升级后 在继续
网友评论