Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

超级账本Fabric 2.0链码操作实战

青丝暮雪780
154 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。4 d3 U3 z) ?- h/ }' Y! e6 n# Q
1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。/ }4 m4 ^! Q9 V! M& ]5 }, e
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。
( ^  z  b$ i5 K( d3 E$ Q下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:% L6 x& |. \% @
在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。% x" b% T  ]& t; G4 G
在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。
  \, i4 W3 d  N! ?Fabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。: X3 }+ |. W; v7 I; x; P) A
下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。5 O" B( v. i4 e, W
宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。1 [  {% z5 Q0 e( `0 S& b6 m* V  Z
链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。# O8 ?2 o- m/ Y6 y3 A8 W: b/ K6 E, |
安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。' N  V4 `: U: m# G9 `/ d; J, H
机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。
, ]7 u; F0 i, N: O) @& f( s+ q当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。! K+ I1 ^% L- L  C1 B
在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。1 X0 v$ F  w+ Z* a
链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。( o7 k' h! L' c: E6 q. e
现在链码就可以使用了。
5 {4 J3 l: S5 t6 N; Q2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。
& F# n. M2 F8 N* tFirst Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。+ ]+ Z+ H* d' X: y  N, p9 a( M/ _" j
SACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。1 r2 G$ H/ U" H% J# i- z
好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。& U4 d5 V' {+ o- r0 l
3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。7 X/ Z* {  n$ T* N7 n
下面是演示步骤:' y% F) E/ u& b% ]
无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:
( z' t' `9 p& ^$ {( E
1  s% H( T5 [$ N3 R+ x
2
. O7 s9 S. ?! L& I
cd fabric-samples/first-network
$ @, |6 @# y! N' V./byfn.sh up -n
, }+ Z1 {% r7 ?0 w9 ?$ M% Z
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。
& r- @$ W2 E2 j  Q& x现在我们可以开始链码部署操作。3 i/ K* F6 Y  u9 ]
STEP 2:在指定peer节点上安装链码
% V& v! S& M) S0 P这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。3 [4 t6 @" q, |3 H/ x; ~) p
1# u3 p. F/ H( p
2
" V, V; p1 B2 p3 K3
2 k5 k& [1 `/ ~8 ?  z4 H7 M4& o" D! c  n- p0 `8 K5 n( |
5( Z4 ]4 x' c! Z3 e/ h" E+ h' a* z9 i* N
6
/ ?$ g9 P3 E+ b* S* b* f0 T7( ?, a# m; s8 N* c; H
8
: t$ f$ r+ Q/ h! E0 J5 N* z  M9
5 K, `. z# D; |5 d* \- C107 v" O9 V( f9 K( {  H3 |
# peer0.org16 U! B- \* G9 k! f* ~$ r6 c& J9 l9 E
docker exec cli peer chaincode install -n mycc -v 1 \
1 R% b) s! e8 n- c, w  -p github.com/chaincode/sacc, Z! f  |7 P6 i$ H$ R$ T
  
$ Y# y* \  |2 Z* p9 F# peer0.org2  
  K+ i: r' ~0 ]% [, Qdocker exec \
3 |* o( g5 |$ K$ y# F/ L& \0 t  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
; p$ H' ~% J5 x" @  C9 _' R  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
$ f* Y1 I, S/ B4 G9 e. j$ Y  -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 \, i$ w* m2 R2 x/ i
  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc
$ T' m/ e+ R/ k, Q; s: a; D
0 ?# J3 P* b( ?' s0 |" j& [
STEP 3:在通道mychannel上实例化链码并查询7 u2 P$ P6 o8 J5 r  C
注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:# z+ j1 p$ d7 |
17 \0 ], U/ E* L' j$ J  N3 u, K
2
8 \1 H3 [7 r' x; b/ y: ?) ]3
7 B! N/ `* Z/ o% B" x: P8 E- ^4
$ t& Y2 D9 ?$ Y8 _# q9 C: b
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \2 j* g6 E& R0 F) \, X: @, ?
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
( F! m" X  N* u) R' U/ X  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \
1 C5 G+ x3 }6 p0 k  o$ w  -P "AND ('Org1MSP.peer','Org2MSP.peer')"
( J+ r  F1 \: o7 B$ F
2 W  P+ a1 ~% r4 X
如果现在看看peer节点的日志,我们可以看到出了新区块#3。9 \* {+ ~$ d1 N# D( V# I
在链码实例化之后,我们可以查询:% I7 p& b. |# |- G
1
/ o& a' _% c) M( L0 t
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'$ J. r* c+ U3 T. \# X9 |9 F

" H1 S' A0 P# B/ q' {, ASTEP 4:调用set()设置新值并从另一个节点查询5 D1 n& @: I" C
出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。
8 j8 @$ K0 D: K1 J. Z# z: d
1) ^: h2 E# {; }, B. I- P4 K7 _
2
' L# |% A2 s5 S3' T. {9 A1 h4 |7 [
4
! s  q) x+ C3 _5 b% _" Q% Z8 ~5
6 P6 q9 C, b1 B% y69 n/ R1 T; D2 n/ H
7; p! e! B& b2 J; F. e- @0 m! f
8
8 b0 D6 w* I* o- u( N3 U9
; c. E9 b% j5 ]0 v) L# M$ L10
9 ^* T0 ], ~* {/ F* I/ k& Q$ R0 M11
2 G9 q# z$ `% I: e. T- V# X12
9 r3 J+ K; m3 z9 l# O13
) o4 F+ R- A3 N9 b14
' ^, F! j% `6 m; e
# peer0.org1& X" R0 |  N, y
docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \) ~: u6 Z' y# x/ 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 \
5 z6 _. }7 @  P: l  --peerAddresses peer0.org1.example.com:7051 \4 K' Q/ o' f  k0 F% O& V* y3 S0 V2 ~
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
- ]. M! {' s$ b6 E  --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 \. h. G. F: ~0 ^+ B
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'% S* @9 P# N* Y5 R% \6 O1 P
  
& p" z: t2 a& Q5 \8 @" G9 G* F  # peer0.org21 e% _3 K- Y% r% D3 m
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 \
9 y; ^/ k/ f. |+ G  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \- y& ]& {0 c! P
  -e CORE_PEER_LOCALMSPID="Org2MSP" \/ ~2 K. O# Y4 r: s5 O
  -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 \
1 o! Y- Q- S* C  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
# }1 W7 V* y6 w2 f
. A3 [- u9 O) l3 Y# E
4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。
  b& S6 K* W  t6 a下面是演示步骤:5 }% |: m. B% L4 Y3 D
无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:
2 A4 j$ Q% N, P' y
1+ |, y3 h1 U, w9 F# \) _
2
7 w5 E. A5 \4 l
cd fabric-samples/first-network
* n- Y4 s# q7 a, D./byfn.sh up -n1 E. j2 Q- |% [3 {2 q! |  C+ g
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。
* w4 E8 E2 ^# p& |! S) {STEP 2:打包SACC链码/ C' q9 C. E7 r6 U
首先我们处理依赖问题:
8 X+ a$ |- q" b
1
2 z  v4 R1 \7 V+ K5 ~! T7 N7 M/ Q! H" q2
9 I9 k) l. S9 m& s! S7 L! D3
- B% X. J! b) ]% Q# V
cd fabric-sample/chaincode/sacc+ {; ?) C0 T. [7 X1 e5 m
GO111MODULE=on go mod vendor1 p$ Z' u, i( D* p
cd fabric-sample/first-network, k! h: I- j. z( e# [7 E4 s
然后打包链码:8 a" ~4 u' ^3 C& {5 Y
19 \  E: A" E. S/ ]# B+ z9 W
2: [3 U0 G& E" n2 p
31 ~! t& D* j4 x/ r
docker exec cli peer lifecycle chaincode package sacc.tar.gz \# ]" l+ k  M$ ]. L& x, H. r1 R1 y
  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \
+ H$ N- \- O2 f; o' n5 a& B  --label sacc_15 }' ?9 Q) O' c
在CLI容器内可以看到生成了新的文件sacc.tar.gz:0 X6 k4 V2 h$ k+ I: v$ @3 n7 O' E
STEP 3:在指定peer节点上安装SACC链码包
" v9 M! l, r* [" {8 O$ h现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。( b* {: q1 N; T$ D, G
1
* S& {) V# u5 }+ X9 l/ {2
5 Q* k4 V$ ?) ~! @; c: L  I36 \0 a* K  \! x
4
' g7 J7 T! w  p- R5
. z- G/ _& g2 L; F% {1 o! t( p7 N62 D+ |  V0 {0 t8 U: P% c
7* _. a* B/ ~4 i# Y1 _
8, d8 h, g  ?( l6 X
9
* L0 _, }$ M9 d6 W) ]10
0 c5 @. t: o! d* B6 z6 H' x
# peer0.org1; M1 X5 i/ f+ g: V
docker exec cli peer lifecycle chaincode install sacc.tar.gz* J  ]/ L6 w, \9 i8 \! V. Q
# peer0.org2) M) U" Z+ _# s* b8 K" ~5 \
docker exec \
9 v+ N& }' P7 \- l# ~9 p, k  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \2 S: N" [' Z6 K8 P* [
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \: d& G8 M; \- O( [1 V/ C5 X& I0 F
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
; A) V$ A3 O# T  -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 \
' \. Q/ o8 a, w: j& J/ q  cli peer lifecycle chaincode install sacc.tar.gz
3 M7 y3 Q7 s: @1 x1 `: P
" U7 H# q; @$ c+ |/ C
我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。+ s6 T2 ~4 P# F( _9 I' S; u6 a
我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。
/ T& J  N& I+ j, C$ Q
1  V6 L* n( l# W1 @% H
26 d7 V) O1 i, e# S
3
$ C, u- i6 c: V; Q4
  w9 S* D5 M2 O9 m4 Z8 c2 G5( U" N2 f8 U9 q! }' k
6) e7 X) Q  a3 p( s& \9 `
7, E7 Z8 X5 w. ^' K  v
84 b6 C$ ?; |9 b0 P  k/ R" O
9
6 u# F' W+ F" m$ B1 L) u10
+ L& J1 x/ w) |0 O& Y
# peer0.org1* g( l- l( D8 Z5 c+ X0 A6 \- S& t* ?
docker exec cli peer lifecycle chaincode queryinstalled
0 l$ R6 |8 O: }( L' c  ?# peer0.org2
! x8 C( O' u3 a# Zdocker exec \: F" d2 k  l8 t3 ~6 z4 ~
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \4 E8 M9 J! R3 ~* x
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
. K1 m" p- K5 M! V  K1 d  -e CORE_PEER_LOCALMSPID="Org2MSP" \
" L! T# R: I0 G7 g. s4 [2 F  -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 \
! }: b1 }8 I! H. E+ w5 r  cli peer lifecycle chaincode queryinstalled
' z% q+ d2 C7 E- h" }$ y/ S
STEP 4:审批链码
( t& I; B3 F0 `, c$ y' p. E; d0 y根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。
! v) e' y7 L2 w9 v首先是Org1批准链码:
' D5 V) W  {* v. O
1
2 H; x+ z; E$ |1 i2- [( i. S. z; G* m& M
3
& F$ p* T6 Q' J- N- g$ K% A0 V4
* q- c. z' y9 [$ Y. k3 I55 I8 W5 y' {/ x7 M* _' B3 x7 g, @
docker exec cli peer lifecycle chaincode approveformyorg \& z1 a+ ]( G  h; E; b
  --tls \
' I; b* o! B  |9 i  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
2 o) M' k4 s, n9 o  --channelID mychannel --name mycc --version 1 \* B0 H7 b- t. L
  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
* w" \4 z0 ?- V& ~  M" Q0 j  l

: ~4 T% p* s1 X8 Z: R如果我们现在看下peer节点的日志,可以看到出了新块#3。: Y5 d" o1 Y8 T, m+ B7 N% C% Z
类似的,我们让Org2批准链码:
$ q6 L) _) h& I$ h, }5 s) j$ E
1
+ z% a8 C4 Z2 O& p, M- k2
- |8 d  o2 r) K" q9 i3& m0 L+ s& R0 X3 v. ^8 S
46 {  G( y1 Y. v1 G8 z2 b
5
" _* I/ I8 g9 d& E( p6 \64 O! u; z& E0 y# d6 ^' ?
7- a# E, G6 q/ S8 j  r; w
89 ~; Z5 I6 {: n! M1 Y$ [3 G
9; |: L2 G0 h2 R$ m% F+ W
10. K. v8 ?, N/ C# z$ J4 N
docker exec \$ T& B; G5 T5 N
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \! a6 y3 S( z+ k( U
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \& K3 a/ |$ H5 n2 e9 b
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
. D9 Y8 T9 ]5 p5 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 \
& L; R+ q+ Y* g( a" `" |2 Q# C* r  cli peer lifecycle chaincode approveformyorg \+ j2 O: s! L; p! o8 Z! W
  --tls \
) j8 k8 k8 U; d) d; `  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
: N, K1 }1 V  t% M4 r  --channelID mychannel --name mycc --version 1 --init-required \
: y$ d1 f; e# \9 z- s6 h5 j7 ]' W  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}, o# w7 J: a, N& L
7 v; D) P* Z1 B2 ?- k0 C
不出意外,可以看到出了新块block#4:" U5 F1 a2 G8 ]* Y
注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。. b% ?. S! c2 k# E. _- x
可以随时使用如下命令查看链码的提交状态:! `6 Y3 S0 W' ~7 b6 x$ Y5 P# O+ K7 O
1$ }+ _# q& S6 @1 E5 L- V) F
2* A4 L; G# P' T4 t9 J2 r
docker exec cli peer lifecycle chaincode checkcommitreadiness \
9 w/ l) i3 c/ i2 k  --channelID mychannel --name mycc --version 1 --sequence 1 --output json
7 F7 d4 A# y3 R8 q! X  J
: v7 \# @4 x4 F- j/ {3 t
两个机构都已经批准了链码,现在可以提交了。
7 J8 U: }( U2 P2 g1 i4 h5 `STEP 5:向通道mychannel提交链码
) F6 K. z( }4 [9 c链码提交可以在一个peer节点上完成:0 F! X. O; B% \0 t0 T" c+ M
1$ e9 H8 l! V) r
2
  q& S, a  H8 U& c, V$ }& R& A3
4 s7 U* J& P; I* b; D) i  C' A4
0 E, V1 f8 _: j* R. {5
. ^* T: k5 ~* U  z* q; X4 U6 r6
4 `5 N& ?$ Y5 W( b; L: N6 x# }9 Q- G7
3 t4 {' Q: ]6 U% {8
9 r1 s  G$ L- d6 J1 }7 d6 l. b$ A
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \* `- r7 H- u9 A4 g8 ~" {$ v/ q
  --tls \% G' f& l; l- B5 h3 d
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
& n$ G. |) ~( m3 R  --peerAddresses peer0.org1.example.com:7051 \" o' e3 c1 O0 c& R
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \; ~+ p& P& v, `. ^2 z' S; a0 h
  --peerAddresses peer0.org2.example.com:9051 \
7 j6 a$ b2 y& g5 q0 |6 P  J% k: e  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \( P; f& p3 B- z5 W5 b; d8 G7 t: A
  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required& q& Z6 E0 j, f2 @

6 z/ P$ h3 t3 x  v( Y5 U可以看到出了新块#5:
$ V! \% ]& \1 V6 O注意我们在commit命令中已经包含了init所需的参数。: e: o; h; o1 A- ^
同样,我们可以使用querycommited命令来查看链码的提交状态:$ H6 W; l; O% ]4 \% g9 k
1
6 _" y5 \/ S& e5 M
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc
! d2 i5 `) _% E7 j1 Y) K. {3 i
1 ]# f" a( j7 W. W1 l
在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。: v& B0 u! E3 {) O
STEP 6:调用链码的Init方法/ j, |8 g! a/ |# y- i
SACC链码的Init方法需要首先调用。7 W+ w6 l3 ]0 c+ \
1
0 m* s9 Q) W8 l4 u4 e21 Q0 w2 T" A3 C) @
37 L$ K' U5 Q) ]/ W6 u- I* }0 N# p
4
2 N& Q6 T0 f9 W1 D5
8 x0 U5 S4 F; d+ Q7 S62 Z3 r+ q) _( j, N! v, Y1 c9 ?7 Q
7  _( |0 ]) B) J% l! k
8  J" V: z0 L" _6 |) }% ^
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \+ `6 }1 c" [4 r1 ~# j/ ]. \
  --tls \: l8 M9 p8 p- ~
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \' N% Z9 z9 m4 z7 S
  --peerAddresses peer0.org1.example.com:7051 \
2 v) J, [  i  V0 E. H3 o' r6 V  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \0 V3 s! ?0 ?" L2 C) d+ ^
  --peerAddresses peer0.org2.example.com:9051 \0 ~! z  X8 M8 R: L0 j' g1 N! I
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
! [# V6 ~& ~% c' C( s% J  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'* y- p, q) }1 p, k$ Y

9 Y' Y0 h7 G+ _4 K+ [* S现在可以查询 链码:
7 ?6 C6 q/ G- H' k+ \  N* O' L
1
6 d  K6 i3 Z7 `
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
* R- C4 k9 U7 C. I5 y

* a  n$ f9 x( [STEP 7:调用链码的set()方法并从另一个peer节点查询
- q2 q9 H7 |1 k和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:
# F3 X  B% R4 h9 d
1
% q+ E6 o, C( q  J7 I% T2
- ?7 {( c- z8 V7 y9 B$ ?, |3
/ l& J2 j9 a2 p# H8 P( o4! y$ @+ ]2 l4 Y' X& J
5
9 {" l, Z& Q1 Y8 R6
2 E8 L9 m; L4 u  f' q( M7
/ s! G9 {  w$ d. m& ^+ T8 L1 m8; j: q4 u' [1 w
9
: S7 \' P# {$ o; J5 j; ^( v5 ]10+ f7 @$ d( Y5 _/ R! ^1 U
11. N6 \7 K+ A3 Q5 q  H' H* s" \
12% a' o1 ]2 k& d
13% z( `7 G7 }# e% J, ?
144 n0 Y. U% }% p" c2 z; M
15
; D* B# w) W4 r: W) R162 b' D6 V. r: x: F
17, a+ i) @( r2 Y, v" t
18
; ^3 j( W6 s3 q, e) N/ r
# peer0.org12 ^/ `( w/ d4 v  E: Z0 |" D
docker exec cli peer chaincode invoke \4 L( s5 q) o" U$ M
  -o orderer.example.com:7050 \
, l- o$ `/ s' ^' U9 |" i/ c  --tls \
* m, C* R5 W) D: D  E1 Z# X* v  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
" {# T) k" ~& y4 w% G8 R$ j# B  --peerAddresses peer0.org1.example.com:7051 \& t# r! ]/ U. w  W! n: }# _
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
& o6 O+ @9 O3 f2 w1 j" |8 B  --peerAddresses peer0.org2.example.com:9051 \& U% v. l8 O+ M0 S, _9 m  i: ~
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
# H! Z+ j' c$ l, s  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'# P; [, z" C# M  Q
  ! X5 C% @& @3 a; x, I
  # peer0.org21 v2 V. t0 c: d0 m9 e
docker exec \5 `! b2 y1 B6 M. U
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \( [- T; O+ V; B6 F( e9 A- K
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \+ ?* I3 U1 c& N
  -e CORE_PEER_LOCALMSPID="Org2MSP" \$ r- x- l  C3 U, s' t
  -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 \
- Q& V& ]6 q& E# O& Z  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
% d: F, P1 ], R( I

2 W" k: r8 y6 y# m6 C一切正常。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11