Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

青丝暮雪780
288 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。
: q; Z6 D) \# [  m& Z- ]6 D1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。/ R  a, D2 _8 h3 D9 F8 r, Y
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。
- l0 E, n& c7 z! g下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:
! [3 T* R9 M1 n: X在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。
7 Z" e4 s7 r" [/ S% f在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。
1 {0 L1 B& L6 ?9 H3 LFabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。! g& Q+ I0 S! t# z
下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。; E9 u1 |8 F+ T! Z2 i
宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。; \1 ]  ?9 u* A9 {
链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。
% O; u% X6 x7 J' A. G* j. ]$ k( `安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。
( w. j, x. `; m4 `. C机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。
; G6 ~+ N- g, U+ U2 H5 R当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。
' r4 T( B3 N7 u; C  H) D9 d在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。
3 ]! v$ W3 Q& R0 m" J链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。7 ~$ T5 K/ k8 w9 ]
现在链码就可以使用了。- e  [4 B8 J: e" ]* X
2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。
" N1 B& m  J, Z; @, P9 vFirst Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。
# X  k3 _1 a0 ~9 z& nSACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。
9 E  W  h/ u) }好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。
7 k% I2 s8 B& b7 ]- c  s3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。
1 O  J% r" E) w8 ^8 T8 H- u. i/ ?2 G下面是演示步骤:
, N2 y8 z/ U8 s" p( h7 G3 H; @无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:
' y% w! G. H! T0 L
1
& i  D. S! z( N) m6 d2
6 c) S9 z( z$ r0 i1 Y
cd fabric-samples/first-network
, v; _/ c3 @( t./byfn.sh up -n' P' Q2 ?0 @( a* ~# I7 ^  v
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。3 W8 ^4 Y$ @# v
现在我们可以开始链码部署操作。1 p2 M( V: ]" G5 }3 Q
STEP 2:在指定peer节点上安装链码
6 [; H  K; Q! I, y( T( P, m这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。
8 Y  q3 d+ T. F9 L- J# b
1
$ b2 _, |& T' t7 B/ A) u1 O9 P8 J& v2
: O, m0 Q& Z5 z2 C4 a: F" W! `3( b$ W- i2 K! R! X) C9 N
4
8 Z5 e7 E0 ~: B7 o$ s' ^% |1 V54 x, @3 Z! I; V3 p9 v$ v: L
6
$ C( e9 e7 i& x/ ]% R5 |7
* k" P2 O6 ^8 U. z7 b  F4 L0 E8. C$ T% i0 A4 ^) @* g
90 k, k2 l* o# l( a7 k
10
7 C3 l: o( M: I# W
# peer0.org16 _4 t' E! F; [4 p4 t1 X. h. a
docker exec cli peer chaincode install -n mycc -v 1 \0 K. w" C0 G9 x3 i
  -p github.com/chaincode/sacc: i& q+ I7 p# x* r# n
  9 q. W( X( W( |0 e
# peer0.org2  
# k) `* F8 ?/ N, o: J: K+ ~) ?docker exec \1 i- Q$ z' }. `& D! ?' L* ]1 l$ ~
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \- R7 {* d4 V. D# _/ k+ t
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \" |5 @& B- o: F' O2 R! O4 _3 W' 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 \
6 W2 w1 b6 l( s( A: ]6 I  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc7 O0 t$ ~: c) G% z( q

8 o6 @. d" X7 A. P/ f8 w8 QSTEP 3:在通道mychannel上实例化链码并查询
; L! W2 m0 B9 f) M注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:
! D& ]& _8 ^) P7 K
18 |4 q/ C" D, J7 q3 \
2; r% W/ s" Z2 z& p
37 M+ h7 b: v/ s2 \2 s) j9 y
48 b: W, J. L8 \8 B4 v
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \( X# z2 d. d5 K' S4 I* H9 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 \8 \  J. m: `7 N; ^  G
  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \0 Y/ o: \8 ]+ X
  -P "AND ('Org1MSP.peer','Org2MSP.peer')"+ X9 K: I  W# f) s, z
1 o0 ]9 |2 t: o; l- A
如果现在看看peer节点的日志,我们可以看到出了新区块#3。; W, q0 d' X7 r* K, i5 U
在链码实例化之后,我们可以查询:
" m6 }8 }- w( s5 ^
1
/ n3 @) M+ q& h/ c. e
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
5 ~! |1 ^* F  h! K6 P+ F
8 M$ X% ?+ B6 q* f# G+ L
STEP 4:调用set()设置新值并从另一个节点查询
! C. ~( j: c( u7 f4 [" c% v3 ~出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。/ W) h, Q& C" e( U! ~% e
1
4 d3 z+ F6 `% O  ~3 d2
5 \3 z7 t0 Z1 Y3
9 J- O% ~) x' ?- g3 A* V4
& v2 Y  [9 z* z  |* B5
) M: H2 [! ~. L2 h4 H6
7 [% I9 x  |5 F7
) b4 j6 m8 {: y8 m85 r, u& y8 O% f4 {3 C
9
. @. {- i3 m+ M101 Y1 d8 g2 c4 S8 L3 Q. U9 v
119 d" u$ R/ @: u& e' F! y  c- ~
12
4 C2 F* Y7 J% I3 t13
2 u: S7 S/ G$ R1 l4 c; v/ z14
6 D: a1 ^# l; ^: c/ ]
# peer0.org1* F1 K$ T% u/ u  _  d0 v9 f
docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \5 F. N- G$ u* F9 _
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
( m" B0 q# d9 @7 ?6 v  --peerAddresses peer0.org1.example.com:7051 \
6 T3 i9 p1 `1 ^6 \* T  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
. s) _6 C* a0 `  s4 L3 t3 h  --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 \
+ O5 t6 O0 j/ B" H- M1 J  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'. |3 g; F# d0 t( s' {% x' C
  
& B9 w6 W) N; H2 Y  # peer0.org20 D! {( g% G, P& N
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 \
6 D! L0 e% Z6 j  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \6 r6 o# u2 @% B2 `2 |0 m. c+ V& G
  -e CORE_PEER_LOCALMSPID="Org2MSP" \3 C  R1 K0 @  ~% E# 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 \
( ~; \5 n7 R  f3 z& D6 M  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'6 c, ]4 g3 X) E! ?) N$ _. s  q

3 G6 B; F4 m. Y$ q( t0 u4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。
: e2 R3 F: O$ \- Y" d8 C5 w下面是演示步骤:
$ e7 S/ F$ g. s0 l' V7 i无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:( x7 a7 X' G/ r2 d& H
1, a. d2 l4 l5 H% Y
2
- I$ m; o: a5 d7 d/ y
cd fabric-samples/first-network. l% b! {% c. d7 D( p
./byfn.sh up -n
/ v' j9 O7 u; T/ r7 q/ c
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。
: x8 Z- r7 l0 _/ Q, iSTEP 2:打包SACC链码8 \9 _7 h4 s; \
首先我们处理依赖问题:
# v( A: B/ F# X: O( m9 v! \9 F
1
' M8 o3 U0 b% A9 E2 U, X23 p0 {( z3 ^/ s# r2 E' b0 v
3
6 a) q' E4 S( A- L$ j0 E( l
cd fabric-sample/chaincode/sacc+ y& Z1 @/ p4 N0 L% Y. B  D* H. e
GO111MODULE=on go mod vendor3 D4 E' h; `; b7 X( e5 }
cd fabric-sample/first-network4 }0 X+ Q0 Z) G* |/ X9 V3 B: T
然后打包链码:
/ u1 a! {+ a+ a* U( w3 \2 d. w
1+ f# }  b7 b: w& j' I: x6 w
2( f0 v8 w) I4 q
3
& k. x4 Z  F; @! S5 F( H+ F
docker exec cli peer lifecycle chaincode package sacc.tar.gz \
" ^) j" o7 T4 f7 t, K; G( U  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \1 n; v$ A0 ~" N+ p1 R) t1 y1 u( j
  --label sacc_1/ l. @  W) x* d5 j% R! I
在CLI容器内可以看到生成了新的文件sacc.tar.gz:
6 {: o+ l- U& Z" R' c0 \STEP 3:在指定peer节点上安装SACC链码包2 O5 [7 O3 N  t
现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。
) j9 a) C. G# y. G
1
2 I5 i( L2 c+ U2! f( P! \7 j4 R- Q! s
3' a% [0 K9 ]% {: u  V
4
' e. D' l; O' `! e2 {57 q# D# I3 v8 B  m5 c
6
) N2 [& f( `$ o0 _8 f& y) n* z" S77 {8 X( q6 L5 ]; ]1 j4 B
8+ i3 n! P& y8 b- L: T
9
  S/ ]6 f+ o$ |+ q. l10
$ B3 g: s6 j+ G" m; n8 b$ a0 i$ i
# peer0.org19 T" q1 P3 x/ C% U9 s3 j3 H
docker exec cli peer lifecycle chaincode install sacc.tar.gz8 O8 w# V( u8 h  t* \7 q) z& [
# peer0.org2
: ~4 M  k5 k0 F% R. f, Adocker exec \5 e2 Z1 K% L2 ?
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \# F( t  f6 w" v* w/ r; D9 p
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \3 N3 x% ~* \9 W. r% E: J
  -e CORE_PEER_LOCALMSPID="Org2MSP" \  t! d5 p: f7 c" l* 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 \
5 ]4 m* \* Q  j" ]7 F  cli peer lifecycle chaincode install sacc.tar.gz
4 y. w# H; f& j6 t* Z; W3 a1 A3 r/ J7 I
$ V# m  _* O/ s% `2 A, [, V8 I
我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。( d$ G7 ]! P9 R; e3 S
我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。3 Q9 ?: X$ i! o
1
1 X9 Y5 b6 ~) x: o7 n2
8 ~3 Q' n4 K) B9 S- l  Q37 \3 S  H2 i% I$ ~1 x! C
4, e4 {8 ^3 h5 x4 V6 ~% J$ o7 N
5
; K  e+ D7 L) U: P$ n60 S+ l/ E1 W" `& |
7
: s  A: f: x+ i3 E& _/ v8
1 g; M. r, g# }2 O  Q, _8 q9
5 ^. G$ ?1 f7 `6 M. K6 [108 m1 }8 c; V" w; V; w
# peer0.org1
+ S2 Y0 `9 _; ^( G) b2 sdocker exec cli peer lifecycle chaincode queryinstalled
+ v6 w1 X8 m% ~0 x- a1 H6 @# peer0.org2: G6 e& f  `# s8 x/ `
docker exec \* f# g) W" O: S
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
- _* e. J3 y2 @/ N4 Q9 }  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
9 Z6 c/ K, X5 I. t7 N  -e CORE_PEER_LOCALMSPID="Org2MSP" \
1 M, p+ A! X0 g% l  -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 \* Y5 V' r& K; x, N! o+ O; {" w
  cli peer lifecycle chaincode queryinstalled
7 C, G( D7 Z3 a
STEP 4:审批链码; k/ z! s+ r7 W8 X1 Y  g3 J+ S
根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。
9 X  M( T& v: D% o! x& L首先是Org1批准链码:
4 G- {6 U3 u" y# c9 E- _) X
1
3 n" D7 [; d, S7 k* O8 b, h2 {3 Y23 D4 Q/ s; Y2 q3 G8 |
3! E! U' }' Z1 Q( x- A
4
( b, [# j$ v6 \: y4 t) G5
6 c5 o& G3 b  j
docker exec cli peer lifecycle chaincode approveformyorg \
/ f( z7 m% ]9 K  @  --tls \
9 j( k8 w0 f. A$ r% a; i9 `  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
3 L  G- ?. q8 y7 O: N  --channelID mychannel --name mycc --version 1 \
1 p5 Y: I% F- n8 j- J  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}4 T( O$ c; g( Q! o$ z9 E

: M& i" p" v6 t$ L0 n4 @! g/ q如果我们现在看下peer节点的日志,可以看到出了新块#3。) i! ?+ o6 g9 E/ p6 u. b9 [
类似的,我们让Org2批准链码:) v" W& b! O! v& Q. D* S% m; [
1
7 p" R! [: Q; w8 J- ?, @2
2 S5 Y+ f! l3 u3$ ~7 p6 l; y3 g4 x4 q  I4 ]: v
49 W3 n! S7 R: L
52 s3 ]4 \+ B' U' T5 ]6 Y
6
8 @7 ~" x0 x8 w7 B( O74 c! T% w% w# F% U0 B
8" y. _3 H* S" n" K0 ~( i; E3 j
9' V3 M0 D9 x% p( C( q6 {% Z* Y
102 O. B: M. @$ Q( O( X9 d
docker exec \
) {& x0 |% x- r  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \- ], f0 [$ |* E8 p
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \# x. o- _0 _3 j& v) }% ]
  -e CORE_PEER_LOCALMSPID="Org2MSP" \. N8 j1 m0 r8 ]+ h6 X9 l& 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 \+ l. N- O! z; V) ?$ @' f
  cli peer lifecycle chaincode approveformyorg \( k6 a1 @* u0 i* B
  --tls \
+ m' l% q, k8 f1 ]# v! M  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \7 a9 `* R" \' n" A4 O* t6 z1 l
  --channelID mychannel --name mycc --version 1 --init-required \1 i% f( I4 I8 i; S- f8 K
  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}+ T/ o  }5 s& J" ?3 l1 T% x
% q. u: |2 m# T" o8 g. w
不出意外,可以看到出了新块block#4:
" [1 ~& r( w$ s. z1 K1 q3 V注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。
8 C% O) _" i) r5 S0 Y0 T. K# Z可以随时使用如下命令查看链码的提交状态:2 W- ], \! M6 a* ~
1* ^% k) B, v8 I& w( ~
2
$ H4 i, F3 P# c! q; C
docker exec cli peer lifecycle chaincode checkcommitreadiness \
4 j2 U6 b* o( K0 f8 n6 i% A7 J  --channelID mychannel --name mycc --version 1 --sequence 1 --output json
; ^8 D. a4 f" Q: K/ j+ ^
6 y& x* V* @# i0 K
两个机构都已经批准了链码,现在可以提交了。
$ |: j+ N. j3 l& b0 M' pSTEP 5:向通道mychannel提交链码
2 z- ]$ s/ Z3 t: B5 y: w链码提交可以在一个peer节点上完成:
, J+ O9 [% B! c2 U. ]
1  X5 {! n2 m9 x8 P
2
) L: _, H0 r: \9 ?, M3! ?! N/ s+ X+ z0 O
43 [5 N! u1 r5 b! h
5
# `6 K- g! {5 J6
# [9 K$ |4 d. j5 n: y; K+ a7; m4 @! D" f: k2 q4 x! [+ G+ f
87 ?$ d/ b1 ?2 W; W
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \
$ {, l# s3 v6 _5 e7 ^- P  --tls \
* Y. E" [9 V0 A5 @  --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 v/ k4 X6 H" R7 @! y& L
  --peerAddresses peer0.org1.example.com:7051 \
/ l  j: Q' c7 X, s+ ^# s+ O4 q  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
9 ~. z- R5 `, z4 z( D, A& m/ O  --peerAddresses peer0.org2.example.com:9051 \
- @, @) j1 L) w/ w' l  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \) |. H4 C* C1 N7 L6 i7 B( c3 D( |
  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required
/ |, Y( x, m6 B0 M1 T

5 h9 ~9 F( I& S) M" V- l可以看到出了新块#5:6 k7 u: J' \9 K
注意我们在commit命令中已经包含了init所需的参数。
: I) u1 o; T; V% q+ N1 n' _同样,我们可以使用querycommited命令来查看链码的提交状态:: t( h4 U. C9 v! d. u9 C
1- m9 L$ v( H, o& u! C  b+ Q) t! E1 H" n
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc+ b8 z+ b0 t6 q9 q% d% ]

6 B# Z+ N; L  T  r) W: g1 T在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。
5 n6 p# r3 W# s( TSTEP 6:调用链码的Init方法
; ^; |0 ~9 x  A4 N4 A! o  aSACC链码的Init方法需要首先调用。  I. T. y9 M1 ~/ ^
13 u7 L$ i- s- v( [* E
2
& }: ]5 u0 Q5 M: r! e3/ R& K0 y$ Y4 N7 P2 [1 v
4% c! c& @, [: ~: L" \  w0 I
54 l7 L2 v! ?% _! j- d( n
66 q1 ^6 X6 r; D" z9 ~. ?
7
* p8 n6 R7 C$ J& T8
$ q, @; T: Z) u) X9 ~# S& H( B
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \
# I; B8 h% ]! E" c2 o  V, I3 {& b' k  --tls \3 y$ @* ^9 D: L
  --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' v1 V+ o4 W! T2 t, y5 N' V  --peerAddresses peer0.org1.example.com:7051 \8 l, u2 f: w5 x+ N
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
5 e, D, m; m6 p0 P1 t- R; Z( b: N  --peerAddresses peer0.org2.example.com:9051 \+ A2 \8 i% R) M; ^1 g$ f- a$ C
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \1 G+ F. c/ X, T' N8 S8 W
  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'$ o& @+ ~9 y, `' e  P% o
4 k5 E; H: B5 y$ J
现在可以查询 链码:. X: X, u  A1 U# A/ H# w
1& |; S" `' q# i
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
! C( d1 l6 g  Q4 D) z6 \2 H

0 j7 f3 o" F' d' k. E" [6 B0 ZSTEP 7:调用链码的set()方法并从另一个peer节点查询
/ _+ r" Y6 {" F5 n2 e和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:+ I  d7 D# s$ c5 m. Q% u0 z( N
1
1 y  P! V+ L# Y+ S! t% C21 g; \. ]( q  }- ?: Q, y. z/ a
3
5 S# _2 r' x+ @, R4# d, N3 K  ?0 x
5
* `4 I. O: M8 G& t, F6
2 \  o* ^# {4 r76 r) l4 F* ?4 j) h$ L5 `
89 N5 S) w: u, {! C9 J  `
9
! ?# I/ M& n% z7 N10+ N2 n5 ^: q9 Z2 S1 P+ V
11  R1 E4 b2 o, E' `! {) V/ `
12
4 r1 Y. i) l' |& Y13' P2 O$ X* F+ ^2 L" w: l
14& o5 E1 i6 _. z. v! \4 \9 }, }
15! L. s! C( O8 t2 @6 E
16. r1 K0 l" V6 b' T3 M
17
2 ]* U- G" f- j181 N: b" h) j9 K/ p
# peer0.org1
& k! P; s) L1 ddocker exec cli peer chaincode invoke \
( d! P9 ]; U0 B: g  -o orderer.example.com:7050 \
! F% ]& P5 z# I, m) ?& q+ L  --tls \
8 K/ A1 D; N* 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 \' y6 W+ m4 u; B4 y8 [- j
  --peerAddresses peer0.org1.example.com:7051 \
1 R; Z, i, G' {1 y6 a  T4 B" z: ~  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
! f/ l- p- V/ t1 P$ n0 m9 m  --peerAddresses peer0.org2.example.com:9051 \6 u& J! I' l7 a: X) t
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \: D6 h; P( C8 l4 c. i. @
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'' r, C: Y6 F( U
  , R& e/ `! a! r1 c& f5 W# J0 B
  # peer0.org2
/ J% g- e7 }( ~6 [* c- udocker exec \% N6 Z. U8 R  b# Q- q
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
7 r  H# w* u6 v( Q' e) W1 q/ j  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
6 O( Y/ X8 h/ K+ T) ]  -e CORE_PEER_LOCALMSPID="Org2MSP" \
5 n8 u2 P9 p2 }: O% m+ z  -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 \6 \+ k/ ~7 v5 f3 e% C2 b
  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'2 T, n' w6 v+ J% R9 ~
  L  `- y5 I1 N* ]  `2 m0 p5 n
一切正常。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11