本次介绍chaincode的部署
背景阅读
- 本文针对V0.6.1版本
- chaincode与validator通过shim layer交互
- chaincode vm启动后向validator注册,validator回应registered或者error
- validator通过shim layer调用chaincode vm的init,invoke,query方法
- chaincode.mode dev 为开发模式本地命令行运行
- chaincode.mode net 为用docker启动container运行
单个validator和单个membersrvc场景
membersrvc:
image: hyperledger/fabric-membersrvc
ports:
- "7054:7054"
command: membersrvc
vp0:
image: hyperledger/fabric-peer
ports:
- "7050:7050"
- "7051:7051"
- "7053:7053"
environment:
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_VM_ENDPOINT=unix:///var/run/docker.sock
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_ID=vp0
- CORE_PEER_PKI_ECA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TCA_PADDR=membersrvc:7054
- CORE_PEER_PKI_TLSCA_PADDR=membersrvc:7054
- CORE_SECURITY_ENABLED=true
- CORE_SECURITY_ENROLLID=test_vp0
- CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT
links:
- membersrvc
command: sh -c "sleep 5; peer node start --peer-chaincodedev"
分析
- 上述docker-compose中command: sh -c “sleep 5; peer node start –peer-chaincodedev”指定了chaincode.mode
#src/github.com/hyperledger/fabric/peer/node/start.go Line71...
func serve(args []string) error {
// Parameter overrides must be processed before any paramaters are
// cached. Failures to cache cause the server to terminate immediately.
if chaincodeDevMode {
logger.Info("Running in chaincode development mode")
logger.Info("Set consensus to NOOPS and user starts chaincode")
logger.Info("Disable loading validity system chaincode")
// 节点验证开启
viper.Set("peer.validator.enabled", "true")
// 开发模式默认共识机制采用noops
viper.Set("peer.validator.consensus", "noops")
// 如果定义dev模式,则chaincode在命令行中运行,若为net则在容器中运行
viper.Set("chaincode.mode", chaincode.DevModeUserRunsChaincode)
}
...
#chaincodeDevMode的值在56行通过--peer-chaincodedev 解析获得
- dev这种模式下通过peer chaincode deploy… 执行validator不会去寻找chaincode的实际字节
- docker-compose.yml中将容器的7051映射到宿主机的7051,所以按照如果你的环境是HOST->VM->CONTAINER则在HOST访问VM的7051,
来简历chaincode和validator的连接进行注册 - 官方教程是编译chaincode为可执行程序
- 设置chaincode注册需要的环境变量
- CORE_CHAINCODE_ID_NAME=mycc chaincode的id
- CORE_PEER_ADDRESS=192.168.78.128:7051 validator的地址
- 注册成功日志输出类似
16:03:36.547 [shim] DEBU : Peer address: 192.168.78.128:7051
16:03:36.548 [shim] DEBU : os.Args returns: [chaincode-example.exe]
16:03:36.549 [shim] DEBU : Registering.. sending REGISTER
16:03:36.550 [shim] DEBU : []Received message REGISTERED from shim
16:03:36.550 [shim] DEBU : []Handling ChaincodeMessage of type: REGISTERED(state:created)
16:03:36.550 [shim] DEBU : Received REGISTERED, ready for invocations
- 此时可以在peer上通过peer chaincode deploy/invoke/query 等进行部署
peer network login jim -p 6avZQLwcUe9b
peer chaincode deploy -u jim -l golang -n mycc -c '{"Args": ["init", "a","100", "b", "200"]}'
peer chaincode invoke -u jim -l golang -n mycc -c '{"Args": ["transfer", "a", "b", "10"]}'
peer chaincode query -u jim -l golang -n mycc -c '{ "Args": ["query", "a"]}'
peer chaincode query -u jim -l golang -n mycc -c '{"Args": ["query", "b"]}'
多个validator和单个membersrvc场景
- src/github.com/hyperledger/fabric/bddtests/bdd-docker里面有多重场景的docker-compose文件
- 我们分析docker-compose-4-consensus-batch.yml
membersrvc0:
extends:
file: compose-defaults.yml
service: membersrvc
vp0:
extends:
file: docker-compose-4-consensus-base.yml
service: vpBatch
environment:
- CORE_PEER_ID=vp0
- CORE_SECURITY_ENROLLID=test_vp0
- CORE_SECURITY_ENROLLSECRET=MwYpmSRjupbT
links:
- membersrvc0
#笔者编辑增加
ports:
- 7050:7050
- 7051:7051
vp1:
extends:
file: docker-compose-4-consensus-base.yml
service: vpBatch
environment:
- CORE_PEER_ID=vp1
- CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051
- CORE_SECURITY_ENROLLID=test_vp1
- CORE_SECURITY_ENROLLSECRET=5wgHK9qqYaPy
links:
- membersrvc0
- vp0
#笔者编辑增加
ports:
- 8051:7051
vp2:
extends:
file: docker-compose-4-consensus-base.yml
service: vpBatch
environment:
- CORE_PEER_ID=vp2
- CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051
- CORE_SECURITY_ENROLLID=test_vp2
- CORE_SECURITY_ENROLLSECRET=vQelbRvja7cJ
links:
- membersrvc0
- vp0
#笔者编辑增加
ports:
- 9051:7051
vp3:
extends:
file: docker-compose-4-consensus-base.yml
service: vpBatch
environment:
- CORE_PEER_ID=vp3
- CORE_PEER_DISCOVERY_ROOTNODE=vp0:7051
- CORE_SECURITY_ENROLLID=test_vp3
- CORE_SECURITY_ENROLLSECRET=9LKqKH5peurL
- CORE_PBFT_GENERAL_BYZANTINE=true
links:
- membersrvc0
- vp0
#笔者编辑增加
ports:
- 10051:7051
- 基础文件compose-defaults.yml
vp:
image: hyperledger/fabric-peer
environment:
- CORE_PEER_ADDRESSAUTODETECT=true
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# 此处为笔者新增,如果不增加默认采用net方式需要在节点启动docker
- CORE_CHAINCODE_MODE=dev
# TODO: This is currently required due to BUG in variant logic based upon log level.
- CORE_LOGGING_LEVEL=DEBUG
# Script will wait until membersrvc is up (if it exists) before starting
# $$GOPATH (double dollar) required to prevent docker-compose doing its own
# substitution before the value gets to the container
command: sh -c "exec $$GOPATH/src/github.com/hyperledger/fabric/bddtests/scripts/start-peer.sh"
# Ideally we'd only mount /var/run/docker.sock but v1.5.2 of docker-compose
# does not have to capability to mount individual files. Hence we mount the
# entire folder in specific folder and specify it explicitly above.
# This issue seems to be sorted in docker-compose 1.8.0 however that requires
# Docker 1.10 and CI isn't at that version yet.
volumes:
- /var/run/:/host/var/run/
# Use these options if coverage desired for peers
#image: hyperledger/fabric-peer-coverage
#command: ./peer.test --test.coverprofile=coverage.cov node start
membersrvc:
image: hyperledger/fabric-membersrvc
command: membersrvc
分析
- 笔者通过把4个peer的7051映射成为VM的7051,8051,9051,10051后续要在HOST上用chaincode可执行程序向这些端口进行注册
- vp0的7050端口映射到VM的7051方便REST调用
- 在HOST上4个terminal分别执行chaincode可执行程序简历gRPC连接进行注册
- 在VM上peer chaincode invoke… 观察HOST上日志输出
- 在HOST利用工具进行REST调用测试
- 192.168.78.128:7050/chain
- 192.168.78.128:7050/chain/blocks/0 创世块
- 192.168.78.128:7050/chain/blocks/1 Deploy TX txid为chaincode name id
- 192.168.78.128:7050/chain/blocks/2 交易转账 txid 45b56d3a-0a8a-4492-b527-5cc7b1eb6551 交易类型2
- 192.168.78.128:7050/transactions/45b56d3a-0a8a-4492-b527-5cc7b1eb6551 交易类型2
- 192.168.78.128:7050/network/peers 节点查询
{
"peers": [
{
"ID": {
"name": "vp2"
},
"address": "172.17.0.6:7051",
"type": 1,
"pkiID": "9jECmCLyUr1U4yN43WhpasW+hGLpbBXwQXJnCyxomcs="
},
{
"ID": {
"name": "vp3"
},
"address": "172.17.0.4:7051",
"type": 1,
"pkiID": "ply0tf7n0o2e7MDmoGwyK2Rg6XuO+Zv8oBV5vGQi/H0="
},
{
"ID": {
"name": "vp1"
},
"address": "172.17.0.5:7051",
"type": 1,
"pkiID": "iNrePYrAiWxbmlFoquQwT5gGgmy7rLgutAeAAkjHvnk="
},
{
"ID": {
"name": "vp0"
},
"address": "172.17.0.3:7051",
"type": 1,
"pkiID": "xTMo31jTxS0e1D2Rums6RaCCDonYouXyjI0mGZqzCdg="
}
]
}
peer chaincode deploy/invoke/query
- src/github.com/hyperledger/fabric/peer/chaincode/deploy.go 执行主程序,获取参数、peerCient进行调用peer method
- src/github.com/hyperledger/fabric/peer/node/start.go Line 71 peer node start –peer-chaincodedev 指定chaincode.mode
- src/github.com/hyperledger/fabric/core/devops.go peerClient 调用实际执行内容,会根据chaincode.mode进行相关调用
小结
- 笔者在初始测试多validator时发生peer chaincode deploy 代码分析后发现chaincode.mode参数
- chaincode.mode dev 开发模式,chaincode通过手动运行注册到validator
- chaincode.mode net chaincode通过docker运行【本文未介绍】