Fabric实战(1) - 基础篇,基于byfn的Commercial Paper案例

转自独立博客simplexity.cn

之前分享过Fabric官网Commercial Paper案例chaincode的golang实现,现在基于官网Building Your First Network再次记录过程,同时添加部分新操作及分析,以此作为以后的进阶实战基础。

  1. 使用命令./byfn.sh up启动网络

  2. 查看配置文件/fabric-samples/first-network/docker-compose-cli.yaml,可见cli的挂载volume设置

cli:
  volume:
    - ./../chaincode/:/opt/gopath/src/github.com/chaincode
  1. 将编写的chaincode源文件放置在该挂载的路径/chaincode/go
cp commercial_paper.go /chaincode/go
cp paper.go /chaincode/go
  1. docker exec -it cli bash登入容器cli
- 执行peer chaincode install -n commercialpaper -v 0 -p github.com/chaincode/commercial_paper/go
- 执行echo $CORE_PEER_MSPCONFIGPATH。可见当前角色为admin
    ---
    /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/users/[email protected]/msp
- 执行peer chaincode list -C mychannel --installed
    ---
    Get installed chaincodes on peer:
    Name: commercialpaper, Version: 0, Path: github.com/chaincode/commercial_paper/go, Id: f033307bf72f876fb5a95883d53ed5209e6639386e21361eed65f459d8a9f276
  1. 登入peer0.org1.example.com(容器cli内CORE_PEER_ADDRESS=peer0.org1.example.com:7051,也就是其endorser节点)
- 执行ll var/hyperledger/production/chaincodes,存在文件commercialpaper.0(即${chaincodeName}.${version})
- 执行peer chaincode list -C mychannel --installed
    ---
    Error: Bad response: 500 - access denied for [getinstalledchaincodes]: Failed verifying that proposal's creator satisfies local MSP principal during channelless check policy with policy [Admins]: [This identity is not an admin]
实际上,`docker inspect peer0.org1.example.com`:
```
"HostConfig": {
    "Binds": [
        "/Users/meitu/Project/github/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls:rw",
        "/Users/meitu/Project/github/fabric-samples/first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp:rw",
        "/var/run:/host/var/run:rw",
        "net_peer0.org1.example.com:/var/hyperledger/production:rw"
    ],
}
```
没有将[email protected]/msp挂载进来,当然可以修改启动配置文件`base/docker-compose-base.yaml`,或者后续添加到挂载的volume上,设置$CORE_PEER_MSPCONFIGPATH指向挂载的路径也可以赋予权限访问  
  1. 查看/fabric-samples/first-network/scripts/路径下script.shutil.sh,包含设置CORE_PEER_LOCALMSPID=(“Org1MSP”/“Org2MSP”)

  2. cli执行chaincode instantiate

peer chaincode instantiate -n commercialpaper -v 0 -c '{"Args":[]}' -C mychannel -P "AND ('Org1MSP.member') \
--tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem"

env
---
OLDPWD=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts

peer0.org1.example.com:
2019-10-22 14:28:19.931 UTC [endorser] callChaincode -> INFO 1e62ef [mychannel][3156a1b7] Entry chaincode: name:"lscc"
2019-10-22 14:28:19.936 UTC [endorser] callChaincode -> INFO 1e630e [mychannel][3156a1b7] Exit chaincode: name:"lscc"  (5ms)
2019-10-22 14:28:19.940 UTC [comm.grpc.server] 1 -> INFO 1e631b unary call completed {"grpc.start_time": "2019-10-22T14:28:19.927Z", "grpc.service": "protos.Endorser", "grpc.method": "ProcessProposal", "grpc.peer_address": "172.25.0.7:51012", "grpc.code": "OK", "grpc.call_duration": "12.4301ms"}
2019-10-22 14:28:21.993 UTC [gossip.privdata] StoreBlock -> INFO 1e647d [mychannel] Received block [5] from buffer
2019-10-22 14:28:22.022 UTC [committer.txvalidator] Validate -> INFO 1e64c9 [mychannel] Validated block [5] in 28ms
2019-10-22 14:28:22.033 UTC [cceventmgmt] HandleStateUpdates -> INFO 1e64db Channel [mychannel]: Handling deploy or update of chaincode [commercialpaper]
2019-10-22 14:28:22.065 UTC [kvledger] CommitWithPvtData -> INFO 1e6506 [mychannel] Committed block [5] with 1 transaction(s) in 40ms (state_validation=15ms block_commit=18ms state_commit=4ms)
2019-10-22 14:28:31.257 UTC [endorser] callChaincode -> INFO 1e6ed6 [mychannel][b206b359] Entry chaincode: name:"lscc"
2019-10-22 14:28:31.262 UTC [endorser] callChaincode -> INFO 1e6efc [mychannel][b206b359] Exit chaincode: name:"lscc"  (4ms)
2019-10-22 14:28:31.263 UTC [comm.grpc.server] 1 -> INFO 1e6f09 unary call completed {"grpc.start_time": "2019-10-22T14:28:31.255Z", "grpc.service": "protos.Endorser", "grpc.method": "ProcessProposal", "grpc.peer_address": "172.25.0.4:55986", "grpc.code": "OK", "grpc.call_duration": "7.5554ms"}

peer1.org1.example.com:
2019-10-22 14:28:22.009 UTC [gossip.privdata] StoreBlock -> INFO 1e0540 [mychannel] Received block [5] from buffer
2019-10-22 14:28:22.011 UTC [committer.txvalidator] Validate -> INFO 1e0588 [mychannel] Validated block [5] in 2ms
2019-10-22 14:28:22.017 UTC [cceventmgmt] HandleStateUpdates -> INFO 1e05a0 Channel [mychannel]: Handling deploy or update of chaincode [commercialpaper]
2019-10-22 14:28:22.018 UTC [ccprovider] ExtractStatedbArtifactsForChaincode -> INFO 1e05a3 Error while loading installation package for ccname=commercialpaper, ccversion=0. Err=open /var/hyperledger/production/chaincodes/commercialpaper.0: no such file or directory
2019-10-22 14:28:22.018 UTC [cceventmgmt] HandleChaincodeDeploy -> INFO 1e05a4 Channel [mychannel]: Chaincode [Name=commercialpaper, Version=0, Hash=[]byte{0xf0, 0x33, 0x30, 0x7b, 0xf7, 0x2f, 0x87, 0x6f, 0xb5, 0xa9, 0x58, 0x83, 0xd5, 0x3e, 0xd5, 0x20, 0x9e, 0x66, 0x39, 0x38, 0x6e, 0x21, 0x36, 0x1e, 0xed, 0x65, 0xf4, 0x59, 0xd8, 0xa9, 0xf2, 0x76}] is not installed hence no need to create chaincode artifacts for endorsement
2019-10-22 14:28:22.041 UTC [kvledger] CommitWithPvtData -> INFO 1e05c1 [mychannel] Committed block [5] with 1 transaction(s) in 27ms (state_validation=5ms block_commit=13ms state_commit=6ms)

orderer:
2019-10-22 14:28:19.969 UTC [comm.grpc.server] 1 -> INFO 027 streaming call completed {"grpc.start_time": "2019-10-22T14:28:19.947Z", "grpc.service": "orderer.AtomicBroadcast", "grpc.method": "Broadcast", "grpc.peer_address": "172.25.0.7:53034", "grpc.code": "OK", "grpc.call_duration": "23.1002ms"}
  • peer1.org1.example.com上没有install这个chaincode
  1. cli执行peer chaincode invoke -c '{"Args":["issue","MagnetoCorp", "00001", "2020-05-31", "2020-11-30", "5000000"]}' -C mychannel -n commercialpaper",失败。看日志是cli与orderer之间tls失败
    cli:
    Error: error sending transaction for invoke: could not send: EOF - proposal response: version:1 response: payload:"\n /!\373\020OI\024\270_1\267\251\332\337\037 $\370\347\356\004aEXZ\345\332/\366|'7\022\306\003\n\204\002\022\340\001\n\017commercialpaper\022\314\001\n\022\n\020MagnetoCorp00004\032\265\001\n\020MagnetoCorp00004\032\240\001{\"PaperNumber\":\"00004\",\"Issuer\":\"MagnetoCorp\",\"Owner\":\"MagnetoCorp\",\"IssueDateTime\":\"2020-05-31\",\"MaturityDateTime\":\"2020-11-30\",\"FaceValue\":5000000,\"Status\":0}\022\037\n\004lscc\022\027\n\025\n\017commercialpaper\022\002\010\005\032\246\001\010\310\001\032\240\001{\"PaperNumber\":\"00004\",\"Issuer\":\"MagnetoCorp\",\"Owner\":\"MagnetoCorp\",\"IssueDateTime\":\"2020-05-31\",\"MaturityDateTime\":\"2020-11-30\",\"FaceValue\":5000000,\"Status\":0}\"\024\022\017commercialpaper\032\0010" endorsement:\203\215-\204\257 \304*\367sL9\223\207\233\312\351\277\270LR\231\236&\002 )\331\334\006\025\214\337\355\262\252\305\345\214\315ae\3527\317y\274\336\352oX\037F\220\3036%\025" >
    
    orderer: 
    2019-10-22 15:58:14.380 UTC [core.comm] ServerHandshake -> ERRO 034 TLS handshake failed with error tls: first record does not look like a TLS handshake {"server": "Orderer", "remote address": "172.25.0.7:53104"}
    2019-10-22 15:58:15.383 UTC [core.comm] ServerHandshake -> ERRO 035 TLS handshake failed with error tls: first record does not look like a TLS handshake {"server": "Orderer", "remote address": "172.25.0.7:53106"}
    
    peer0.org1.example.com:
    2019-10-22 15:58:15.391 UTC [endorser] callChaincode -> INFO 2c3af6 [mychannel][89d96407] Entry chaincode: name:"commercialpaper"
    2019-10-22 15:58:15.398 UTC [endorser] callChaincode -> INFO 2c3b04 [mychannel][89d96407] Exit chaincode: name:"commercialpaper"  (7ms)
    2019-10-22 15:58:15.398 UTC [comm.grpc.server] 1 -> INFO 2c3b11 unary call completed {"grpc.start_time": "2019-10-22T15:58:15.389Z", "grpc.service": "protos.Endorser", "grpc.method": "ProcessProposal", "grpc.peer_address": "172.25.0.7:51082", "grpc.code": "OK", "grpc.call_duration": "9.4211ms"}
    
  2. cli执行chaincode invoke
peer chaincode invoke -c '{"Args":["issue","MagnetoCorp", "00001", "2020-05-31", "2020-11-30", "5000000"]}' -C mychannel -n commercialpaper \
--tls true --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem

cli:
2019-10-22 15:55:07.564 UTC [chaincodeCmd] chaincodeInvokeOrQuery -> INFO 0c9 Chaincode invoke successful. result: status:200 payload:"{\"PaperNumber\":\"00003\",\"Issuer\":\"MagnetoCorp\",\"Owner\":\"MagnetoCorp\",\"IssueDateTime\":\"2020-05-31\",\"MaturityDateTime\":\"2020-11-30\",\"FaceValue\":5000000,\"Status\":0}"

peer0.org1.example.com:
2019-10-22 15:55:07.497 UTC [endorser] callChaincode -> INFO 2ba6d0 [][7b225797] Entry chaincode: name:"cscc"
2019-10-22 15:55:07.502 UTC [endorser] callChaincode -> INFO 2ba6ec [][7b225797] Exit chaincode: name:"cscc"  (5ms)
2019-10-22 15:55:07.502 UTC [comm.grpc.server] 1 -> INFO 2ba6ef unary call completed {"grpc.start_time": "2019-10-22T15:55:07.494Z", "grpc.service": "protos.Endorser", "grpc.method": "ProcessProposal", "grpc.peer_address": "172.25.0.7:51076", "grpc.code": "OK", "grpc.call_duration": "7.6522ms"}
2019-10-22 15:55:07.553 UTC [endorser] callChaincode -> INFO 2ba716 [mychannel][443bff3e] Entry chaincode: name:"commercialpaper"
2019-10-22 15:55:07.557 UTC [endorser] callChaincode -> INFO 2ba724 [mychannel][443bff3e] Exit chaincode: name:"commercialpaper"  (4ms)
2019-10-22 15:55:07.559 UTC [comm.grpc.server] 1 -> INFO 2ba731 unary call completed {"grpc.start_time": "2019-10-22T15:55:07.545Z", "grpc.service": "protos.Endorser", "grpc.method": "ProcessProposal", "grpc.peer_address": "172.25.0.7:51076", "grpc.code": "OK", "grpc.call_duration": "14.7305ms"}
2019-10-22 15:55:09.574 UTC [gossip.privdata] StoreBlock -> INFO 2ba941 [mychannel] Received block [8] from buffer
2019-10-22 15:55:09.584 UTC [committer.txvalidator] Validate -> INFO 2ba96b [mychannel] Validated block [8] in 9ms
2019-10-22 15:55:09.619 UTC [kvledger] CommitWithPvtData -> INFO 2ba99e [mychannel] Committed block [8] with 1 transaction(s) in 33ms (state_validation=19ms block_commit=7ms state_commit=5ms)

orderer:
2019-10-22 15:55:07.569 UTC [orderer.common.broadcast] Handle -> WARN 032 Error reading from 172.25.0.7:53098: rpc error: code = Canceled desc = context canceled
2019-10-22 15:55:07.569 UTC [comm.grpc.server] 1 -> INFO 033 streaming call completed {"grpc.start_time": "2019-10-22T15:55:07.545Z", "grpc.service": "orderer.AtomicBroadcast", "grpc.method": "Broadcast", "grpc.peer_address": "172.25.0.7:53098", "error": "rpc error: code = Canceled desc = context canceled", "grpc.code": "Canceled", "grpc.call_duration": "24.1982ms"}
  • 从peer0.org1.example.com日志可见,先后调用了cscc(system chaincode。 调用GetConfigBlock方法,获取channel config,从而获取orderer地址提供给cli建立orderer client)和commercialpaper。后续收到orderer传来的block后再验证和提交本地。

  • docker network inspect net_byfn,发现 172.25.0.7 <-> cli
    登入cli,netstat -anp如下。估计是端口过早关闭

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.11:35373        0.0.0.0:*               LISTEN      -
udp        0      0 127.0.0.11:36128        0.0.0.0:*
  1. peer0.org1.example.com/cli执行
peer chaincode list -C mychannel --instantiated
---
Get instantiated chaincodes on channel mychannel:
Name: commercialpaper, Version: 0, Path: github.com/chaincode/commercial_paper/go, Escc: escc, Vscc: vscc
  1. cli执行chaincode query
peer chaincode query -c '{"Args":["query","MagnetoCorp", "00001"]}' -C mychannel -n commercialpaper
  1. 当前commeicialpaper只install在peer0.org1.example.com,此时cli执行
CORE_PEER_ADDRESS=peer1.org1.example.com:8051
peer chaincode query -c '{"Args":["query","MagnetoCorp", "00001"]}' -C mychannel -n commercialpaper
---
Error: endorsement failure during query. response: status:500 message:"cannot retrieve package for chaincode commercialpaper/0, error open /var/hyperledger/production/chaincodes/commercialpaper.0: no such file or directory"
  1. cli在peer1.org1.example.com:8051上chaincode install,并且chaincode query
peer chaincode query -c '{"Args":["query","MagnetoCorp", "00001"]}' -C mychannel -n commercialpaper \
--peerAddresses peer1.org1.example.com:8051 \
--tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/server.crt
或者(`CORE_PEER_TLS_ROOTCERT_FILE`可不修改,因为同org相同的ca证书)
CORE_PEER_ADDRESS=peer1.org1.example.com:8051
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt
peer chaincode install -n commercialpaper -v 0 -p github.com/chaincode/commercial_paper/go
peer chaincode query -c '{"Args":["query","MagnetoCorp", "00001"]}' -C mychannel -n commercialpaper

---
{"PaperNumber":"00001","Issuer":"MagnetoCorp","Owner":"MagnetoCorp","IssueDateTime":"2020-05-31","MaturityDateTime":"2020-11-30","FaceValue":5000000,"Status":0}

peer1.org1.example.com:
2019-10-23 04:43:39.847 UTC [endorser] callChaincode -> INFO 5078dd [][e21cf78b] Entry chaincode: name:"lscc"
2019-10-23 04:43:39.891 UTC [lscc] executeInstall -> INFO 5078ea Installed Chaincode [commercialpaper] Version [0] to peer
2019-10-23 04:43:39.892 UTC [endorser] callChaincode -> INFO 5078ee [][e21cf78b] Exit chaincode: name:"lscc"  (45ms)
2019-10-23 04:43:39.892 UTC [comm.grpc.server] 1 -> INFO 5078f1 unary call completed {"grpc.start_time": "2019-10-23T04:43:39.846Z", "grpc.service": "protos.Endorser", "grpc.method": "ProcessProposal", "grpc.peer_address": "172.25.0.7:50220", "grpc.code": "OK", "grpc.call_duration": "46.0634ms"}
2019-10-23 04:43:54.861 UTC [endorser] callChaincode -> INFO 5084f7 [mychannel][b060b92a] Entry chaincode: name:"commercialpaper"
2019-10-23 04:43:54.914 UTC [chaincode.platform.golang] GenerateDockerBuild -> INFO 508508 building chaincode with ldflagsOpt: '-ldflags "-linkmode external -extldflags '-static'"'
2019-10-23 04:44:19.578 UTC [endorser] callChaincode -> INFO 509732 [mychannel][b060b92a] Exit chaincode: name:"commercialpaper"  (24751ms)
2019-10-23 04:44:19.581 UTC [comm.grpc.server] 1 -> INFO 50973f unary call completed {"grpc.start_time": "2019-10-23T04:43:54.857Z", "grpc.service": "protos.Endorser", "grpc.method": "ProcessProposal", "grpc.peer_address": "172.25.0.7:50224", "grpc.code": "OK", "grpc.call_duration": "24.7588062s"}

orderer日志无变化
  • 此时docker ps,新启动了容器dev-peer1.org1.example.com-commercialpaper-0

    Fabric Documents: If you want additional peers to interact with ledger, then you will need to join them to the channel, and install the same name, version and language of the chaincode source onto the appropriate peer’s filesystem. A chaincode container will be launched for each peer as soon as they try to interact with that specific chaincode. Again, be cognizant of the fact that the Node.js images will be slower to compile.

  1. 以下对peer0.org2.example.com节点重复实验(从属不同的org)。在cli容器install/invoke chaincode。
peer chaincode install -n commercialpaper -v 0 -p github.com/chaincode/commercial_paper/go \ 
--peerAddresses peer0.org2.example.com:9051 \
--tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/server.crt
* 指定--peerAddresses和--tlsRootCertFiles参数。或者修改环境变量(对应关系)
CORE_PEER_ADDRESS=peer0.org2.example.com:9051
CORE_PEER_TLS_ROOTCERT_FILE=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt
peer chaincode install -n commercialpaper -v 0 -p github.com/chaincode/commercial_paper/go

---报错
Error: error getting channel (mychannel) orderer endpoint: error endorsing GetConfigBlock: rpc error: code = Unknown desc = access denied: channel [] creator org [Org1MSP]
  • 这是因为CORE_PEER_LOCALMSPIDCORE_PEER_MSPCONFIGPATH这两个参数的设置使当前cli的msp证书从属于Org1。修改使用Org2的msp以及Admin或者User角色即可
CORE_PEER_LOCALMSPID=Org2MSP
CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/[email protected]/msp
peer chaincode install -n commercialpaper -v 0 -p github.com/chaincode/commercial_paper/go \ 
--peerAddresses peer0.org2.example.com:9051 \
--tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/

Ref.

分步详解 Fabric 区块链网络的部署 : IBM员工,相当棒的系列实践文章

你可能感兴趣的:(HyperLedger,Fabric)