Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

青丝暮雪780
193 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。
; I3 q7 n+ U( z. u1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。5 m) ^) \# @# V6 h
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。
: A/ n+ U- A9 w- [1 p) w2 M下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:+ O" @9 ?. [) j" D
在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。+ n) {3 l- m1 D) D" `
在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。- N7 l3 E) e( ^  {+ ]
Fabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。4 L; x  l2 K! z1 v' E& N
下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。
. C; s" a5 K/ ~宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。+ C6 e' `: {3 h8 x3 A4 R5 A
链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。3 a. j/ T& s5 ~" y+ ^
安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。" v" u) n$ p& ^( m! ?9 Y# g8 o
机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。. P( s* F" v& ?/ T
当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。
% U" Y' O8 m# Y在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。
! [% v1 {# o' {5 k链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。
  L7 f( n* Z+ v6 W4 a! C现在链码就可以使用了。* \& C7 u9 q0 F& E* T
2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。
% K. M; d& m$ K5 rFirst Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。# c2 m) c( v9 z( _2 Y
SACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。
# F" Z0 T6 f4 {% p好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。
6 a* R8 u6 k. t  I( _" u3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。
: i: m6 t! O1 S- s# _下面是演示步骤:
4 g* m* H( W- _) [! B无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:4 W" F9 ^* ^! `; X1 v7 M5 ~
12 [5 c  T  `/ h; Z) l  b  c7 U
2
( [; `0 ?2 |( h, T2 `
cd fabric-samples/first-network
' N" `$ K! P5 S./byfn.sh up -n
2 N0 D4 h( {) K- O$ a
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。
/ l- t' y3 g. o4 t) Y% |% u现在我们可以开始链码部署操作。* D; v0 |1 Q$ f4 b. k1 V+ B
STEP 2:在指定peer节点上安装链码
9 E0 B6 s" e( J1 V) w这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。
) y: [  s  }) L) t1 B
16 B& C) N; t: _3 i! k
2
2 F' }! E7 R$ p7 I6 n) Y3 p) Y3! }) j. }2 w$ j+ H, d0 \6 e2 T
4
* }0 |( s! ~# a5- C: C! t9 Z' G: i& J8 g1 O
6! s5 ]/ ?& H6 u/ }# ~
7  ?* c$ a. g' ]: s1 d
8" Q$ F* E" y; c3 H
9& g3 Z, W; ?9 x5 ^2 J
10
2 g; N2 D1 r. J; w/ v
# peer0.org1
4 O' Z% Z: h& Tdocker exec cli peer chaincode install -n mycc -v 1 \
7 t* u/ v( X. D" u3 B, Y! s" z& U  -p github.com/chaincode/sacc
) l" U/ U* L9 N$ N  : G! l* Y. m, N+ p# r0 L
# peer0.org2  5 S1 G8 U+ n$ f& D0 w8 _$ t
docker exec \
7 {0 u. [! k0 k, E3 R  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
4 I. ~4 h6 q  Z, H  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
* K* e$ @. B- ~5 r5 ?. Z) 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 \
% p9 T/ K' X4 ]# x  G  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc# `! X9 E- I$ ]! c$ g( s

' [7 G& b2 e) `1 z) A" Z) Y0 ~STEP 3:在通道mychannel上实例化链码并查询6 m- c5 f3 f/ \% Z
注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:7 c+ C* @4 @& b$ [7 N
1
# n0 V% N0 e+ J( s  M2% B6 a' `* m) M! \# w+ X& z
30 Q& K6 c+ A/ u- Y, A
4
2 }: Y- D3 T+ r
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \
. t. m& z9 B. K1 ~* _: O  --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 s! T" s  {5 s, |; M
  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \! D0 Q( w* o% ^" u) Q
  -P "AND ('Org1MSP.peer','Org2MSP.peer')"( N/ N' w* t2 u8 g/ A) ~6 z
2 f$ h% q6 e9 ~
如果现在看看peer节点的日志,我们可以看到出了新区块#3。/ C. ^+ m; f2 ?; B& Y  p; L
在链码实例化之后,我们可以查询:
1 V! G: K) p+ i3 T8 }+ n0 k9 i. c
1: j6 y1 I$ [  Q! u5 E# ~
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
8 E/ r9 w& _6 N

2 g1 q( y9 r$ y! }; p! L& mSTEP 4:调用set()设置新值并从另一个节点查询7 Q0 j" r$ r7 Z8 h
出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。
7 v5 m( C( ]- X/ y% ?
1
  a- E. j; o6 h, w, M# I8 a2, O8 b. ~  V& k' Z
3
+ N( ?6 P' Q6 l5 q, d1 K! L% O4& @- T4 q7 z2 b* ]/ \6 ~3 g1 N, M
51 R+ ]+ _( }6 |8 ^; q! t
6# F  N9 t0 `! f; [$ T9 u
7
8 ?4 C6 B; w( g& [88 f" ?' K9 r6 C
9; @2 [0 f: A7 K
10; `2 Q/ d# S0 W8 N
115 b$ @6 l* C! I" n
12
* Z6 c6 A( r: t13: ^; u$ \- D5 V  ~% a8 C7 I$ {1 g8 \
144 O; z& X$ D+ W% X
# peer0.org1
9 M2 Y8 @& P6 I5 r1 S4 ~2 {5 V' edocker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \
) t1 L: U2 `8 C* g' 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 \
# l7 J+ c+ Z% l7 u# W  --peerAddresses peer0.org1.example.com:7051 \
1 E& c( {" U! ^  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
% Y+ H9 I0 ]( m: N7 N  g  --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 \
5 h+ A8 m' v  I0 |  Q9 _. f4 Q9 q  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
$ c9 M1 N. |% {  
% l4 U: }/ T4 b& L  # peer0.org2  H5 N% l; N, A+ M* X& r5 f
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 }7 }5 l5 j' B1 B+ g+ Y* a
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
7 w* I: V. M0 p2 q  -e CORE_PEER_LOCALMSPID="Org2MSP" \* g+ E8 e* _+ j/ J0 _$ \* ?( Q
  -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 \
) n9 y( t8 |8 R9 `, T6 Q  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'1 U0 {8 I& M; t+ ]
7 ^: H3 N, \+ ^% n& I
4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。$ T( F, ]& s$ ]$ q- w
下面是演示步骤:7 h& w+ ^: E  o# c' b" h/ J
无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:( R1 ^7 f1 k& y: O5 j8 V: I9 m! j
1% \( h+ E, c' Y
2
% B; |$ b% s/ E6 |( Q
cd fabric-samples/first-network
0 d& `& }* J2 `./byfn.sh up -n
; M+ L' K5 b  W# g5 y; w$ v
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。. T2 V$ l" s' D; g
STEP 2:打包SACC链码
! d- p; ^9 e$ o; @9 p首先我们处理依赖问题:
1 \% T# o+ c; b* ^% f: f
1
, c" n% K1 y8 h! X1 h2* K: X* [8 y: {6 P' y, b' B
31 f) v8 ~4 H5 I9 w8 [2 W8 `
cd fabric-sample/chaincode/sacc
9 f3 H- h# d& ~; ^- CGO111MODULE=on go mod vendor
3 _, t. ?# a" c! ~  G" Fcd fabric-sample/first-network, S, b# z0 D6 P3 V# B/ s& S& f
然后打包链码:
4 [& i8 K! |2 n/ m  y
1+ H  Y/ q$ g3 o* _/ t# A! U2 N
2
! L- C3 d% ]0 Y3, N/ Q' f$ j! N0 w0 B
docker exec cli peer lifecycle chaincode package sacc.tar.gz \
& F2 t4 q7 F% b/ l6 b  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \; O( `# J& K" N) E, t9 Z  R! E. t
  --label sacc_17 t+ m, ]' l, [
在CLI容器内可以看到生成了新的文件sacc.tar.gz:
8 j7 q" F' L: H5 o% RSTEP 3:在指定peer节点上安装SACC链码包4 U4 c/ x" R; a1 O5 ]$ o
现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。
0 P3 y5 x4 r( w  @& |
1
9 ]2 X) o- \+ ~2 E% Q9 Z: |2& f7 \" q4 A2 F2 \  M
3
5 ^! k4 p9 w. }* v) [# }42 W; ?+ b$ h( c+ I3 I
55 N/ T: C) e0 H7 A) F  K* X0 U9 J
6" |9 A6 ~8 `- c
7  @* O4 F7 u( v+ `
8
$ T2 }) G# F1 s  b! n5 G2 d92 l5 D% ]2 o, X9 E+ k; C2 u
10
0 R8 c8 K: ], q: w4 E4 b/ }' ~0 `
# peer0.org1
- ]6 m! t+ c5 `  e( u$ xdocker exec cli peer lifecycle chaincode install sacc.tar.gz; L( e+ o1 x- [- l+ m
# peer0.org2/ B: s1 |2 n. V6 c0 S# d
docker exec \
; y8 t2 @& c' y. b% z1 o  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \# _; x5 G, f0 W5 U2 v  F/ `
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
/ f6 N6 R# z2 O4 ?- j6 I$ G  -e CORE_PEER_LOCALMSPID="Org2MSP" \' h; i' R4 v/ v: ?
  -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 p) u  W- u" {+ Y- j. `9 b2 I9 Z' d4 o
  cli peer lifecycle chaincode install sacc.tar.gz" Z# z. h: X8 o) ^9 F
5 n# ^( ~& @5 S( ?6 X: {
我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。
" g7 `2 g" c% {; {' u- R/ F$ \我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。
* [; p0 l! y8 D
1
1 w5 |9 p- E' H$ d  e8 _2
2 _1 C* L& M+ {% g. l* s3& W8 Q5 I5 a% k; Q2 D- p
44 T& s2 L& V$ L8 X8 g, Q0 E! n
5
! q- N7 W# Y4 J/ J9 H# w8 v6 Y* @6* y) u; t& x, }2 i
7
: L  D7 P- R$ z! K/ w+ }8
. _& ]4 i& F. o9 Z4 j) v# `9
  u# B$ `1 L6 v8 g10
" f+ V  q, b, @2 W7 D0 l
# peer0.org1' ~' g3 y: x; p. A+ _
docker exec cli peer lifecycle chaincode queryinstalled
& V: ]! B, v% E8 ~& ^- U, J" o3 Z# peer0.org2: Q7 [# e" e* ]( r; B1 H. N
docker exec \
) u2 a* w, |3 K6 t2 C  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
% {7 ~% o9 L  [5 s+ c, P  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \5 r. L, L. O$ g. {, t% i& F
  -e CORE_PEER_LOCALMSPID="Org2MSP" \+ ]+ c! t% y. u/ m
  -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 \+ a# G& C% K9 q7 G# i, O7 I
  cli peer lifecycle chaincode queryinstalled7 v( ^: C" ~# @
STEP 4:审批链码& h" N3 S# d' q9 l' I
根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。" }$ w2 S  I# `4 ~
首先是Org1批准链码:
  a$ o0 D& B- b" k
1; c3 k* L% @; t1 [2 j* r
2
7 r9 _4 W5 A6 y3
; X) H" g$ O0 ]. M/ |4- K! X! u* q0 {$ P9 n0 R
5
- J9 |7 C! ~6 t. _& G
docker exec cli peer lifecycle chaincode approveformyorg \# ?4 k2 T8 j- X+ U7 J* J6 M
  --tls \" f3 v/ M! W2 Z$ o+ }9 Q  z* 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 \
  f1 C% h4 l9 S! s. t0 F  --channelID mychannel --name mycc --version 1 \
, q9 J* F4 z. Z% _) o: T+ ?8 U) z  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
; y4 W" A* Y7 u6 N

) \3 r  X7 X! V( a5 ?如果我们现在看下peer节点的日志,可以看到出了新块#3。/ z+ b  q8 ~* g( P; w) W3 O" e
类似的,我们让Org2批准链码:- j4 h; h9 p. l
1$ |! G; G8 J6 s% T# R
2
- }  A& ^8 }: `( O3
) v6 q. b& X& w1 n& P3 H4
' p' W' ?. y+ o: d9 U7 u5
6 q. r4 u" o# O* ^! H# _6: }* `, Q+ i/ F* d
7  O  V  k5 R2 d' `
8
4 j7 R1 n* G' t/ {- o, k5 W95 t9 U# V& w8 z  Z
10
# R& W/ Y. s8 w) O5 a# M& m
docker exec \  ~/ ~7 K$ `3 X" O" A$ [) U
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
3 U& ]5 G3 N: Y! w  B  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \3 \8 L# z& R* r: q, v5 D/ r
  -e CORE_PEER_LOCALMSPID="Org2MSP" \+ O2 ~4 d, C1 ]' S
  -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 \
  T5 a9 N' ?/ Y" g( _  cli peer lifecycle chaincode approveformyorg \
  C; L6 t" N. y0 W  b7 j  --tls \
) a. n  `0 ?' E2 i7 {% 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 \- _- m, ^3 u# [9 s0 m+ k0 E8 t
  --channelID mychannel --name mycc --version 1 --init-required \1 P) `, ^7 V3 t: O
  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}7 M5 l0 H0 V# G7 E+ s% s2 ~, w

5 K3 B/ k7 k+ `$ O6 u6 b不出意外,可以看到出了新块block#4:
" N- Z$ r8 p- E: ]  O; _注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。
- Z: s$ Z$ d  }2 [  R5 C可以随时使用如下命令查看链码的提交状态:2 f8 ?1 U2 a2 I( s
1
. h7 Q) X/ W+ B: ~" \) V( H: Z2
# B% n2 J8 z  ?/ }# [
docker exec cli peer lifecycle chaincode checkcommitreadiness \
& |; E5 j. W; s- M! v8 C  --channelID mychannel --name mycc --version 1 --sequence 1 --output json1 S' P3 a& ?3 q4 M( g7 b

: ?- `8 f% X( C% m$ |两个机构都已经批准了链码,现在可以提交了。' ?8 |- N: @8 \
STEP 5:向通道mychannel提交链码# r  ^9 T) F( c7 N% b
链码提交可以在一个peer节点上完成:
& q: s$ Y$ L+ A+ ?' n
1/ D3 R+ ?7 D3 U5 `' N
2; X. {3 \) @6 G6 [, Y) c) x$ O
3( `( l5 I* }; v
4: B/ _3 G1 L8 s. i" g1 x+ _
5
  _6 c# p% P4 Z% B0 f0 u) f64 m) A- {' z) a- W6 Z
79 I: O' r+ ]; \
82 W; L! s- X) i# t2 R5 [, s
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \% Y" h1 o, P! M) @; a
  --tls \# Z0 J, {/ F9 ~# w; C3 ?! N
  --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 Z" b' L( V* |4 t. B
  --peerAddresses peer0.org1.example.com:7051 \
# K" d* Q5 O, C1 _  {+ R$ q  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \1 a9 Q) k6 Y4 U! y* i8 ?4 B
  --peerAddresses peer0.org2.example.com:9051 \+ a6 X: k5 r$ M7 P5 [: u
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \! e- d" N9 ]4 f  m5 C& H' J
  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required
8 z& j" y1 r5 m0 o9 s
. s' W8 J/ j8 n% k4 s  e2 v
可以看到出了新块#5:
+ ]6 f. P* X" l$ ~$ {注意我们在commit命令中已经包含了init所需的参数。
) M+ d9 }+ x1 E( C4 |同样,我们可以使用querycommited命令来查看链码的提交状态:" S/ Y2 O" l2 r8 q8 u0 g
11 O. N( u3 n. q5 ^7 j
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc" ?7 M' d, y* A/ N' i

4 `' @9 `- w" o$ ?8 u. ]- W! @% o: E在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。( j) g! d( R6 Y: n
STEP 6:调用链码的Init方法
8 b# U! P3 ?! Q" m* H# p0 TSACC链码的Init方法需要首先调用。
% B8 f/ J$ l( R
1
6 T( M, h/ G) n6 J- e8 n. a2& ]- d* z5 E& Q: X
3
+ v2 G- P0 @- q& r, p3 d4
  I& v" n' H# d( [3 B+ T+ x5
* e) s5 @5 T9 E2 b6
  s2 t( x5 O  k71 T5 J4 L. h1 a/ t
8
% c% j' W+ W' n. Y; [; b) R' i
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \' c/ g3 T, U5 X# s
  --tls \
0 c% W& Q. n4 f/ Y# @  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \. U+ r  Z9 X9 w3 d2 k( m
  --peerAddresses peer0.org1.example.com:7051 \' l8 M" c0 s8 `6 I, Y
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \0 S9 z' z  O2 f% H2 W; ?
  --peerAddresses peer0.org2.example.com:9051 \
6 b( f) b5 x/ g) F+ l  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
+ D+ d1 z4 P+ g5 s. Z  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'/ Y% Z; q9 G  O$ f5 q; o: Y

2 _& g! [2 o) Z' Q; K% Q  O1 x现在可以查询 链码:
/ E0 {, n) m' c$ |
1
- N: u5 E9 i8 B3 \. @+ J) r7 L8 B
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'5 J$ w' k0 ?( X' U

+ Q9 O; G5 F% |( D- Z: M) gSTEP 7:调用链码的set()方法并从另一个peer节点查询
6 F* u! n$ g' ]  b3 h# q: Q: [' I和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:& k6 d) B4 g1 B$ v1 Q8 n
1/ b) `9 T1 j3 T' M, E
2: p- R4 u) \* M0 w6 A7 m
3
0 k0 b5 M0 }8 `; C" m4; Z. L3 c& }# B: K% |. e) `
5
% ~- w' m6 A! x% w6  V% m. I. ^% s# E* d
7
% c( Z$ s4 J* R8 p8 d5 g; d8
3 E8 m3 v7 Q7 q! I, J" n; O9/ v" }& A0 G) }
10
( ]6 ~3 a9 P' j* A9 Y" S& ]6 @# ^11
) J8 A2 \+ P5 ~& V+ k12! e, I6 x. Z2 V1 z6 a
13( x& b! l% a2 _% B5 X' J
14
( h3 ^" i6 V9 r* `15! i, P5 L6 l0 P, p, _/ l8 U" X$ t
16, k  a" ^- I5 Q- ^4 b; D, ~
17+ {0 b4 K# S- [0 P( r
18* _) _5 {( ]# n( x
# peer0.org1
1 ?" Y1 d' b& Jdocker exec cli peer chaincode invoke \* H2 F3 B" x' B) t4 u
  -o orderer.example.com:7050 \
* P# P5 C5 [$ w) S% V: w8 H  --tls \' t2 l" h  D! Y& v" N
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \1 H$ _# O' J- r! S
  --peerAddresses peer0.org1.example.com:7051 \$ G' J  F5 Z- F7 q  U) A- m
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \! M0 J& E2 O0 D) m: K5 t. m
  --peerAddresses peer0.org2.example.com:9051 \+ t( f; u5 b. y( S4 Q6 A% l4 E% f
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \; N  p$ B; X. z0 x  I$ T" K4 f
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'1 J* s1 x# X: @1 Z: _2 I% ?
  7 v) h/ d5 B- `$ W
  # peer0.org2, |8 s# ^8 b9 W% M+ N4 @6 D
docker exec \
1 R( V5 x  y! H  e$ A# l2 I5 j, q  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \  W) R8 i! ^2 U5 ]" i: o
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
6 t: k2 A2 o( R# x& }+ d  -e CORE_PEER_LOCALMSPID="Org2MSP" \) V, D, o2 v% ^* C2 m; R
  -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 H# N# y0 W& t; ]( N2 v  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'$ I! v2 O0 o9 s: i5 t3 _
3 K& T+ z  j+ T: b
一切正常。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11