手动搭建一个fabric网络二
启动容器
根据之前编写的配置文件docker-compose-cli.yaml
启动容器
$ docker-compose -f docker-compose-cli.yaml up -d
注意:-f docker-compose-cli.yaml
是指定配置文件,如果不加会报错
检测所有的节点是否正常启动了
$ docker-compose -f docker-compose-cli.yaml ps
启动容器之后做的事情
- 创建通道
- 只需要做一次 -> 得到通道文件
- peer节点加入到通道中
- 所有peer都需要加入到通道
- 给peer节点安装链码
- 所有的peer节点都需要安装链码
- 给链码初始化
- 在任意一个已经安装好链码的节点上做一次
- 测试
- 数据查询
- 数据写操作
创建通道
进入到客户端容器
$ docker exec -it cli bash
创建通道
$ peer channel create [flags], 常用参数为:
`-o, --orderer: 创建通道的时候需要orderer参与, 指定orderer节点的地址: orderer.itcast.com:7050
`-c, --channelID: 通道的名字, 在configtxgen的时候指定的 channelID
# 之前生成channel时的命令: configtxgen -profile Channel -outputCreateChannelTx channel.tx -channelID itcastchannel
`-f, --file: 创建通道的时候, 加载的文件, 通过configtxgen命令生成的
`--tls: 执行这个命令通信的时候, 是不是需要加密, 如果指定了这个参数就是加密
`--cafile: tls加密的时候, 使用的证书, 这个证书是orderer节点的, 如何找?, 这个文件要使用绝对路径
# ordererOrganizations/order组织目录/orderers/orderer节点的目录/msp/tlscacerts/tlsca.itcast.com-cert.pem
具体命令:
#定义一个cafile变量,之后用的时候取值就行
cafile=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/itcast.com/orderers/orderer.itcast.com/msp/tlscacerts/tlsca.itcast.com-cert.pem
peer channel create -o orderer.itcast.com:7050 -c itcastchannel -f ./channel-artifacts/channel.tx --tls --cafile $cafile
创建通道时可能会出现的问题:
# 错误1
Error: got unexpected status: BAD_REQUEST -- error authorizing update: error validating ReadSet: readset expected key [Group] /Channel/Application at version 0, but got version 1
# 原因: 通道已经创建出来了, 再次创建该通道
# 第一个启动了一个网络, 关闭(容器也销毁了), 再次启动网络, 创建通道
# 第一次启动网络生成的数据保存在了挂载是数据卷目录, 这些目录没有被删除
# 先关闭当前网络 -> 所有的容器都销毁了
# 删除 没有被删除的数据卷: docker volume prune -> 删除所有缓存的数据卷
# 错误2
error validating DeltaSet: policy for [Group] /Channel/Application not satisfied: Failed to reach implicit threshold of 1 sub-policies, required 1 remaining
# 原因
# 这个问题的原因是用configtxgen生成创始块的时候,配置文件configtx.yaml指定了错误的msp目录。 导致生成
# 的区块中包含的证书其它用户的证书。
# 重新生成证书和创始区块/通道文件
cryptogen generate --config xxx.yaml
configtxgen -profile ......
# 错误3
Error: failed to create deliver client: orderer client failed to connect to myorderer.itcast.com:7050: failed to create new connection: context deadline exceeded
# 原因: 连接 myorderer.itcast.com 失败, 是因为这个域名解析失败了,这是没有部署在同一台主机上引起的错误
# 需要通过 extra_hosts声明该域名如何被解析
# extra_hosts:
# - "myorderer.itcast.com:192.168.247.203"
加入通道
# 验证客户端操作的节点有没有加入到通道中
# 通过客户端将网络中节点 - peer 加入到通道中
# 当前网络中所有peer节点都需要加入到通道中, 都是通过客户端操作来完成的
$ peer channel join[flags], 常用参数为:
`-b, --blockpath: 指定通过peer channel create 命令生成的这个个xxx.block文件的路径
具体命令:
$ peer channel join -b ./itcastchannel.block
验证是否加入:
$ peer channel list
更新锚节点(如不更新可跳过)
# 注意事项:
# 更新go组织的锚节点, 当前客户端应该连接到go组织的某个peer节点上
# 当前组织的锚节点发生变化的时候, 才需要更新
# 每个组织的锚节点更新需要依次做
$ peer channel update [flags], 常用参数为:
`-o, --orderer:
创建通道的时候需要orderer参与, 指定orderer节点的地址: myorderer.itcast.con:7050
`-c, --channelID: 通道的名字, 在configtxgen的时候指定的 channelID
`-f, --file: 更新锚节点的文件, 通过configtxgen命令生成的
`--tls: 执行这个命令通信的时候, 是不是需要加密, 如果指定了这个参数就是加密
`--cafile: tls加密的时候, 使用的证书, 这个证书是orderer节点的, 如何找?, 这个文件要使用绝对路径
orderer组织/orderers/当前orderer节点的目录/msp/tlscacerts/tlsca.itcast.com-cert.pem
# 命令
cafile=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/itcast.com/orderers/orderer.itcast.com/msp/tlscacerts/tlsca.itcast.com-cert.pem
# 更新go组织锚节点
peer channel update -o orderer.itcast.com:7050 -c itcastchannel -f ./channel-artifacts/goAnchor.tx --tls --cafile $cafile
# 更新cpp组织锚节点
peer channel update -o orderer.itcast.com:7050 -c itcastchannel -f ./channel-artifacts/cppAnchor.tx --tls --cafile $cafile
安装链码
使用源代码直接安装
# 每个peer节点都需要安装链码, 链码安装完成, peer节点才能根据业务逻辑对账本进程操作
$ peer chaincode install [flags], 常用参数为:
`-l, --lang: 链码的语言
go: golang, 链码的语言默认的go, 如果链码是go写的, 可以忽略该参数
node.js: node
java: java
`-n, --name: 安装完成之后的链码的名字, 随便起名
`-p, --path: 要安装的链码的文件的路径(程序存储的目录)
链码go写的: gopath/src, 使用相对路径就可以了相对于: gopath/src目录
node/java: 使用绝对路径
`-v, --version: 链码的版本, 随便
具体命令:
peer chaincode install -n itcastcc -p github.com/chaincode -v 1.0
将源代码打包, 使用打包之后得到的文件进行安装
# 链码的打包
$ peer chaincode package [flags] 打包之后的文件名(生成的文件)
`-l, --lang: 链码的语言
`-n, --name: 安装完成之后的链码的名字, 随便起名
`-p, --path: 要安装的链码的文件的路径(程序存储的目录)
`-v, --version: 链码的版本, 随便
具体命令:
$ peer chaincode package -n itcastcc -v 1.0 -p github.com/chaincode chaincode.out
得到文件–>>chaincode.out
链码安装:
$ peer chaincode install chaincode.out
链码初始化
背书策略
背书策略: 交易的执行流程, 过程中有多种交易方式, 其中的某一种方式称之为策略
举例: 现在有两个组织, 进行交易, 对应的交易方式有多少种?
- go组织
- peer0.go
- peer1.go
- cpp组织
- peer0.cpp
- peer1.cpp
方式:
- go组织和cpp组织的所有的peer节点都参与
- go组织和cpp组织的部分的peer节点都参与
- 只有go组织的节点参与
- 只有cpp组织的节点参与
在命令中如何指定背书策略:
-
如何表示某一个组织:
- 通过这组织的组织ID来表示
-
如何表示这个组织中的成员
- 普通成员:
- 组织ID.member -> 表示的是一类, 不是一个
- 管理员:
- 组织ID.admin
- 普通成员:
-
如果表示组织和组织之间的逻辑关系:
- 都需要参与: AND
- 至少有一个组织要参与: OR
-
背书策略示例1
# 按照该背书规则进行交易, 必须通过组织Org1MSP,Org2MSP,Org3MSP中的用户共同验证交易才能生效 "AND ('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member')"
-
背书策略示例2
# 按照该背书规则进行交易,只需要通过组织 Org1MSP 或 Org2MSP 或 Org3MSP 中的任何一个成员验证,即可生效 "OR ('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member')"
-
背书策略示例3
# 按照该背书规则进行交易,有三种办法让交易生效 # 1. 组织Org1MSP中的某个成员对交易进行验证。 # 2. 组织Org2MSP和组织Org3MSP中的成员共同就交易进行验证。 # 3. 组织Org1MSP和Org2MSP和组织Org3MSP中的成员共同就交易进行验证。 "OR ('Org1MSP.member', AND('Org2MSP.member', 'Org3MSP.member'))" # 按照该背书规则进行交易,有三种办法让交易生效 # 1. 组织Org1MSP中的某个成员和组织Org3MSP中的某个成员共同就交易进行验证。 # 2. 组织Org1MSP中的某个成员和组织Org2MSP中的某个成员共同就交易进行验证。 # 3. 组织Org1MSP和Org2MSP和组织Org3MSP中的成员共同就交易进行验证。 "AND ('Org1MSP.member', OR('Org2MSP.member', 'Org3MSP.member'))"
链码初始化
$ peer chaincode instantiate [flags], 常用参数为:
`-o, --orderer: orderer节点的地址, myorderer.itcast.com:7050
`-C,--channelID:当前节点加入的通道的名字
`-v,--version:链码的版本号
`-l,--lang:链码语言, 默认的go
`-n,--name:链码的名字
`-c, --ctor:初始化链码数据的代码(json格式), 给链码传参
-c '{"Args":["init", "a", "100", "b", "200"]}'
`-P,--policy:背书策略(交易的规则)
`--tls: 是不是需要通信加密
`--cafile: 加密时候需要使用的证书, orderer节点的
#orderer组织/orderers/当前orderer节点的目录/msp/tlscacerts/tlsca.itcast.com-cert.pem
具体命令:
cafile=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/itcast.com/orderers/orderer.itcast.com/msp/tlscacerts/tlsca.itcast.com-cert.pem
peer chaincode instantiate -o orderer.itcast.com:7050 -C itcastchannel -n itcastcc -v 1.0 -c '{"Args":["init", "a", "100", "b", "200"]}' -P "AND('OrgGoMSP.member', 'OrgCppMSP.member')" --tls --cafile $cafile
链码初始化只用做一次,在对其他节点进行读写操作时会把链码同步到哪个节点
查询数据
$ peer chaincode query [flags], 常用参数为:
`-n,--name:Chaincode的名字。
`-C,--channelID:当前命令运行的通道,默认值是“testchainid"
`-c, --ctor:JSON格式的构造参数,默认值是“{}"
具体命令:
$ peer chaincode query -n itcastcc -C itcastchannel -c '{"Args":["query", "a"]}'
交易
- leader节点(主节点)
- 也是一个图通的peer节点
- 一个组织内部只有一个leader节点
- 代表当前组织和orderer节点进行通信
- 将orderer打包之后的区块, 拿到当前组织中
- leader节点将拿到的区块在当前组织内部进行分发, 当前组织中的各个peer都拿到了这个区块
- 背书节点(Endorse Peer)
- peer节点
- 参与模拟交易的节点
- 由客户端动态指定的
- 锚节点(Anchor Peer)
- 和其他组织进行通信
- Commit Peer
- 向Order提交数据
交易
# 指定的背书策略, 根据规则进行模拟交易
-P "AND('OrgGoMSP.member', 'OrgCppMSP.member')"
# 这个调用, 客户端发起的
# 调用 Invoke 的函数
$ peer chaincode invoke [flags], 常用参数为:
`-o, --orderer: orderer节点的地址: 域名/IP:端口
`-C,--channelID:通道名称
`-c, --ctor:json格式的调用->给链码传参
'{"Args":["invoke", "a", "b", "25"]}'
`-n,--name:链码的名字
`--tls: 通信是不是加密
`--cafile: 加密通信时候orderer节点的证书
# 背书策略: -P "AND('OrgGoMSP.member', 'OrgCppMSP.member')"
`--peerAddresses: 指定背书节点, peer节点的地址:端口 -> peer0.orggo.itcast.com:7051
`--tlsRootCertFiles: 背书节点使用的tls根证书, 使用绝对路径
#peerOrganizations/参与交易的节点所属的组织的组织目录/peers/参与交易的节点的节点目录/tls/ca.crt
具体命令:
# 命令
goca=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer0.orggo.itcast.com/tls/ca.crt
cppca=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/peers/peer1.orgcpp.itcast.com/tls/ca.crt
cafile=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/itcast.com/orderers/orderer.itcast.com/msp/tlscacerts/tlsca.itcast.com-cert.pem
peer chaincode invoke -o orderer.itcast.com:7050 -C itcastchannel -c '{"Args":["invoke", "a", "b", "25"]}' -n itcastcc --tls --cafile $cafile --peerAddresses peer0.orggo.itcast.com:7051 --tlsRootCertFiles $goca --peerAddresses peer1.orgcpp.itcast.com:7051 --tlsRootCertFiles $cppca
注意:如果交易不满足背书策略,交易是不会成功的
通过客户端切换操作的节点
进入客户端容器
$ docker exec -it cli bash
# 客户端默认会连接某一个节点
CORE_PEER_ADDRESS=peer0.orggo.itcast.com:7051
# 对客户端进行操作, 操作的是默认连接的节点
# 看docker-compose 配置文件中关于 客户端容器的设置 -> 环境变量
- CORE_PEER_ADDRESS=peer0.orggo.itcast.com:7051 # 客户端连接的peer节点
- CORE_PEER_LOCALMSPID=OrgGoMSP
- CORE_PEER_TLS_ENABLED=true
- CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer0.orggo.itcast.com/tls/server.crt
- CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer0.orggo.itcast.com/tls/server.key
- CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer0.orggo.itcast.com/tls/ca.crt
- CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/users/Admin@orggo.itcast.com/msp
-
go组织的peer0
CORE_PEER_ADDRESS=peer0.orggo.itcast.com:7051 CORE_PEER_LOCALMSPID=OrgGoMSP CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/users/Admin@orggo.itcast.com/msp CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer0.orggo.itcast.com/tls/ca.crt CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer0.orggo.itcast.com/tls/server.crt CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer0.orggo.itcast.com/tls/server.key
-
go组织的peer1
CORE_PEER_ADDRESS=peer1.orggo.itcast.com:7051 CORE_PEER_LOCALMSPID=OrgGoMSP CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/users/Admin@orggo.itcast.com/msp CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer1.orggo.itcast.com/tls/ca.crt CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer1.orggo.itcast.com/tls/server.crt CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orggo.itcast.com/peers/peer1.orggo.itcast.com/tls/server.key
-
cpp组织的peer0
CORE_PEER_ADDRESS=peer0.orgcpp.itcast.com:7051 CORE_PEER_LOCALMSPID=OrgCppMSP CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/users/Admin@orgcpp.itcast.com/msp CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/peers/peer0.orgcpp.itcast.com/tls/ca.crt CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/peers/peer0.orgcpp.itcast.com/tls/server.crt CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/peers/peer0.orgcpp.itcast.com/tls/server.key
-
cpp组织的peer1
CORE_PEER_ADDRESS=peer1.orgcpp.itcast.com:7051 CORE_PEER_LOCALMSPID=OrgCppMSP CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/users/Admin@orgcpp.itcast.com/msp CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/peers/peer1.orgcpp.itcast.com/tls/ca.crt CORE_PEER_TLS_CERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/peers/peer1.orgcpp.itcast.com/tls/server.crt CORE_PEER_TLS_KEY_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/orgcpp.itcast.com/peers/peer1.orgcpp.itcast.com/tls/server.key