Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

青丝暮雪780
287 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。
. [5 ^4 }! A" P3 B: a( l6 L1 b1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。9 A! m$ L- ]+ O2 `/ O
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。# F8 i3 |' V& i7 F8 w
下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:
3 B* o. Z9 E' g& o! _' J/ K8 t在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。4 Q% r. j2 K( k* F# n
在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。) I* I: Y" p7 I: u; K4 w
Fabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。
5 v+ F! u+ M. [; Q. s5 B下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。
. d) i' U+ C5 q2 x3 x+ m* _0 V. g宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。
0 A5 C3 x) `8 J; Y, z, j链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。
* N! Z: l8 n. f9 t  n  u5 z安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。
2 F/ D- Q  C3 A1 a机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。
/ j4 _( X/ V, I# n' f当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。
3 a8 w8 Z( y" S6 K1 e: M$ l& _在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。
/ I/ B8 }. y' p: m3 a链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。
" y3 ~8 {  _" d' m. m2 u( B现在链码就可以使用了。
8 \/ E# C2 N! G" \0 T  Y' w2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。
; Y- j+ i3 `4 ~9 a7 PFirst Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。0 B( x5 K- f" t' _5 k+ H% G' o9 c# a
SACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。4 b' ?: Z& [. k5 `9 H
好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。
$ @4 ?$ |7 V& f, u4 s7 i6 ]. S3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。+ L- @9 p; t* h; S% @% F; S
下面是演示步骤:- S5 M# [* |( H  F% U( ~+ b% |% F
无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:# l6 q0 j. N# [4 z* q3 u
1
# z/ @! W# X. B' I& J( ~+ y8 B2
' z$ ^( P0 }6 \4 O% P, `# V. m
cd fabric-samples/first-network
! F0 M  a6 E% K* O  d) o- }, ~( {# A( _./byfn.sh up -n3 u1 @  g" y- X
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。
5 s* A  B) Z+ l6 ^. x现在我们可以开始链码部署操作。$ a3 c9 X' n" j' I
STEP 2:在指定peer节点上安装链码8 R9 k7 [+ Z! X
这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。, w* S/ V$ |" @( _! Z! h1 b
1
# E! g0 Z) Y+ b; j# F( U2* y5 ~8 W+ _: a7 G
3
: U/ @" L4 P8 [8 E: {40 h8 F1 {& M& S6 s$ V0 b7 u
5. l% l8 f7 e- `% B5 u; D; O( R
6; t: `, U: Q$ I3 A' c! J* g
79 V/ v* N9 I8 n- i
8
6 U" ]( R- p8 u2 n' E+ G$ g0 _9/ T4 X! w& \. _
10- i# m) O, j4 H- a
# peer0.org1" x. Q# h/ U+ s* f* g
docker exec cli peer chaincode install -n mycc -v 1 \& F' Y0 U4 a$ S& b9 O
  -p github.com/chaincode/sacc
( X. K5 i" m: L: @  
: X+ E9 H6 z' n. A  S+ K( s; J* M# peer0.org2  
: ]& {+ I) K7 n; w0 ndocker exec \
+ S  x& R6 r7 p) \/ A  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
4 q7 A  ~% P! n  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
5 |7 a3 F- [# W7 \& ^  -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 \
+ D+ Q3 r! O5 ^  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc
+ ?( Q9 ]: M& j9 `% q; v( q

+ A. i3 \) q( X& W& H, wSTEP 3:在通道mychannel上实例化链码并查询
0 J/ h% l! G' x2 q注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:* u( D  R$ h- w2 \$ O+ `. E
16 Q$ m4 V1 s+ F% i; o
26 y+ C- ~) F" Q) g0 U
30 `4 U% Q. k+ X( z( {" C9 w1 b; w
4  O6 i. G+ w+ b5 A/ W
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \, H1 y. T* R; \7 L. _  }5 s
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
& z' {. o2 g$ l  i& f  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \
/ a/ ?' P) l) Y6 E% q! ]2 G3 R  -P "AND ('Org1MSP.peer','Org2MSP.peer')"
4 X% ?0 x6 b4 a- V1 h4 X, M1 S) C, h

, I! s, d  c, z* o如果现在看看peer节点的日志,我们可以看到出了新区块#3。
5 v$ J; l' Q2 O; i! f在链码实例化之后,我们可以查询:, J, A! Q3 b; z% h; E0 B) |% U+ |1 d
1
4 P. e5 ~/ q3 `. y) J1 X7 j
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
1 y3 d# |: [) c

' u- L1 c) p2 v) K  HSTEP 4:调用set()设置新值并从另一个节点查询! O/ O. [& @1 D
出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。4 c( F3 P! O- u0 H/ P7 ?* I  ?
1
# D2 c/ I! w7 Z. ]# ^! l27 F3 h& S' T7 z+ i9 r
3  X# `( e9 u. F; S
4
' W0 e' q; _* y  S7 s8 x5, o+ A" a# h4 [. t  W9 G; ~
6
# S# k+ U4 L$ K+ m7/ G' Q7 o' b3 {# Y
80 ?. m8 a. A; w5 k
9
: T0 A1 s$ f' n; P10: P/ w/ {* m0 ^- q
11
6 H7 ]8 w( {" W2 I  S6 T12* N7 N  H6 o$ y; v& [
13
+ L2 I5 U6 Y8 Y. I- P. {: z+ f14
! b  \: K8 }) g
# peer0.org1
5 Z( O4 P* [2 [. b7 wdocker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \
+ J* a! l7 b" @/ r! f  --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: J7 Y# g" ]3 O
  --peerAddresses peer0.org1.example.com:7051 \
5 I  y% c% n( Z" j# r- q  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \, b0 P- _# W5 X3 f3 ]- Q5 s
  --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 \
0 \) V3 a/ ^9 h" C0 m; I+ p- Q8 I  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
" e/ s6 }6 [, C  R( L0 n, ~( @  2 Z3 v4 n7 K; O  U, f) o
  # peer0.org2" W" y+ p1 ~; H' {8 V. h3 s
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 \
3 I$ b- {/ i+ a1 \  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \2 v5 ?  L6 S6 y, @: {
  -e CORE_PEER_LOCALMSPID="Org2MSP" \4 @' C3 ?& e9 e' |9 Y1 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 \
3 D. r* r3 _3 t$ @& ^( c1 @: ]  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}') z8 m* k  ^9 f, o- f

9 B" ?' l9 C* [" P2 G4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。
, p+ ^  }0 j/ U+ x$ Y/ h下面是演示步骤:, ^1 }$ i% P; s7 p( r  {
无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:& v6 X* F/ ~, C
1) Y2 H, D: V9 Y% M
2
1 t* j5 W4 l# V* v& Y
cd fabric-samples/first-network
3 S+ M9 k. G* I9 O6 S) x( s./byfn.sh up -n
& j4 |. M  e" H" ^
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。
" n* u0 l4 ]* E5 L$ Z  ySTEP 2:打包SACC链码
0 T4 t7 w( C( K首先我们处理依赖问题:
5 J2 u, g! P& B& ~1 `
1
. L! W% c, j6 U- I2
- ?9 a2 C9 c( o3/ T+ t& M4 M) q7 C
cd fabric-sample/chaincode/sacc# x- _2 a, e' w  |5 K; U# {+ z
GO111MODULE=on go mod vendor  N- p$ y# \: s( p- q
cd fabric-sample/first-network
" t( e# p6 T$ s# z- ~- }
然后打包链码:- d3 y! d, ^7 F/ ~7 Z
1
+ q/ C- |0 |  y8 i22 z3 |! j7 `; l! \
3
5 X  N2 G6 l% z
docker exec cli peer lifecycle chaincode package sacc.tar.gz \5 S& L  J/ Z% S8 B1 R! j4 z6 T
  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \
/ ?. V  B3 i/ [  w1 {7 s: u  --label sacc_1
. q* n0 @2 F' A- h0 P1 E
在CLI容器内可以看到生成了新的文件sacc.tar.gz:
9 C4 G# ~  M+ F4 BSTEP 3:在指定peer节点上安装SACC链码包2 f* Q5 O  \( n6 X, u$ ?4 D6 T
现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。* I6 c  R! f( ?: M1 P" i! Y
1
- @5 L, \2 ]# @( J2
' X: u  a6 o! B- z; W3 z9 S5 I3; w) }. ?$ F: `2 {  \0 G. n
4
+ s! n1 n' @8 m$ R0 b50 U5 B( ^: D. }- ?5 V1 M* w8 k
6
7 o$ E' @" l( H7
+ h9 U% a+ \' d1 m2 z8
2 q9 o; g6 F0 g0 Z( y! L9
0 E; v3 K! A" M10  p2 T; Z8 r1 w  @# H' Q
# peer0.org1$ E. X9 e, N* w; z1 J
docker exec cli peer lifecycle chaincode install sacc.tar.gz3 _* F  o  @: i9 ?" c0 l2 A
# peer0.org2
0 `  [0 z' Q( K( b' bdocker exec \
4 }: R: x$ H0 ~7 W  G* W# c: x  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
: k1 }, u& X. J; G3 R5 a% g  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
/ o) q" P7 ?3 l. o7 g5 i$ ~  -e CORE_PEER_LOCALMSPID="Org2MSP" \
) `$ {% M% a7 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 \
8 K; k' Q$ R/ i4 w" Z& a  cli peer lifecycle chaincode install sacc.tar.gz
( S2 }; i2 M7 {! I. c8 ]
8 `, U  l( T; J
我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。
8 H# b, V3 }3 a' c/ f5 d2 ?我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。) u* N! s* G5 ~# O! h. Y
1
0 O8 @$ w( [9 I" Q9 j* _& F; s1 e2 c5 }2  N  z% B- M' P+ w1 F0 J: w
3: U5 J6 e8 [/ i! z7 D# F  U
4
& v- }! q8 P. z% ]( f. r& z5 z58 O" }4 D) ^$ r( _+ o' H' X
6
# Z( `; V- h6 D- Y7
* B8 T6 g/ g7 j: h5 \9 [0 Q8. S6 q) ?; F) j! _( }+ V% m+ P6 U
9% p4 ^6 P- A9 O& N3 J# z4 ]: N2 S
10( {: m% U0 ^& H0 T1 U' G& E  g& Y
# peer0.org1( T& V# B( m, V* y5 ^2 x+ ~
docker exec cli peer lifecycle chaincode queryinstalled
" |4 W# `4 a- c- j+ w& Z9 H# peer0.org2
' G9 R. J  t( C4 t: T" @3 Tdocker exec \# m4 U8 Y. [* h( X! A; X
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
8 g4 P( t( W, D) E# H: z  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \. `0 E" W& [$ J' c+ ^+ K! S
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
5 ~- [1 [% C1 Z  ^- E: v, 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 \$ ^  T, s& v: s0 }9 M+ T; M' K/ \
  cli peer lifecycle chaincode queryinstalled3 @) k' p& V. A6 l1 ~
STEP 4:审批链码
  a+ ^1 C& N5 [0 |- v5 h根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。
* K0 }, D* O1 m首先是Org1批准链码:) d: p, U) h+ X7 N* H& I. W$ t
1' u9 }$ e2 a7 s- T6 i; E9 E& F
2
5 u7 v: O3 d+ [; h+ \) r6 A, i34 _1 ^5 M' W% P) H7 l
4" {5 ]* r) w4 M+ O& b1 T$ v
51 n+ K7 j/ {; S1 V- ?6 T  t2 a
docker exec cli peer lifecycle chaincode approveformyorg \0 o' A; \; X# F, k$ V
  --tls \! R# Q; h) t" b6 z0 ?+ z
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \$ W7 W7 \1 ?1 L6 n/ U. m5 G
  --channelID mychannel --name mycc --version 1 \
/ |/ D1 Y5 {# g0 `4 k6 I. P  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
- N0 W) f% W8 b0 q8 _4 }

6 o" N* w# h1 O- G2 |8 _9 ?如果我们现在看下peer节点的日志,可以看到出了新块#3。! @6 i" W: n. `: i
类似的,我们让Org2批准链码:
3 [- ?% q! ^: q
14 ?7 A9 C. Y* f% m
2
  O1 t# P1 X0 i3 A# B! d# a3
3 m. K1 F$ P$ N2 F4
# i+ t" V0 E5 R( V9 |/ m5 l5& ~# k4 \) y. I% E9 o. R
6
- P; _8 S7 w7 o9 T! d2 _7
$ F$ D. O3 i6 o* }8" t: k& j+ H% R( Q$ @6 F5 t8 A2 T
9; Z! [# ~) M$ m/ g0 ]
102 h, T0 T0 p; O0 t2 a
docker exec \
4 k. w7 a3 T$ w2 J3 m  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \" ^* o4 C- @. T
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \, u( A$ z+ l( r% m0 }
  -e CORE_PEER_LOCALMSPID="Org2MSP" \2 q( v" R2 T/ p& ?5 J  e# I
  -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 \  l8 V* [/ r) M8 K; W2 o  H1 O
  cli peer lifecycle chaincode approveformyorg \
  }! x- K! g2 l8 y  --tls \
1 y. \, G/ \, X. V7 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 \* S+ ]6 s; E% c6 R' p
  --channelID mychannel --name mycc --version 1 --init-required \
8 o+ v" f4 X  p, u  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}0 N/ R  M* [: ]
7 o5 Q& t6 a; @, I6 P; o' m' D
不出意外,可以看到出了新块block#4:! x, C8 G) Q; ~& B6 d
注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。
( x# E  d% N6 L0 p1 Y7 C" T, J可以随时使用如下命令查看链码的提交状态:
! d, _1 e2 K1 h( b2 U; C$ O
1
' h9 s, H3 e# }" N2' ~" \) D5 ~8 c' O3 T1 ^7 `
docker exec cli peer lifecycle chaincode checkcommitreadiness \
" ?8 o6 l2 E0 _, X, n7 |  --channelID mychannel --name mycc --version 1 --sequence 1 --output json4 m1 V4 t; [' J! f* \0 y4 E- X
* }. Q- n7 q# Z8 f3 b
两个机构都已经批准了链码,现在可以提交了。
- c$ J4 B& i1 `9 \8 @! TSTEP 5:向通道mychannel提交链码
3 K# M( j, M7 w- f& ~链码提交可以在一个peer节点上完成:
* a2 f* r4 ^& j0 w( t
1. i" `- ^. R. a- Z
28 k# M0 i! o! S6 x
3
/ \0 I( d; e8 B7 x3 O+ ?0 G45 b" ]" D3 V1 B( R- [7 n5 R1 e
5
; R, S1 a$ S3 C( F65 M5 Q' v0 ^  Q5 x
7
. U+ ?' j0 U4 Y' \# Z' w8 N8
" f& y8 I' m& a/ }* Q
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \: Y+ ~9 O3 m) K2 E
  --tls \
" h+ N( w' T2 P0 n; 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 \
& C- U: X. }  V- W! b4 }% Z- b  }  --peerAddresses peer0.org1.example.com:7051 \" t0 C/ q1 N3 m. l4 N/ ]  ?
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
+ g2 m' d& [4 U1 Q  --peerAddresses peer0.org2.example.com:9051 \
; R+ @4 y  u& |6 o. ~  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \* ]9 V! o- |4 }; {& a
  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required4 F( R& r, e8 J" T( Z0 ]' b

( E1 H$ F# e# L: J* s' w3 J8 @! m' s可以看到出了新块#5:, W( D( }. N  I8 H- E
注意我们在commit命令中已经包含了init所需的参数。
3 ?0 l9 a" A, V# @1 P6 E同样,我们可以使用querycommited命令来查看链码的提交状态:6 I) N  D' b' C
1! D, k# i" g: _5 H
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc9 Q, V# K" v" q3 s# o, M
5 I# j6 M3 g) ~
在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。
! n: x; ?1 V. X: zSTEP 6:调用链码的Init方法
& a5 A6 E& M# Q7 y; ~3 N& JSACC链码的Init方法需要首先调用。7 E8 v/ X# e" T4 X) ]
1
; Y) G1 e! R' A# A, n5 M2: f8 ?# |% e% f/ p  ?/ f8 A" X# D
3
* \( C; n0 x- [$ N: \49 ]+ L0 W. T, S/ w" v
5. e" @/ \& Z1 d' C% h. B
6
0 a& p5 c1 S. `- {! `/ a2 F- K+ Q79 C$ ^2 }# Q; j8 Q6 ~
8, \! N1 V" s. X  S3 a: B% h
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \
6 U# Y3 T' v# c  --tls \
+ ~- b2 M4 b- I( c( {2 D; 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 \# K* C; X9 G1 x5 \
  --peerAddresses peer0.org1.example.com:7051 \
) @4 S  l$ g$ W  \3 A. X  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
* W5 Y1 c1 u( Z( v: f9 A2 W, u% k  --peerAddresses peer0.org2.example.com:9051 \4 L( R, p0 b, y# R( B% E2 _- U8 C
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
6 d( a0 n  Y. O% o# o: d% h. L+ E  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'8 f% x: g$ B5 j. w: ]8 _3 F' i7 W! ]

' y3 Z% F% M8 T$ [现在可以查询 链码:& X4 I0 f3 ?/ L5 e* s
1( c& Y4 M5 k9 B4 @: b( D
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
/ t& d+ x" R# v7 ~) P

  c7 Y( \1 v9 V1 M) C4 uSTEP 7:调用链码的set()方法并从另一个peer节点查询* l2 l8 H4 f( U3 j! P. o( ]4 Z
和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:; V, l; e# J; h' O. _
1
' ?1 O. M9 U9 G26 ^1 u4 D8 H& ]: q
3
( D& ~$ {& h. j6 M) p4' s$ a2 |5 n0 e' M
5) k! n6 s1 ]' Y) o
6) O- H* ?4 H5 ^1 ~5 ^& R
73 ]; T' {& t) W
8
! u% k9 E9 n2 u, i# M% I9
: m) c# u8 E( c$ X# T10  e7 ~; a1 ]/ l3 V
11
. V. m: ?( }9 |5 t7 d8 _120 I; n. \$ k# p  |; s3 E4 a6 x- k
136 \; H9 G+ f8 s5 z+ s
14
2 L7 g1 o; n- A" _  A5 n0 q15
& I6 O. D& M6 k! {16  h4 Q; g' Z  N; j# J7 k& h
17/ q3 d5 z: F) v& |- Q
18! l( w2 q0 {. `8 t0 R
# peer0.org1' C- \0 A) z7 I- s2 `7 S6 _7 Z% I
docker exec cli peer chaincode invoke \
  k/ E. j, @5 [7 K+ p$ G. m; ]  -o orderer.example.com:7050 \, S+ d/ J8 o; y( X6 X( {
  --tls \2 ^; f; _/ K7 d* K% _
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \9 @7 @+ e5 u+ b/ e
  --peerAddresses peer0.org1.example.com:7051 \$ s- G7 i; e) @% d+ l: ^- P
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
4 M8 \' y/ q+ S& `  --peerAddresses peer0.org2.example.com:9051 \
7 q7 N3 Q7 A6 K: I- M  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
! ~3 }+ l; V+ K) R5 u2 m  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
* i$ B+ E$ W; c0 {/ G7 |  - o- f! C4 ^# |% [
  # peer0.org2
' x& d# f8 H) g; y- S- l/ G' ?+ udocker exec \  y& A! Y# C$ F3 {* I
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \0 z* ]8 f8 t2 y5 N
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
4 J0 X6 `: ]$ o0 e  -e CORE_PEER_LOCALMSPID="Org2MSP" \
! U& H5 w1 K# r: I7 L% \$ j  -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 \
4 m* i" _& h" K: U4 J$ w: S  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'5 Y  S1 s+ D4 W( \7 R* L

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

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11