Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

青丝暮雪780
147 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。' j) H6 C6 E" i
1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。5 j4 F2 q' b" i3 w' G2 P( y
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。6 y/ U/ ^" v" Z* p9 K
下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:9 s' J- W. x8 E. a$ h/ W
在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。
% `4 ^  q1 d4 ^2 l& {* h0 N/ d" L* K在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。
* z; o- ~  o8 GFabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。
4 {2 H$ g. H) K' m# c! t$ T' {! B下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。4 `" N1 W- Y: x6 q; _
宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。% E" ]) e0 ~2 G
链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。+ W8 v0 l) A. }" l; }
安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。
: i. h7 g' X6 C- |/ O7 W机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。6 \$ F  H1 n$ c- k/ h& Q, u
当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。
+ B7 c' R' h1 |( x# i* E在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。! b* n0 U6 `8 r6 d2 F4 j7 ~
链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。
+ J* O( y, V" {4 F8 s) b现在链码就可以使用了。
+ N) Y* ^% d7 l: h0 y) R0 }9 ]; g2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。+ b& i# I+ n. g' h+ C4 ~
First Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。
. t, H4 v6 b0 j! gSACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。1 ?  w' }' u6 i, s' D7 S( |
好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。  s. u) V. i! `# O+ ^/ [3 z
3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。
: x/ ?# {# g. T' J$ N下面是演示步骤:
) L' e3 g  x: i无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:7 C3 E: R' w8 x! T; G5 m. j
1  a8 _" T; A, h6 _
2( x; T( l7 g$ `/ W4 O4 ~
cd fabric-samples/first-network
. e- Q: L& w/ d6 l% Y./byfn.sh up -n
; P/ z  u8 c6 C7 i" D
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。
8 ^  a$ E; I# n7 }5 k8 y  x. n现在我们可以开始链码部署操作。
3 ^: [0 v( ~) v9 a! @7 Q: tSTEP 2:在指定peer节点上安装链码
0 A$ |# ]3 s8 p* j" {  U, m9 w这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。
/ s! H! i3 S* a- {5 Q- `
1! ]5 X" S2 n) Q" n1 ^9 E7 b! s, x
2
  f' s2 N0 J% X& t$ V) S3
$ e) z7 i% _' U5 o4
% ?5 n: P' |( e1 f5
7 Q! W8 @8 F4 S6* u) z: `. c3 V! l0 a9 v) A
78 @6 A: z* c! y& ]0 ~# j
8
2 y8 u" ^3 l  }6 @9 H& Q9
. p0 Q- m; p: E% ?1 W4 e10
. r- D+ \1 B, H0 Q5 r' D
# peer0.org1& d) c8 ^2 q2 X7 D
docker exec cli peer chaincode install -n mycc -v 1 \5 V* @# q, k6 t4 e
  -p github.com/chaincode/sacc2 D0 h1 O* {9 S! S9 @
  
; ?" K# ?: w0 x2 z* I# peer0.org2  
$ p! P) z, c, ydocker exec \
6 @& u+ h& @6 L' v' b% 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 w2 c1 L" Y/ z5 P  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
9 l6 b5 m4 q2 f. W% {) b9 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 \) @2 N7 R- ~  o1 O+ C6 J$ }/ `
  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc0 _+ S+ s+ J" k

6 |# F( b* h, fSTEP 3:在通道mychannel上实例化链码并查询/ ]2 V" L( h0 M8 _
注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:
: E% z6 f; G& U: ~. j; B
1" S5 C; M, Q% _. f
27 f2 i5 G, h; @) s/ q
37 b5 X$ I" t5 w6 [- X+ e
4* S( A3 E1 e1 ?' A% _8 G3 Z
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \
# C4 K$ q5 b$ R: L7 P. Y# 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 \
# D' V3 {* U5 p- u# D  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \
" }/ V2 o# t+ m  -P "AND ('Org1MSP.peer','Org2MSP.peer')"
7 D5 e4 z( Z; g3 s/ i

+ c* |, r3 X% B如果现在看看peer节点的日志,我们可以看到出了新区块#3。
7 X* W) S# t0 a在链码实例化之后,我们可以查询:5 R6 ?: i4 }  Z$ f
1. k: G! H( ]0 K- M: m% u
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'' g5 c& Y9 ~- c$ u8 l0 e  g3 X
/ Z+ A9 l+ X. N# k8 V6 G
STEP 4:调用set()设置新值并从另一个节点查询( g' p" E2 o1 m1 }" \7 }  o
出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。
1 u' b" J/ e! M  ]9 y* V
1! n% |8 ~5 t8 ?0 E* h- }- o$ V& P
21 N2 R" h5 A( t: K
3
: @3 ^9 s0 D6 b* v5 K4
# B9 @" `( V1 V1 G! P* l$ F1 n  v5
( x: K# o9 R: Z- |4 U67 X; j7 G; H! b# d5 y: Z+ h6 w$ Y
7) n: _- w$ b# F
8( [6 w/ ?( x  ~. F
97 C9 a! N3 d& N6 K7 c0 C4 U
10
7 e- `( n3 j: R* T" Y; o; V+ e5 n) R11
  K9 B/ U+ d. U1 J% h2 C124 ~6 W, G8 T0 p0 `7 T
134 M3 d9 I$ @; z, v4 A
14
7 ?# Y* C. L1 X/ s
# peer0.org1% T$ K; `1 Y! n) C  N3 b
docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \3 P; O) V  {% R) O5 d  I* 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 \$ f7 }' L+ ?/ U0 k) X" z  z) W
  --peerAddresses peer0.org1.example.com:7051 \
& e2 u. m: t- p  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \7 z, a' s0 d7 O3 E
  --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 \% M' |3 P9 ]+ f: v2 \* o7 d
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
) v* b; c2 c2 x! ~/ B% V! I  
2 D- e5 Q9 C! u. h& U: r  # peer0.org2
9 q# Q( k& Y: N3 y" j# \8 Q0 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 \
& V* O+ ^3 _0 B- i4 r) ?  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
  W0 Z  V! X0 b' ]1 u9 \0 N7 Q* g- ^  -e CORE_PEER_LOCALMSPID="Org2MSP" \; k9 y. ~8 O1 b. l: O+ i/ h
  -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( T, f; p) ^4 N& J' _* t
  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
1 r7 q; N1 j$ B; |. t* P: j
& N% \# h+ R8 R  Z
4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。
6 X4 h7 Z% o2 S  M. Z1 `: M3 y下面是演示步骤:
4 y, o  d! W& y9 R' y# U无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:
* c3 G% p. q; k0 J# J5 X! c" G$ U
10 K& M4 |- c' f/ f: g9 G( W
2
' c5 u: D0 |* V0 h9 F
cd fabric-samples/first-network+ g, g+ e& S6 j- N. e4 d
./byfn.sh up -n
& q( N5 ]# w5 C. B
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。- U$ N5 \) o6 C. g2 W
STEP 2:打包SACC链码5 d# P7 k* U/ d
首先我们处理依赖问题:
' n! M9 q2 a6 f; J' H8 X
1" E, J- `; ]/ d: D0 }: p$ f: z- D
2
" Y8 z+ s0 R/ c4 Y; c$ {3. P; i: j  D" P# _, ~
cd fabric-sample/chaincode/sacc* j3 [& N! s7 B5 [7 r
GO111MODULE=on go mod vendor
; d* ^, }" m2 Ecd fabric-sample/first-network
! U% m' V2 D% I
然后打包链码:0 D/ n" ^! Z9 `! {& i; S. E
1. K  v. h, p1 l4 |
27 ~( a2 Q1 v$ V& y, s$ g
3
$ `2 e5 J, I7 M9 I
docker exec cli peer lifecycle chaincode package sacc.tar.gz \
, o$ I& o: e8 z3 u; x, m$ n  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \. w8 n& a& b( C+ f5 D+ O* Z+ ?
  --label sacc_1# w% J+ }+ i4 R3 h
在CLI容器内可以看到生成了新的文件sacc.tar.gz:
: l" j7 X7 j8 I+ R5 @4 Q% _STEP 3:在指定peer节点上安装SACC链码包4 |5 y5 W- a1 X4 Q
现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。1 }! h4 ]9 H! _! A9 r, i. L, S& p
1+ W' I$ V  D- N6 J
2
* `, p# T+ j  D' I, @( @6 y37 {, L! @4 c! Q8 `
4' j$ t- }+ O0 E; P
58 V( p  D3 I2 e% I# Q  q
6
% }1 z' g+ q$ f- ^7$ c" N% T' F" ~/ w* E2 d' J/ g
8
/ M  C. x( Q, |: J2 v& Y91 [' ~4 Y0 ^. m1 x$ q: z
101 Y1 r8 S# O5 Z
# peer0.org1
  Q& G& ^7 S! Y9 Z1 L) f2 idocker exec cli peer lifecycle chaincode install sacc.tar.gz+ K) ?5 A% v2 T) K* K( Z- m
# peer0.org2( t; ]& |$ }3 h2 `, T. G2 Q
docker exec \' ^& X) [8 w# _
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
4 e6 W/ G$ a) y7 `$ N  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
6 t. o, s; Z) k+ e  -e CORE_PEER_LOCALMSPID="Org2MSP" \
+ S# C+ p8 J3 O8 W! |  -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$ \' Z! F* Q* E5 s
  cli peer lifecycle chaincode install sacc.tar.gz  r& J( N, |9 L7 |# o* {1 }

- q4 P# ^" U3 J& l! }; q我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。
# S8 B/ K" n0 _我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。, h) k4 L) h9 J: b2 W; M  _
1
/ y% k; s5 ?2 {4 i9 a/ [2
/ g( `% Q- Y+ y4 A9 s% `3% _: L0 n1 X6 i0 v$ S6 L: I
4
7 \- |. x9 Q- K1 p: g5
4 J3 b' m: J' C# V61 `+ t6 u- @+ n/ f
7
8 O* P* e& _* }& a- n% B8+ E9 E6 Q+ G' K2 ?( R" Q
9  f% i* S. c) h: j5 K6 W. j' B
102 _2 O  A6 \* S; G3 g! o7 f
# peer0.org1
5 T& H" p0 f! s: }  E: U+ C& @, cdocker exec cli peer lifecycle chaincode queryinstalled4 S) e% y" P5 x7 v' p
# peer0.org2
6 w4 u7 |4 O0 f' x0 Q' x, L! k# Zdocker exec \# l9 N; c  ], e4 t
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
6 O- N; d; Z/ {9 Y/ \, s- i  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
4 u1 v4 w( n7 M" R: s, I4 ~  -e CORE_PEER_LOCALMSPID="Org2MSP" \
6 ]; P3 y& L' m0 F' A; l0 C- n  -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 \/ P+ g( G# s5 A3 @' H4 W) @
  cli peer lifecycle chaincode queryinstalled
; U* _3 W) `# l+ e
STEP 4:审批链码
& O2 d2 h" b% j根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。
) j1 d; s1 h* A8 m7 _0 h首先是Org1批准链码:& U0 Q+ R' C3 h1 d
1
" k# [9 x$ \3 ?& }0 b7 B" ?2
1 h* h1 \; U% H3 S4 R+ g( S3
: B, B8 u% A4 ~# k2 a- M* f4; h$ s0 ?+ Y8 a7 M
5
& U; T1 v2 X: Z. p. t
docker exec cli peer lifecycle chaincode approveformyorg \& k  G& ~. ]5 T7 e3 T) i- j
  --tls \! p# v8 C+ E! u9 {4 Q7 o0 ^5 S: I. 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 \
' ~- W5 @$ F( g  b# B7 g6 D7 [  n  --channelID mychannel --name mycc --version 1 \7 R) T0 ~& k% P6 o+ T: G1 F/ _
  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
4 e3 E: i2 F1 a7 u9 M
' Q1 x7 h* r$ O% Y( i/ N
如果我们现在看下peer节点的日志,可以看到出了新块#3。9 X$ O) B5 \1 ]$ W  ]- c: u- W0 v- X5 X5 ]
类似的,我们让Org2批准链码:$ @; l$ A$ W0 `  _- m+ T" C
18 z, v+ S% F! `6 G
2
) T7 |5 y1 [, N+ C* h8 ^3
% H% D: R& E" c9 c7 a3 b4
- `3 t0 o& T: o+ G8 _# d6 U57 F; t- j4 X8 a- z/ I) e6 b: ~
6. z8 |3 n7 M. _6 m
7
# R- x; @4 h. @89 ~7 `( a& A( ~: X$ e0 x& K
9) p6 ]$ A9 f( j/ o( o4 C
10
+ q0 y* x. `( y; U: S0 J
docker exec \4 X9 f' b  h; I/ I
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
3 x, ?: `6 C: X$ K  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \" g2 F: K" |$ k" S4 T- X
  -e CORE_PEER_LOCALMSPID="Org2MSP" \- ~; E- F. C: }4 s0 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 \
  X" v0 S( V$ h: F- z( U  cli peer lifecycle chaincode approveformyorg \
8 v) @6 m6 P4 O- k& ]* s  --tls \
6 p5 m9 L# \0 X* 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 g8 }0 ^# R/ X4 h$ \
  --channelID mychannel --name mycc --version 1 --init-required \( n/ H! g% O. K7 b; i, Y& D  e
  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
! I9 [; u3 _+ C7 E8 E. ]
/ v7 ~3 z  S! g; t, }) g
不出意外,可以看到出了新块block#4:
7 [1 G8 g" B( r$ X5 u" Q; g注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。* T+ ~" ^8 `7 g4 i( R3 b, U
可以随时使用如下命令查看链码的提交状态:
0 Y$ M  I" {6 O+ H
1
# N3 U- g5 v1 P0 X/ H2
3 s. _: _3 i8 s- V8 m" _
docker exec cli peer lifecycle chaincode checkcommitreadiness \5 n5 ~7 Y5 P9 J' f& n$ G
  --channelID mychannel --name mycc --version 1 --sequence 1 --output json' a; ]4 w$ w& I0 J
" P5 H2 h, Z0 h. ~: K- J  F# L! W
两个机构都已经批准了链码,现在可以提交了。, r4 w! l5 H2 P& c
STEP 5:向通道mychannel提交链码
) X. l0 \% M& W$ Y! X" O链码提交可以在一个peer节点上完成:! r# m! w. `- X' E/ r! N
1
9 W+ [9 V2 }! U" N6 p" r2, _9 H& K" m  N/ M3 G
3  E+ e' @  }+ i7 |7 ^  D
4
" v# [, L! [6 F+ X2 Q) D5
0 K8 f# B; ^4 y3 f* G6# o4 w: h, S$ N' x2 @
7
  }9 v5 y! D6 s  a  [' H6 l85 V+ L& B- _! _5 M
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \
3 E7 Q. v' O* D' t+ ~/ M. b  --tls \; ~, C* F5 g) ~" u! c, p0 {: y4 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 \
. \* X" o; T4 \5 h' V' d+ y  --peerAddresses peer0.org1.example.com:7051 \+ J' r/ N" v8 K8 j& T* `
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
3 S( |! S. _. K8 z- F  --peerAddresses peer0.org2.example.com:9051 \
( `! Y% r; k3 s' {  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \4 u& O7 ~% ^; E8 `0 M7 j3 U
  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required
. q; u1 Z5 f4 B0 U) j
, w! E' Z( X+ v8 D$ A
可以看到出了新块#5:) o1 c+ p1 H& d6 [" I
注意我们在commit命令中已经包含了init所需的参数。
# |7 P% T2 O$ o# V3 R同样,我们可以使用querycommited命令来查看链码的提交状态:
3 o- @, Q% Q% u. E
1
( s6 M9 ~0 T1 M* R0 J9 S6 _
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc. D. _5 S# E' y. \# T

; P: n9 v3 p9 Q8 m% b在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。
0 e0 S1 V- w; t4 a9 ySTEP 6:调用链码的Init方法- i4 N6 G# a/ \" m8 F8 d! k( O
SACC链码的Init方法需要首先调用。
6 J% P5 L" |/ _: l- r* p6 u
1
8 V5 v; `: H1 N8 `5 \0 |2 F2
3 Y+ F8 p! |" Q/ X+ }1 L7 A( A2 `3) x# b" @& ^4 x" Q2 d6 x( J5 f
4
) y+ P- U. E8 C% `) z5
% A8 ?, M: R3 M6: q; c! Q. j& E' P! H
7' r, q& j) ^% E& q
8
# U. k0 J7 Y/ @* X/ `
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \
4 y7 R# v1 @( x9 b7 D9 R1 `0 ^  --tls \, z$ U, v# j  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 \) A/ B$ O+ z/ }( m6 E
  --peerAddresses peer0.org1.example.com:7051 \/ g: W- S' Z0 D/ z- Q7 K
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \! R7 A8 i7 B1 q8 z: f9 M  ?
  --peerAddresses peer0.org2.example.com:9051 \
: g) s& C( B2 C' P. r  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
5 B9 [9 g  N2 u& K$ }9 z; _' P2 v$ |  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'8 p! V7 n6 b' s7 b

0 Z& r5 W- \" l9 h现在可以查询 链码:
) x9 ^% Y4 I5 f4 c8 G4 X6 s* V
1" y/ G" I6 c6 K
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'+ W+ ^0 y( i; U9 \* d$ I; x0 u3 a) e
: e1 y; r' D, z1 c6 v2 h( Z
STEP 7:调用链码的set()方法并从另一个peer节点查询1 t$ |+ h" ^- G
和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:, U* h0 M6 s8 n9 [# o2 n& R/ K
1  u7 U7 A4 L+ V* m) I- Y$ h
2
" w# b9 p. o: K5 M) O3
0 E' G5 m2 o6 C4
8 G5 _* Z7 o+ A- y51 Y3 n9 m8 K/ d
6. {9 `$ C6 `9 R: O' }8 b, I% h
7  R& {% h+ {1 ?! k+ [
8
1 O. p- b5 N- A# R9
1 T" ?3 y& D- @7 \" W& {* B10& w9 H. A- y% W1 m
11( L. C0 q7 K: R' e" O
12; E3 v( D* g, o. q9 n& E8 }! p
13/ l: W/ w, p  [) r
146 R9 k* o0 k( [( i$ @3 J& g
150 i) W- }9 H2 N6 k& B
16
6 d, ~& Y& M+ O& t: _0 {179 [# B! x! p- |/ W
18; [6 b$ |" R* A1 C6 _1 K6 H
# peer0.org1
  w% i& v/ f4 h3 vdocker exec cli peer chaincode invoke \
- Z- |3 a$ B- Y: l* V% n5 j  -o orderer.example.com:7050 \  |0 m. U: |5 X, x" g9 v, I' N( n
  --tls \
4 y! |7 a! P* b1 u) I: 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 \
' _0 ?% g/ s  M+ V9 w4 [$ \: a  --peerAddresses peer0.org1.example.com:7051 \/ c. ~. L) ^3 y/ G' d4 ^4 D# \$ v
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
# z8 i+ e: u, n* d  --peerAddresses peer0.org2.example.com:9051 \
0 [% o/ S2 m9 d) w  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \- ^4 U4 E& W9 h, U" M
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'0 u/ }4 I, w7 m& v, K" D) d
  - J& D# m( s- b* ?
  # peer0.org2
; v7 W  I/ o8 w6 v9 z3 c! zdocker exec \
- L% M+ F' q. H# R+ Y0 V  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \+ _" E$ z0 l6 t$ L  T& e+ b, m
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \9 k# F1 i. a& B! i6 m: x+ J
  -e CORE_PEER_LOCALMSPID="Org2MSP" \2 S6 J& T% {- S) \' y; 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 \7 B! G+ R& ?6 a, V9 g
  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'2 l8 e# i$ h( u3 ^9 I/ R, S0 V, _
& g0 C6 S5 Q9 Q4 G5 |: V: V5 }
一切正常。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11