Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

青丝暮雪780
153 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。
" Z8 r, L# x/ n( r9 b, n1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。3 D( m5 h; m9 L  f+ v
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。
9 J: d; u% @3 B; s& h. U下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:8 M' d2 L2 x% J
在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。* e- a- O" x2 [, f2 G
在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。
. ]  O. `5 D* i* j% C  _. K1 gFabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。! A2 x% U$ w1 |4 B5 \& L0 n* J
下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。1 F% h: U0 A1 x; t" [/ M. R
宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。
  i4 t2 A+ w% ~; A1 S9 L* l% z" F链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。# o% a* F' s3 [
安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。/ Z% F& }- ?8 c+ M5 ^3 [. e
机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。" H6 x1 S0 v) P/ E
当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。
9 ~4 p7 Q; B/ a. X. {在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。! }# M9 ]2 W  A
链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。; j$ {1 Z5 S3 i# P) y! q$ ?
现在链码就可以使用了。2 M, Z" a2 Z, x0 G
2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。
7 Z* M; h3 \( }8 Q5 y% F! jFirst Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。
9 i8 H6 \$ o+ Q% l: ZSACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。5 a) ]7 m$ Y/ B2 z
好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。
* n3 k% e( v* T. a( z0 N3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。& D* N' E: z9 s7 a! S& N( N' b
下面是演示步骤:
/ M! b  D  z2 \4 c. j  ]无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:3 Q- n0 p0 ]0 f
1( p$ t2 {* F* Q; v  u8 j
2( h7 W5 E( _) D2 t6 K, Y4 M8 O1 n
cd fabric-samples/first-network; U) t; K6 A1 S" L7 [( b1 U
./byfn.sh up -n
( e+ c5 x. y5 a9 q8 Q/ R! \. U
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。0 R; F: ?) T- Y. L' L4 }" k5 k
现在我们可以开始链码部署操作。
' m0 g* D& y/ ]8 tSTEP 2:在指定peer节点上安装链码. q3 y4 Y) E4 q0 ]
这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。
. W* C8 @! i7 R8 L! m0 w
1( [- F( F6 O& o9 C: s
2$ i, S9 E" ?3 _7 h9 G4 k3 W) K" r5 B
3) e4 h+ c- w* w/ \+ |# e2 ~1 Z
42 ^+ ^2 x" Y7 y9 O# w/ R7 q
5
# `% ^! ?$ Z) {6
$ Q- |6 ^6 @/ r' l! h71 r6 b5 T! U/ g" j: x
8
* t, z4 o& _5 b9: L. d. `! `) G/ ?& z5 s' e
100 @6 C+ z* b$ B  c1 |# T. G8 R$ y
# peer0.org1- I- o5 T  Y8 T9 R: y# s
docker exec cli peer chaincode install -n mycc -v 1 \' _0 N0 A! D9 B$ c# K
  -p github.com/chaincode/sacc* t3 b( g$ s) l
  
4 b3 B) [; f: ]! I. C# peer0.org2  
0 q. {0 {$ A  Gdocker exec \% L( Z( ]4 a5 r  r+ S
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
0 w  l4 p8 I- z& ^* _6 I1 a7 I  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \0 S% ]# N' \- C* x1 ~6 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 \
7 m0 ?  C3 l: G' W1 d* _  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc
; N9 f: x! Z) Y8 t

, @4 I6 T$ ?# w! @/ X) U# I; ISTEP 3:在通道mychannel上实例化链码并查询
& e+ C1 p4 p6 s" d注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:
7 m# P: G8 T# ^( L
1# H8 }" k, g# @+ ~: E
2
: W8 I% C+ l" h" E" @# ]3: W- e+ I7 [, o; y+ m  ^% G2 g, Y2 k
4
- \$ T# B" _) z# Q0 f5 z
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \
4 m' @+ c! Q5 S' y% 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 \
2 ~1 c/ U/ E9 u+ E  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \' [( G% ?8 j5 P2 S8 f/ Y
  -P "AND ('Org1MSP.peer','Org2MSP.peer')"1 {, T6 Q2 e$ b1 W6 Z$ s9 _- c$ A
6 b% l! R) ~" ~7 A
如果现在看看peer节点的日志,我们可以看到出了新区块#3。" `4 e9 U2 D- G% x& q0 d) U2 Y3 x
在链码实例化之后,我们可以查询:# v' P* N5 }0 L. M
1# Z- F/ h) m; X5 T  o5 l
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
. ^8 \6 v+ O3 w+ s
' a: a& i$ U, S5 X+ W+ ?
STEP 4:调用set()设置新值并从另一个节点查询9 U: W* S" Y/ U# p
出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。
3 G- z0 u  l' j$ L1 G1 c0 q
1  {" B) N% p8 p* d8 K0 ?+ s
2+ |# G$ E1 W# A8 i; U% _" r
3
9 y! v+ O0 i1 Z' A$ a; f1 ]4
, `' A: s2 W" Q" v) P, L5
8 _8 ~# j. R9 s; |- B6- I8 [9 n% e! `: ^3 b2 s
79 T- k5 d& w7 J/ U
8
/ Z5 T- G6 p! J, d9
  n* r% e2 h6 V3 ]106 Y! f4 h" s! P2 e
11
0 ~, g# Z4 C% Z- b3 ~* t12: N0 R( {$ j, b  H1 a
13* z& c) U/ m$ D2 [5 Q' Y. o% p  |8 k
14
: q# e* k" j2 |0 E' R+ T/ y
# peer0.org19 ^7 {# k& F- k# D4 E6 [
docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \6 O- g- r. |9 L$ G4 M) i% ]+ 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 \
3 k" v/ l% i+ d3 ?, ~. P  --peerAddresses peer0.org1.example.com:7051 \3 n: m! e9 K" W9 Z$ z- e$ z- k
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
- _- R; d/ |- q7 ?. c5 _5 x  --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 G. ?* ]- o9 R
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'  x0 }, Z' B( I6 A( c
  6 Z& O. Z" L8 ~4 V
  # peer0.org2
. \# m6 w* C3 v( Idocker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
. q  b/ A, x  B  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \; g$ u$ n' J4 I. T
  -e CORE_PEER_LOCALMSPID="Org2MSP" \  L4 r( z) O+ D  `8 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 \
5 m) s! h8 a. \4 ?  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
" A+ {  ?9 `1 F8 T* D6 }
- C* o) |) Y; `& C( ~
4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。
& ~! D4 c! A) j8 T+ X% |% G8 M下面是演示步骤:8 U1 d; ^  E. }0 V4 ~7 `
无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:3 l: z0 b9 y- b6 B
10 f7 y4 z! t4 f& N3 o3 {5 `
2
, e/ K. d7 x' ]( s
cd fabric-samples/first-network
$ Q/ g/ p7 L+ G1 j& t5 l./byfn.sh up -n
# P: }7 o: ~. Y5 R
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。; \2 f1 \) j! V% L
STEP 2:打包SACC链码3 N% i- |# N8 H9 P, }, N
首先我们处理依赖问题:4 }% b3 u0 Q, p
1
# `- i. D/ n  X8 |, e9 r2
; Q/ s: k5 y+ r; t* o7 \3
0 `. [6 N& M% R+ }% {2 H! T5 G
cd fabric-sample/chaincode/sacc1 I7 I; i( H/ M1 ]% \# t8 \
GO111MODULE=on go mod vendor
0 A0 G( a5 A" Ncd fabric-sample/first-network; c8 ]( L8 |( I1 G
然后打包链码:. n3 h+ R' N7 q! b+ w: U$ n
12 R4 Y$ a: R/ L. z6 |
2/ t( A7 b: _" d% G7 O
3
, J2 M; e4 s  Z: ?, |: j
docker exec cli peer lifecycle chaincode package sacc.tar.gz \2 ]. z4 i$ `: ~+ t" C
  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \
2 d6 D& I4 \4 `! j  --label sacc_10 d; K5 f# d+ ?& Z2 D
在CLI容器内可以看到生成了新的文件sacc.tar.gz:
. @* m3 \6 c' ?7 W. _; h9 F5 kSTEP 3:在指定peer节点上安装SACC链码包
3 M( y8 e. |/ o, c% F现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。* `, f# L! w8 P4 n) ~
1$ P; i- `, u2 p) `- u6 @
2
: S: L7 X; A4 \$ F# m) o3
6 b& f9 T9 ]- }4
+ b2 M) b- [4 G5 N" A5
- G* u; @+ N& O/ \4 n8 R$ i6
3 p9 w; c6 }) F9 ~7( H6 I/ G$ Y; B; |* \; B9 B. ?# K
8
1 K- @% [( \3 o4 N9
# b8 G3 R8 @+ i& C+ z3 @4 F5 u10
* ~7 S5 _, Q- @, @' ~) ?$ x
# peer0.org18 u! c$ t# v. e3 ?) x9 w2 |
docker exec cli peer lifecycle chaincode install sacc.tar.gz
- f3 X. V5 j5 l) c6 Z# peer0.org23 f  M  f; D7 o5 Q1 D1 I
docker exec \3 n9 X7 a1 s0 s+ |
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \0 v( p. C/ {: k% h0 F
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
$ K# _& B8 `& G9 S* Z  -e CORE_PEER_LOCALMSPID="Org2MSP" \
9 J+ V) U1 ^) l  Z  g4 i1 }  -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 \
/ v8 P) r+ w  o" L. e1 ~% L  n  cli peer lifecycle chaincode install sacc.tar.gz
7 N) j( B% M+ F9 S: y  A) t/ N( t- |
9 f) V' y: E# R1 O! X% O! ^
我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。3 M; u, u3 \! L7 n3 [$ M8 I2 J
我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。# A  H6 C: J5 t7 k, N
1
2 V- I$ D% V  f0 L$ t& y24 s# Q1 H+ M. Q# R, `
38 x3 e( Z2 E/ s9 ]: g
4
$ ~1 h! i1 r" q: K5
0 p% y  e7 ?2 J; |' s6
! a) E, M6 k8 H5 M, M  f" ]+ m7
7 ^- m$ P  y% {! m1 a  q  v8/ }7 H: m7 f) b5 U
9
0 ~1 G# {& H% g10
8 ~0 D5 `; d6 J1 H8 }2 z! }
# peer0.org14 y, Y/ S( h( |
docker exec cli peer lifecycle chaincode queryinstalled5 f/ j5 E. H! ]2 h1 {' t- k  T: Q
# peer0.org2
: D# S, J5 u8 F5 q- L& i# K9 @docker exec \$ X/ `' X1 e& j7 x9 s9 J3 r
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
" A7 f* J- K5 |3 E) C  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \1 O+ L5 ?) h% [9 ~; O% x% v( a, m6 s
  -e CORE_PEER_LOCALMSPID="Org2MSP" \2 I/ Y4 U( y! O% ^0 O1 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 \
' ?; g) B7 J9 ~4 s/ e, d" a1 Z  cli peer lifecycle chaincode queryinstalled# C3 l; v' L" o- A& ]; U4 R
STEP 4:审批链码
8 H: t0 R$ ?$ P& P+ s3 q( e根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。. A& v2 z; B( c1 z( G7 m( S
首先是Org1批准链码:/ J5 {& M. m' X, _, c% J
1
- t6 y1 V8 H0 z* g( q$ @  E2( w! d1 n) a6 K2 B
3# M6 I' i" h6 e) t- W0 `2 B
4
4 h, Z* ~5 Z# j, s8 a- U5( `' V+ u6 i- t6 P# C. m# b
docker exec cli peer lifecycle chaincode approveformyorg \
0 m( J6 i  ]& I' G6 O0 i( |, u2 l  --tls \! `: F/ Y. p0 ~0 D+ A* 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 \2 ~! k/ q0 p& `' p7 x' v+ G
  --channelID mychannel --name mycc --version 1 \
' r  _: `% |3 G" e6 G- I  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
1 Q6 E' L1 V( K) ~- w

  e+ n( b4 k) v3 V9 t如果我们现在看下peer节点的日志,可以看到出了新块#3。
9 @' {1 j' \( m0 S! L( n类似的,我们让Org2批准链码:% p4 D! L& w& x+ t& K
1/ R+ h2 v* e; M
2$ n; Q( w5 }6 Y9 |) f5 c4 F6 h
3+ [  O: F) `- @
4, z, Q4 S2 t% q/ w# y: z
5
; Z- k1 K5 l' {  b$ t* V4 x6
4 C$ E8 A( o3 g78 T7 E+ q# A3 U
8
, ]2 R' @4 z: Z7 }8 z9/ k$ m7 a0 `% z3 z7 @
10
4 j# E8 |' K# @& A) H
docker exec \
% G% o7 h: D8 A, Y' E  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \" G  U9 r/ Q; T$ s. u5 i
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \7 B& e" y5 O+ K9 d' f
  -e CORE_PEER_LOCALMSPID="Org2MSP" \% s" n' ]: J  T4 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 \
* V0 _) c; c$ N% U5 {: U  cli peer lifecycle chaincode approveformyorg \
  W# G. k( {2 z  --tls \2 A; _; d+ T2 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 \
4 f' `5 A6 B" k! L2 ]  --channelID mychannel --name mycc --version 1 --init-required \
/ h6 ?4 A! A1 ~  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
! r- l; [: G4 a
+ Q9 n" f, y9 B* `+ h
不出意外,可以看到出了新块block#4:' v8 f+ s% m/ O  S9 V# Q8 w6 {9 V. ~3 [
注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。
8 G  E; j4 X2 q6 W可以随时使用如下命令查看链码的提交状态:
' K5 q+ L) l& _% X+ @) s
11 N0 N8 i' F0 b+ x# b% D" [
2$ E$ @1 f) F7 |: [4 n" s* D
docker exec cli peer lifecycle chaincode checkcommitreadiness \
. H9 T+ v# s1 B+ _1 b2 J! d  --channelID mychannel --name mycc --version 1 --sequence 1 --output json
# c  R& A7 v) u! P
+ g% R- e, c# o7 L. x
两个机构都已经批准了链码,现在可以提交了。. Z8 K+ l; r) h5 Q5 e$ o! H6 r5 s3 r
STEP 5:向通道mychannel提交链码( Q8 l% h2 E$ ~1 j: g
链码提交可以在一个peer节点上完成:
- y* S% h- i- ~' z- n3 m* p7 W
1, ^! ?8 F. I& p& b0 l. _# V+ {
2
  F2 `% D8 q* I* E& ^4 N3 e3
. X* L: j/ ?, ~3 R8 H4
1 a& b( F$ p6 ~* i5
7 v2 m0 [" h/ [/ o0 q  u8 a6
& m- s. V" \2 ~2 I2 V' m7
$ j8 L! i# F6 z8
+ c. G  P* U6 g, E* z; D
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \8 X7 G2 y  y* H' y& u
  --tls \( f. R% y4 Q+ m4 c+ 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 \
' Y9 ~' }. A  o4 `3 [( i  --peerAddresses peer0.org1.example.com:7051 \
' r+ e6 E" f+ E9 T6 N& e+ x  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \  z" J5 n( }7 O" t5 Y" Z5 G
  --peerAddresses peer0.org2.example.com:9051 \: ]- X0 v6 S  T* ]- p! A
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
! _+ A' A( j! D  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required
9 F6 I7 N7 z( T1 P9 w4 _
# ?* t9 @9 H# y* v" I" b; }
可以看到出了新块#5:
% V4 K; Q0 z, I6 b% F( x4 O注意我们在commit命令中已经包含了init所需的参数。/ l. E/ o0 d- C) B
同样,我们可以使用querycommited命令来查看链码的提交状态:( g$ x4 @6 R) d. q  N) Y( h
1
8 O" ?8 F) K( r: W8 r+ Q
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc  _" z* I# ~8 s3 k' |; m
* s( L6 V. j5 x0 ~, w# U- q! i
在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。
9 m3 p; a3 A: }$ ~) O: }8 A) g7 `STEP 6:调用链码的Init方法' q9 T0 T" h  i9 R# H8 D* K; g
SACC链码的Init方法需要首先调用。! U* e" b7 s/ A5 D! X& b
1
  T* g7 L  E1 O0 l3 u" T$ q2
# n1 m0 |, ]' T; Z/ k# a( q5 M# p) `30 }+ \/ i- f& J) U: ?+ q
4; e# }4 O, ?; H2 C% r7 X8 R
5
) A2 O; E* T/ `0 r% h$ A& f6
% Q% u% f  U' |1 i7, i0 x, z+ W/ j4 {0 ~2 ]* ?2 Z
8' S# j' k" c" e3 t9 z+ @
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \; O5 e2 |9 Q* o( `7 e1 M
  --tls \1 a& Z# Y, Y( v/ 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 \- E. ^- H/ z: L( n1 n
  --peerAddresses peer0.org1.example.com:7051 \
) \! D* [. l. K% v  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
' R& N; q7 P: R4 k  --peerAddresses peer0.org2.example.com:9051 \* M* @$ o  e  k! f; \; m
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
9 f; ]' i& _1 h4 I' s" D  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'
# B0 F$ O1 K# c( T9 x7 g

% I' [% P+ _2 K" }5 d! z- j现在可以查询 链码:
9 j- P6 L- q: ]6 {/ x8 e- t
1
2 A) k* \7 `, H- P
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
% c$ d" R7 v: @3 {- f2 z$ {! U  S3 c

8 Z) H$ h7 E/ T- S6 I5 |. YSTEP 7:调用链码的set()方法并从另一个peer节点查询2 T& X8 d6 h- \0 D" ~3 w  g
和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:
! F( V  m( t( G" \3 {  v
1
5 c. k& S# H. k2
2 t( `+ U6 ^' C+ D' I7 u33 {- m9 S' D3 ?
47 _4 G1 j6 O$ H9 h# l
5
! U4 S; c: H& c6
& U' Y0 U( \7 T6 M7
' `7 S0 @. l, h7 r4 L80 P0 o8 a$ u/ w
91 ?5 M  M, t; s
10
5 I( w* y! u0 I114 t8 ?! W: i1 _# l
12
  c8 n% X: v2 D2 T, U1 Y! N13
2 _! a: i+ Z  @! W! }( {145 S% Z4 E# i$ D! j' u! n$ ^
15% j  Y3 S# c& u8 ]7 B8 Y
16
9 B. v3 A" g* D17
( S, y, W  J) T6 r5 T18! E# U6 M  {( }9 g
# peer0.org1
$ f0 k* o% B/ z" }' Udocker exec cli peer chaincode invoke \
! v# `+ {# p8 K9 S6 ]  -o orderer.example.com:7050 \8 H3 ]: [& U) t& v% @8 p
  --tls \- P0 d, v" T4 N6 G. ^3 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 \
4 D0 Z' u' Q" [! H- `/ A5 G& U4 A# W  --peerAddresses peer0.org1.example.com:7051 \1 j  B* j: C- _7 p# R
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \( H7 k, m5 U3 h7 |2 \/ b- e% B
  --peerAddresses peer0.org2.example.com:9051 \
1 Q: Y% e7 R  H! b4 x% t  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \; I# w# j9 U' T# A2 [% D) t
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'$ t. ^$ ?+ _0 a
  7 ~' w4 J% j6 i0 \* N
  # peer0.org2" T- X  R4 V% H4 \$ Z2 ]- B
docker exec \2 t$ a  q5 U: l( a& r4 g
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
9 ]  L& A, E9 m, }( ~  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \7 Y. ]( e+ |( K9 Q
  -e CORE_PEER_LOCALMSPID="Org2MSP" \# k/ f0 p/ r5 ]5 ]) y  O1 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 \
. ?! u" `( t+ H( g* M  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
4 s- _4 Z8 e" X7 @
* j; o: F( L& E* V
一切正常。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11