1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。; ]( R9 n ?2 d+ G: W# O, S$ I
下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:
在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。
在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。. m: r( E" }1 [8 t& x) X
Fabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。
下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。
宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。
链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。) U* D: s3 c2 R% U6 {
安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。
机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。 z, d: w7 H- Z/ R& N
当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。% l/ b, a7 E/ Y% w
在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。
链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。
现在链码就可以使用了。( k6 [- {. I: i9 n2 q
2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。" S5 G5 z2 `+ U2 D6 }
First Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。
SACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。
好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。% ]# z* [# X. }$ v: C2 Y4 V
3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。) W# w6 N6 H/ N; Q4 ]0 i
下面是演示步骤:3 w% Y: r1 L+ L u3 S! }
无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:; h7 s, E! c, [8 \* R4 W
13 e6 U1 M3 S/ m D' `8 t3 j0 i 2 | cd fabric-samples/first-network3 @# W4 Q: Q( M# C/ Z ./byfn.sh up -n2 S: B7 M& O& Y ? |
现在我们可以开始链码部署操作。
STEP 2:在指定peer节点上安装链码# e1 h# z$ J! C5 [
这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。6 a+ C* D8 R* A/ ^
1 21 \# b" R5 G3 A4 N 3& S& p/ \+ @5 s0 N! l( i 4 5) v1 W" e) | Z, x1 [0 F: X 6 78 [3 Q; }# U# b, S& J" t9 Z 82 \9 h5 w0 M- A3 l- x( z 9 10" m0 B; S, d+ }( r | # peer0.org1# h x+ S; h5 x docker exec cli peer chaincode install -n mycc -v 1 \, |9 t- Z9 o+ M: P -p github.com/chaincode/sacc 5 P- Y$ K7 ]3 L: k: C$ @ # peer0.org2 docker exec \ -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \ -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \% `. f8 {$ ]( }1 s& x S4 X2 h ? -e 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 \+ P' g( g1 h: O5 H! K cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc) w/ `( L4 a) z: J3 j |
STEP 3:在通道mychannel上实例化链码并查询
注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:
1 2 3+ ~& H ^7 i4 w# M! n' I 4% o2 V% h2 O+ ]# H6 L) I- Z, W) U | docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \ --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \( J% N% w: A; n# U7 l% R3 j -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \ -P "AND ('Org1MSP.peer','Org2MSP.peer')" |
如果现在看看peer节点的日志,我们可以看到出了新区块#3。
在链码实例化之后,我们可以查询:
1 | docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}' |
STEP 4:调用set()设置新值并从另一个节点查询
出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。
1# F/ a) ?: i! v; U7 f8 n/ U, q: F 2 3, ?3 w* i0 x- _" ` K" p 4 5 60 |( b7 c; p6 J i% Y3 w 7; M( o3 b4 p5 N. B0 v0 P( N+ U 83 ~4 n" b( I( C Z 9 10 119 Z3 k0 ]! M4 O! x5 { 12- e- ^9 A( @% n5 Y" u- X 135 E# E0 s2 q. @7 ]& j$ W% I 14& @- W: q3 w9 t i% f' l | # peer0.org1( G: u9 y+ R8 e! |- {7 p, ? docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \ --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \ --peerAddresses peer0.org1.example.com:7051 \- \& Y2 R2 r# r --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \. ^. P6 M. j9 e, Z --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/ca.crt \, P l6 u0 E2 t# ^$ p/ Y -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}' 7 S: w& Z' t& F: p # peer0.org2 docker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \. `2 d9 t8 n- I% R, m% P -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \ -e CORE_PEER_LOCALMSPID="Org2MSP" \: @3 ?3 I/ y; [' q) n- p -e 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 \, w3 V3 c# D! V7 s8 T cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}' |
4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。! W8 |* T* E; ]' \9 T3 w
下面是演示步骤:
无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:$ `* h$ ] {, U; d- Z8 c9 n+ N
1 X+ `$ z0 F& @/ M. t# d# s" p 2 | cd fabric-samples/first-network+ U( \3 p( W; z* p0 H5 O. I ./byfn.sh up -n |
STEP 2:打包SACC链码3 l7 A0 d8 i/ I: N8 b4 m, |! ~
首先我们处理依赖问题:
1 2 3 | cd fabric-sample/chaincode/sacc GO111MODULE=on go mod vendor- W5 M4 M& t' _ cd fabric-sample/first-network* I$ v8 s% M8 |: d |
1) _: L4 U6 z8 ^9 { 2$ C) r- a. t3 s$ j 36 f, w9 K' A7 n4 X+ w | docker exec cli peer lifecycle chaincode package sacc.tar.gz \ --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \/ M/ t/ P. }0 _5 H3 e --label sacc_1% _$ ^0 ?( o I |
STEP 3:在指定peer节点上安装SACC链码包
现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。
1+ ]: z$ F7 b0 g9 M8 F+ B# B3 a 2# d1 e' B5 e1 F' [( _. y ] 3: C/ I3 G$ [1 e$ N/ ?3 @ 4* V8 k: I: O; M1 v9 ] h% T 5 6/ f! s; W) m- e4 p7 Y3 z6 d( Z 7 8 9) K) A" p0 d% \/ G, c) L8 c 10 | # peer0.org1) ?' [( t! }% e( k docker exec cli peer lifecycle chaincode install sacc.tar.gz # peer0.org29 c0 f! t8 ], A; k docker exec \8 Z/ @3 z/ |4 v" p* d -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \$ p, m1 L- T. @9 S8 v4 }- m9 C -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \0 b% c5 @) t3 R; s; G7 s -e CORE_PEER_LOCALMSPID="Org2MSP" \ -e 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 \" { j& e, o& J# f( u cli peer lifecycle chaincode install sacc.tar.gz3 h- P8 ]$ k, c* c" o1 ^ |
我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。
我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。
1 2 3 4 5, I# h+ [* B! J: }# n 6 a1 F# @- l* m) Q: v1 [ 73 z# Z2 H; [( S3 I 8 9 10 | # peer0.org10 ?5 W: p1 I: I! c docker exec cli peer lifecycle chaincode queryinstalled # peer0.org2 docker exec \ -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \& o# Z* h7 T( Y K+ d0 n. J7 M- L -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \7 @3 _, @' r1 ~ -e CORE_PEER_LOCALMSPID="Org2MSP" \! J% a: O& T* b -e 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 \ cli peer lifecycle chaincode queryinstalled$ Z, ^/ T2 z7 |; I I( g |
根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。8 A+ R$ C* a% ^9 H
首先是Org1批准链码:
1; E( |8 t7 c7 \( E 2 30 l9 H$ b j9 g r 46 `: H. p$ E k- h 5 | docker exec cli peer lifecycle chaincode approveformyorg \$ S8 y. j3 f! { --tls \ --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \% D$ ?/ M6 F! X+ `6 [+ c, H- ^ --channelID mychannel --name mycc --version 1 \ --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}+ t1 `; l& w, S5 T, ~" r. z |
如果我们现在看下peer节点的日志,可以看到出了新块#3。
类似的,我们让Org2批准链码:
11 Y$ i; J9 U" t6 X 21 Z# J: X+ L( D& m: Q! H 3. r0 a- q6 K. P0 B2 }( a A1 W# N* ?( d 4 5# h9 R. J4 a$ o ?6 Q 63 g' | |4 h* ?- t- I7 r; y/ ` 7 8# I. ^" M# X8 a: @4 _! g% ] 9. `. C% @) ^& |% G0 o- S4 X" `& F 10 | docker exec \7 x3 X4 L1 A8 O9 J: J -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \- r9 {/ y8 f) Q -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \ -e CORE_PEER_LOCALMSPID="Org2MSP" \ -e 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 \ cli peer lifecycle chaincode approveformyorg \" `+ i& ]7 f3 k --tls \9 j7 R: n& u) ^- s8 Q& t --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \ --channelID mychannel --name mycc --version 1 --init-required \9 ]* A( p- R! E1 B3 D, q --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}, U% Y/ `3 W4 S( W" S) [ |
不出意外,可以看到出了新块block#4:/ b& H: }3 P$ J
注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。4 q( p0 n! }# ] f; J2 }
可以随时使用如下命令查看链码的提交状态:
16 K, X: N3 i+ p9 [0 T& b 2 Z; Q( K, W! u3 x, K3 n. C5 E | docker exec cli peer lifecycle chaincode checkcommitreadiness \ --channelID mychannel --name mycc --version 1 --sequence 1 --output json; {9 b* b- e2 f |
两个机构都已经批准了链码,现在可以提交了。
STEP 5:向通道mychannel提交链码 l" u+ D; [" X9 g4 s1 `
链码提交可以在一个peer节点上完成:! O0 t3 c" k& f2 l" r! W
1. A% `. ^/ w6 @4 b' i 2* _. p4 B+ `" Y* D& T6 r' H 3- N) O: v9 N& a3 ?% B 46 K! W! i2 r0 b" ] 53 w. U) a5 ^/ w; F0 Z+ A 6/ q) {9 i# b# T. w 72 ^& A! O8 }7 {) D& p 8" Q- `- |( q4 Z4 J- t | docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \8 s" c- V6 r5 z% g& a; i --tls \ --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \! Q( Y! I K2 K( j8 B. u% [7 W$ | --peerAddresses peer0.org1.example.com:7051 \7 N. f! O8 _$ E4 k! H3 ^# b) O --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \ --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/ca.crt \ --channelID mychannel --name mycc --version 1 --sequence 1 --init-required, D. r7 o* J3 d8 a |
可以看到出了新块#5:
注意我们在commit命令中已经包含了init所需的参数。. }$ S4 d: n! N7 O0 f
同样,我们可以使用querycommited命令来查看链码的提交状态:
1& |3 N5 @6 D" X+ d$ v; a( \1 c | docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc+ t, y6 n- J5 R$ m4 m* ~7 @ |
在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。/ ~9 K v0 y) b) h5 h
STEP 6:调用链码的Init方法# m$ P% b' R( y2 m! K6 z0 a
SACC链码的Init方法需要首先调用。+ I0 L* `* D. [! G
17 t! q, y0 t1 q" D: Y( A 27 b Y5 g: \) C5 K8 W3 B& G+ w1 { 3+ R$ b3 H# N% Y. t 4 51 S. O! H8 U5 P0 k; k F2 f5 t 69 O+ y$ c2 ^. i4 e! P 76 e$ ]! l0 p6 f% m 8 | docker exec cli peer chaincode invoke -o orderer.example.com:7050 \- \6 W7 `0 X% X% ]" T4 u' P( I --tls \ --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \ --peerAddresses peer0.org1.example.com:7051 \, E* u1 V+ r# G& ?1 l# l --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \ --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/ca.crt \ -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'1 ^/ o Z6 O" Q: w, r, U |
现在可以查询 链码:8 q) v& W o6 v) ?
13 H: W' ?2 v$ z | docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}' |
STEP 7:调用链码的set()方法并从另一个peer节点查询
和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:
1 28 S a. m' h, L) r4 w( d& N 3 4 5 65 J* L' x4 n* i0 Q1 e 7 8 9 100 Y6 M, q- t* {+ D& x3 u$ _ 11 12 13% S+ y* v1 m1 x) o" K" V9 N. W 14 15 16 17* O. Z. I1 l! ?: }& @ 18# J( j, l t2 l | # peer0.org1 docker exec cli peer chaincode invoke \: z! R" W" a0 P* m, b0 y -o orderer.example.com:7050 \9 i) z) C8 e/ u& _: @& t --tls \ --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \' v0 O6 r+ A2 q8 W' c+ y --peerAddresses peer0.org1.example.com:7051 \ --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \ --peerAddresses peer0.org2.example.com:9051 \7 I( W4 L, O/ H9 S! b7 d! R --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \ -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'5 }, h: c! l1 n! f; E7 S # peer0.org2* M1 {8 C" _) X& B. F8 V$ d docker exec \ -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \$ p/ G9 p$ p, w) A% Q- q9 A -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \ -e CORE_PEER_LOCALMSPID="Org2MSP" \ -e 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 \ cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'0 `- x/ D8 D+ {! B. _ q |
一切正常。