Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

青丝暮雪780
242 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。
# e1 k0 H9 ~: n: |8 K; v1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。1 q6 c2 e. |  c9 ~
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。* n: [- S# E' P! C& B  n
下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:
6 t9 b1 z2 ]3 ~在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。8 C) A  t, f( V
在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。) @0 g/ \0 g6 P/ x3 o8 G
Fabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。
" u  _- N2 e/ S+ n) a, N, k4 t下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。
5 w' Z" G- G7 o1 b' n宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。
" b5 t6 l% C" _* Q, B4 W链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。
  a  ]& ~% C& j! w+ A安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。# X: g; G* n' X7 C, F
机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。6 Z6 Y  c. A% G7 x1 {- y
当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。3 C( |! p4 w- W) g) A/ L( t; b
在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。
/ Z4 L, l) R; W6 U( O- p链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。
/ J5 p2 n$ c9 w5 M3 d; m2 Q/ }现在链码就可以使用了。$ t  r: r9 N% ~
2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。
6 \  P$ F  A  d2 D9 @2 \First Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。
) V# b5 r' u5 y1 ]8 n) x% C+ U+ nSACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。
/ A, z. U1 n, e2 I. W好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。
) g9 K9 {# P! u( t8 V. m3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。
* s; ]) Y0 @/ T下面是演示步骤:
6 B4 L+ i* H8 ~: u0 R' ~' O7 I" i# L无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:
# t" m6 _2 Q" S  l; ~5 K
18 w" [5 Q. G: G9 w: W: H
2
! g( n* @9 @) [  w7 O  T
cd fabric-samples/first-network
4 @: |' f0 M: |3 L./byfn.sh up -n
# m2 {" I% F  v. S
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。; E, S2 t( L7 b* g7 ~
现在我们可以开始链码部署操作。: _3 O" h' T; `9 g! F
STEP 2:在指定peer节点上安装链码
0 d0 ~% `0 B# G/ n! q这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。" V2 S7 _1 }! I$ K. O! a
1
. p9 l7 B/ `5 u( I2
& ~9 m. q6 [, `' M6 O38 l. [% T7 H1 S- `, c6 i
4" G0 B6 G- D& \# W. ^
5
  x4 F" M( E: u65 ?/ J- w& ], V1 c6 O; o$ M2 q; q6 ?
7
) q- m! B* m$ d6 t8
; `6 l* [( F. r4 Z# w+ i& {9  ^4 T( \' V" A! R5 x6 Q* A
105 H" n9 f& s: c7 M  o
# peer0.org1+ \4 `7 ]  p# P# y/ r6 T2 e  r" o
docker exec cli peer chaincode install -n mycc -v 1 \. R+ k2 @4 L7 Y' U0 I8 ?" ^
  -p github.com/chaincode/sacc
  `5 h* M" ]7 X' K1 m/ U  5 i7 ~9 V, Z- t; v
# peer0.org2  
  A( d7 V: E7 I" J) y7 `+ vdocker exec \) I- v+ `! ~8 V, }0 G' i0 S3 O
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \1 G5 ]9 ?  }/ ?7 z+ k- d" t+ e
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \2 d6 O  r4 M" i0 r" ?+ 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 \' s6 b( s; C/ c2 \5 R
  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc7 H2 Z! ~& o0 G1 }+ l

/ q. O2 K, a0 n& E3 M2 _8 GSTEP 3:在通道mychannel上实例化链码并查询  n4 c& p% R# B. T
注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:
0 e1 B# \$ @* ?! b- {% U, e
1. |' \) |0 c! @) @! G& L
2
5 C9 p8 G. v% p) @$ H3
! r/ z' V; [* L: K0 q# G" A$ @1 h43 ~! A& L7 `2 w& v) d9 o# A! s" I
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \
+ F6 |3 P5 Q. m3 j& ]  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \$ `, ^: x, N# v* v
  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \) s, R$ Q4 X, @+ r, D) ]4 }
  -P "AND ('Org1MSP.peer','Org2MSP.peer')"1 v* U9 i( O7 o5 d9 _+ h2 \

% w# I2 P3 M  i. [* }如果现在看看peer节点的日志,我们可以看到出了新区块#3。1 q# ~1 D. j# j, r# x: E1 B1 L
在链码实例化之后,我们可以查询:3 D" a" x! b3 P5 N- z6 T+ ~& r
1  G2 k, y& R- T2 e$ l
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
3 h' x% _% Q( o$ _: r3 X; ?

+ U9 a; j$ q& h$ x# g, d; v. wSTEP 4:调用set()设置新值并从另一个节点查询
- {: h# e  ]/ H) F, y0 @* I, \出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。
1 C. h1 R- X& \1 t1 `1 F
1
- T7 K' \6 @* B6 V# |: j9 I2
( K. a0 a# {! G; Q38 H  t7 [% K" Z* E# v. n; d
4  `5 z3 |: b8 d, t0 |* z: i
5
1 L+ j4 K* b/ a( M- d* ~' ^! a6
( W. h/ X1 [/ S0 d! @8 x* b! h7" y) v  x$ `2 L% `5 n' r
8
# X* h" n! G- Y- G9
2 _' q5 y* t* F, `# T10, \1 M0 g4 ?8 x6 @3 W/ I5 w/ e) q
11! d( R$ S2 f9 W3 v2 m& y
12
' f  ^" O- }. s13( ^) \, B; ~, U  n
14: g* W# F# z; w. k
# peer0.org1
) _/ U2 B( X4 V+ ]% _docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \
; J* o- I6 d' ?9 z3 i1 [0 g1 C( h  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
+ y8 e# r0 n) W5 t* X; {  R  --peerAddresses peer0.org1.example.com:7051 \
" r' t# M; v8 y  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
# K7 s5 [( y6 I9 B  --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 \
# m5 L* ?5 @  [  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
7 u  t% c6 y& L8 I4 n$ K& h  o( @  
" b" O1 x0 v( o. r5 v  # peer0.org26 n9 t! K* N) I6 `4 i/ Y
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 \
8 o; ], o3 D) w+ L$ E8 [  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \3 L9 e% v7 ~/ E5 {+ W! }% T# K
  -e CORE_PEER_LOCALMSPID="Org2MSP" \- k8 z  j/ ?6 L3 U1 V. 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 \
* t7 ]$ T1 C7 P+ p  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'& ~# k5 [% a# H. F) o, c
8 n" @) u) p8 y, j/ _8 f# {
4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。
/ S) l$ v" w5 C/ ~" g" M下面是演示步骤:
1 z8 J2 D0 ]1 Q& ^0 R8 [, _8 P( E无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:& Z3 x" E. {2 X6 ?3 z, _- N
11 E. Q( X1 `; }. L9 [; V
2
& ]9 g8 E& @. \6 x" l/ K" d+ v
cd fabric-samples/first-network7 i! P" j! g) D! @* c/ H# E& }
./byfn.sh up -n
. V) u3 V+ B. l' a! w* d
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。' g& [8 I2 I4 }7 t3 U3 [
STEP 2:打包SACC链码) C( ~: Y3 Q2 ]
首先我们处理依赖问题:, h4 r* p1 V) ~% }
1
( \# |% E+ D9 J" l+ W2
5 w1 a$ n2 h; N' N3 ?9 [3
" H/ r0 m0 p/ d
cd fabric-sample/chaincode/sacc
2 ~9 u, \3 L4 G5 K& ~& h( M' aGO111MODULE=on go mod vendor1 i/ F! L' A" H5 W$ K
cd fabric-sample/first-network
5 e8 F* v+ P! A
然后打包链码:: @! ?* t% M8 C! q: N( A
1+ D4 j, a$ n7 H7 F3 x) d1 ^4 {
2/ D6 r( b( F& Z& }4 \
3
3 d' T/ F+ C4 F. q1 K. Y4 f. P# ]1 r: |
docker exec cli peer lifecycle chaincode package sacc.tar.gz \$ z5 K. G5 ]: F5 {4 Y" P$ K
  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \
: w0 o* l* b/ F5 u1 g  --label sacc_1
% |, b6 y% A7 G
在CLI容器内可以看到生成了新的文件sacc.tar.gz:/ `7 u" g& A2 N. z/ H9 R% C
STEP 3:在指定peer节点上安装SACC链码包
7 M( n9 k, E* C; g" y8 R5 L现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。
' i" v0 n: g9 i5 X7 ?8 O; U
1+ Z7 ]$ B' M7 l' F0 S
25 b0 y* Y7 D# ^0 p7 p
3
+ u& p2 H# y# u0 K5 i4
" F  ~. @# b1 d3 g& K! D5
' C; \, Z/ d+ _& T5 {% n) J60 l+ Z5 \% R8 {' g) j
7
* ]  |9 q4 d, |8 h9 `: a5 a87 P2 r/ [) K% A. ]1 N: q! |
91 D9 }+ p7 D& C' O3 ?
10
  T% ~  j, j0 o' r) @/ F/ K
# peer0.org1$ }0 q$ a( Q. u  M" b: ~& A
docker exec cli peer lifecycle chaincode install sacc.tar.gz
9 X+ j$ R3 t; ~/ t# peer0.org2- m$ \) i' T4 H( n; a+ c
docker exec \
# c4 f- P4 Q2 F! u) s1 k3 J) E  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
5 L; n) R+ `2 i9 {8 `2 h; J  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \) A/ a0 x4 f5 n" W0 q; U
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
" v  w! q4 O" K  -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- B3 \9 @+ q( L  cli peer lifecycle chaincode install sacc.tar.gz
8 Z  W% m% Q0 @) C
8 Z' J. F; I! X, F" X8 [
我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。* e/ q% }! I; |8 _
我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。# o$ y' g( X' N1 ]
1
% N( _6 A6 V& x* f& }  j  _6 }" U2' L- l4 |7 t/ y, y1 s; t( f: }1 f+ L+ F
39 R3 q2 u9 m" T: ^( P6 H
4/ Z; h- v6 e& P
5
( U% Y1 i+ H$ V) d  i6
" c# b% p- `4 W72 c( `7 j9 B$ Z8 r( q* O
8- Y! s. E2 J6 j# I: C
9, O) l& d$ B8 Z7 G
10, [% D, w) \! J, {+ E" O2 k! w
# peer0.org1. N& \1 V2 O4 P6 n7 o
docker exec cli peer lifecycle chaincode queryinstalled
' R' Q/ T! y- t! r) x: B7 F. ]$ a# peer0.org2- f$ X# Z4 a% ^; W5 _
docker exec \
3 f9 Z8 E* [; @6 i8 [  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \9 _9 p* M3 N& [. a) B6 l2 E: y
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \% g, V% x9 _* `
  -e CORE_PEER_LOCALMSPID="Org2MSP" \, e$ u7 }5 ]5 I4 U+ W% }" u
  -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 \
  A1 L* P, j7 b" ~7 Q3 _! a" n0 Q/ l5 `  cli peer lifecycle chaincode queryinstalled3 |- ^1 b' O% K8 g6 T
STEP 4:审批链码& i9 A* u, w2 E' L9 t
根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。# C. C, q% G: y0 N6 }. Y5 E
首先是Org1批准链码:
6 u- P0 R$ [7 u! z) _8 K, j1 l, ^9 _
1
" |  D; ]- B6 c. v" F% I! J2* @+ i# t8 N4 N) [9 X$ h
3& G. b7 E9 _* A2 X
46 R) ]; J: v4 w& a6 a, ]
5* Q: X1 ]- c5 s
docker exec cli peer lifecycle chaincode approveformyorg \% }3 {7 E& E' d  j6 e) \  o/ D
  --tls \
" @; }: ^2 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 \
$ y4 _, A/ n8 d; K2 P* W  --channelID mychannel --name mycc --version 1 \
- R( d% [" D4 z, j& |  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}5 L0 d" ?: e4 _1 {2 M9 R

+ y8 ]+ a- L. o; W3 @6 a2 ^如果我们现在看下peer节点的日志,可以看到出了新块#3。: n3 H7 ^+ K0 r1 U+ W! _, E
类似的,我们让Org2批准链码:6 _5 y3 y! Q- Z. f7 a
1
& {# y( r2 _5 D7 }- B2
( q6 l* b6 {. }% j7 R) a  J. @3  m4 _8 b( B. `9 k. N: ^# @0 w: H
4/ t# J' G1 X9 n( g+ ^3 k+ ]
5
0 ]0 ~4 G9 B: b2 K6
1 X7 ?% L2 a& W; t( X, j- W1 L7; E$ ?6 K) e9 J# a( \
8
4 L3 A6 l) D( |! ]3 t99 V+ v, r. _% U+ E6 t) ]
10
. E& j5 Y, O' z3 S* O9 }+ K
docker exec \; r$ L- R3 j* R4 K
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \- h7 _. ^: Z, Q/ ~7 b) D& H
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
6 Q# q6 v0 E- J4 Y; d  -e CORE_PEER_LOCALMSPID="Org2MSP" \
  |. _6 G- O0 Y" X' X  t4 U  -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 \9 O" e6 l0 G  ^6 W
  cli peer lifecycle chaincode approveformyorg \
$ J! V# g9 @! g) {$ R  y  --tls \& S9 X9 ?  F- ?; 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 \8 u+ H+ [) C$ p5 W' {/ ^
  --channelID mychannel --name mycc --version 1 --init-required \
% T# `% G% P3 s  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
. y. }" _0 m9 S+ u( d( X2 b  M

$ b9 x. K& o* d不出意外,可以看到出了新块block#4:. I; O0 j! _8 v0 V( n
注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。) @  L$ _; j2 o& i7 \
可以随时使用如下命令查看链码的提交状态:/ y; f4 D3 e" J) K# X" g" J( ^
1$ r9 F" l3 o9 R# k
2
3 b4 ~8 p1 O  U5 `
docker exec cli peer lifecycle chaincode checkcommitreadiness \0 L  |$ Q0 S- k
  --channelID mychannel --name mycc --version 1 --sequence 1 --output json
" h0 t9 ?* w: ~% K' M5 q5 M9 v
) K$ i2 |2 x& W1 ]! F8 E
两个机构都已经批准了链码,现在可以提交了。6 w! a) O1 j1 o( l- J, A- I
STEP 5:向通道mychannel提交链码
8 y. |6 o2 `( ~0 ?/ Z  p链码提交可以在一个peer节点上完成:
, l: o7 M- ^* f4 A6 r5 r* g/ [
1
; m- k1 b, `7 g1 l6 _0 w2
5 d! O/ O8 [: a9 S2 h) u+ h3
6 ?  Q4 Y2 ?7 D4 h8 i1 J8 _4
- ]( d- R4 ?8 Q55 t! P- v2 x4 y
6- ?9 }1 }0 {) j8 o" {
7. V7 |& P# y% H$ U% j
8! M/ _( @( P4 x/ \
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \& O2 F$ I( X1 t
  --tls \
8 m' ^: E4 h6 [  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 \/ j/ }9 o  R  q0 X4 _, p1 h3 u
  --peerAddresses peer0.org1.example.com:7051 \
9 _, e; m8 X' c* k5 ^  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
9 m. G) ]! t4 o" R  --peerAddresses peer0.org2.example.com:9051 \! C& n% v6 t' V
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \! o* H; A8 b6 [) p
  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required
6 w8 y6 S6 n$ B6 H  v
) S1 C$ q- K8 b' z: R  d: x, R
可以看到出了新块#5:* E  I/ e' g- O# `% ~
注意我们在commit命令中已经包含了init所需的参数。! a5 G; A8 V" m, I9 r/ @, g1 F' r
同样,我们可以使用querycommited命令来查看链码的提交状态:* D4 b4 o' ^3 l" v
19 v9 A/ ]2 x+ v! \2 B! X# O6 B. W
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc% i& C! r/ p& q1 M+ W. g$ C, H! k

& {8 a/ y* W+ ?1 u在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。
5 Q! V4 Q  X& x3 S+ }6 Z: w! |& q+ eSTEP 6:调用链码的Init方法+ t6 C# ~- V* |$ a. o' a
SACC链码的Init方法需要首先调用。
5 N4 S" P% l# B9 P0 g) ]
1/ U5 `# U! o/ j' j/ r' e1 g0 I& n
2+ U& V% B# k3 Y$ A/ M6 o9 \2 F5 K
3
1 X' s% Y- s; |! I. p. S4
' \4 k/ e. `4 D9 B6 s5
( e% S! p- z5 d  v, z6) S1 ~; N. J6 N" `9 h
7, k) [5 k7 U' P) m* @
8
9 b' v+ }! q/ [
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \
7 V$ g) d- j0 n/ j* P2 ~  --tls \; q7 M6 S7 f" L" C# Z. k% q& \
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
' r8 A/ R' w3 P( Q: a8 [  --peerAddresses peer0.org1.example.com:7051 \4 ?5 o" J$ }. _6 Z# {
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \) b0 K& {9 r5 g
  --peerAddresses peer0.org2.example.com:9051 \
7 l( m4 i8 N4 H1 O& n! Q  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \( S( R$ E. a+ U, U, f; `8 Q) a& @$ f
  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'6 c0 B; C1 {0 Z
( T  A9 y# [) Q2 m
现在可以查询 链码:; v* C+ ?" U# }1 \
1
+ f7 U, K9 V7 i! h5 D. w7 M
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'  A) i2 m/ b% H$ J4 s% Y$ L

3 L+ T, ], [' s" S+ \STEP 7:调用链码的set()方法并从另一个peer节点查询% k/ S) y1 v, B) r
和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:( y# R! n1 n" u, a9 |6 C) L% x/ v: m
1
. J  L4 c/ C0 r) |: G7 @2
/ W! L  j& A" r) o3/ \- s6 w3 Y: M4 M  F8 `/ r8 ]
4* y; ~3 }7 [. I- |3 D
5- C  d7 E+ J+ H, l1 f- _6 q& W
63 Y6 G+ g% V* m0 u, e4 C
7$ ]( Q, D* A+ n! F4 I  P+ I# O
8' Y/ \( z$ ]( t- j) g
93 s* q9 p% |/ Z( m& I) O  z" N5 r
10
) D: l& U' q! e8 a4 R11
& t1 [7 a4 Z8 i+ Q8 y125 d! T+ c  A" v7 k, {& d, }
13
+ F6 t0 h+ l1 v4 [4 \14
/ w/ t" `4 y( `; T15
( P" U; y; Z/ C+ H4 p4 G16, y& `) f  A1 f( T) S2 [
173 O6 s0 D. X! V4 g# ~$ L
18+ C& X9 c# ?1 R% o
# peer0.org18 N3 o5 A( Y- z1 o+ l
docker exec cli peer chaincode invoke \
+ s9 b7 F5 w0 p: G2 m) O# m% p% ?  -o orderer.example.com:7050 \" X" @2 t5 e1 k$ H: i) [
  --tls \
# |) W' J1 ^- G# b4 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 \
% C+ f  J$ m' U1 a, O  --peerAddresses peer0.org1.example.com:7051 \
  ^; |6 t4 `% r8 t* P7 B  Y  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \! e7 z, S2 Q/ e6 F+ J* p) B* \
  --peerAddresses peer0.org2.example.com:9051 \
* ~  W: N) m% ^- O6 z+ U  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
7 P+ F4 v+ ]; |. ]  b/ S6 R  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
& C( j: n- X* V$ [7 ?  
9 O5 [6 ^% d0 A' T! L+ P7 d9 J  # peer0.org2; A- g& P0 C8 o* u! P, I
docker exec \+ c4 O* Q3 \. y! @3 F1 [! P* i  `$ R5 ^
  -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: e2 D# s1 A" c1 H- f8 W( K  G  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
( V& p, k. N, \4 i0 b6 U  -e CORE_PEER_LOCALMSPID="Org2MSP" \9 S7 M0 e: J8 Y1 C, G
  -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 \
0 u+ P& b  j1 c1 K: m' k5 v& v: E  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'4 m6 K% y& R$ R0 G4 Z

7 {5 d! b$ @, k& u" e8 @4 S+ t: }: i一切正常。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11