Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

青丝暮雪780
286 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。
* n! f6 d4 |- G1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。
0 I3 Y* g$ ^0 H; w链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。% I4 H8 A2 a# Z2 e$ q+ O! F$ w5 e
下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:
1 F, M( B: o: G% o+ p在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。
9 C9 C. o3 t8 Z7 _; w) H在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。5 h8 B# t" e6 f# l: E# Y
Fabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。
1 V5 n( ~0 b; S/ o# {# ]下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。
- A" M5 R- D/ D$ f宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。
4 B' M- F5 G- I5 r( n: l链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。
  B+ {4 Z; C; S) g7 y$ ^# K安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。
: w6 i+ Z6 G: p7 Z. h1 E机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。
& ~# ]* p* A( {  i当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。
  ?& u. y2 s# {在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。# f; a9 w) N. z: t
链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。
! [/ Z% {7 t) Q5 r, C# x7 A现在链码就可以使用了。
0 Z' @8 @7 X. w; W$ C2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。, f( ^2 j/ n" e
First Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。- l7 ^! j6 O# u+ [
SACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。
- V) O/ H7 v4 r! ?/ `好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。
! }9 |, ?* F- W* p3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。- p' [& E* X: `. A/ f0 o# G
下面是演示步骤:
& N9 `" f# l- K0 t, h无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:5 m/ k# h9 u; O4 [5 Z# k
1
8 ^) f1 j$ z! c6 ~4 z7 Z2
, w# V, _* O0 K& |
cd fabric-samples/first-network. m7 C3 v! c# p7 u& `; c
./byfn.sh up -n
$ k2 E$ F* u/ l% f( y9 k! C
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。4 M! s# U+ e0 g% X. G5 C
现在我们可以开始链码部署操作。: P, T% A, b+ a! N$ c
STEP 2:在指定peer节点上安装链码
7 r0 Y: O: J, \* ~这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。
" T  c. a. ?* z) ~
1' p/ v: a3 G) F9 L% O: N) H4 D
2! K  s& U& U) Y6 m
3
2 ^( K0 r2 ]- f/ d1 N. B4* s1 x7 {1 W1 O7 ^/ F+ v3 Y& i/ \
5
/ l5 m9 r3 r1 c4 z61 m- E! k3 S* S9 x; i- N
7
' ~9 s' I4 S9 c& S) o# O* r, Y81 X7 e$ r# c3 L" K& {* S# F) V9 O* V
9
5 Q, g# D' A- G3 c) ]7 A10
7 p, o4 ^1 M! S0 \2 I
# peer0.org1
) C# C7 r" W, R' g6 p6 bdocker exec cli peer chaincode install -n mycc -v 1 \5 t5 c* K+ b% h
  -p github.com/chaincode/sacc
9 f8 l$ |1 D; l; F  
2 ~" }( S9 Z" k. V( G# peer0.org2  
: X7 o. v+ n" Y# o: |$ odocker exec \
6 s* u& R, ]9 x/ ]% u& I0 s) n; r  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
$ v6 W  n9 p' j$ E  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
' E- B4 k. @) 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 \- r6 L" K9 b$ ?2 C# ^
  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc+ v3 i9 p: |. f
% W9 B! ?( W/ v* Y2 a
STEP 3:在通道mychannel上实例化链码并查询
9 a9 b( o4 o* r- C2 [" w注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:- E5 d4 [7 G4 M9 z8 J2 {
1
9 |. w9 D% t, h8 k/ i& P2 [2; {+ X3 H2 v" \1 d8 U1 m0 X
3  {1 f6 V3 q- @& f& V6 I) ^6 J. U- f
4: d4 P, B4 x$ c) D2 @+ r2 q5 p* U
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \7 r' m; Y8 R# r/ _' q4 G
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \; d0 Y  i% f$ ?2 o! i6 j, p4 Q
  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \* ]4 b6 R! _6 u' m$ a
  -P "AND ('Org1MSP.peer','Org2MSP.peer')"/ I2 g& c# x9 j0 a6 s2 }1 R0 k: q

, R! u( P1 V  W如果现在看看peer节点的日志,我们可以看到出了新区块#3。; e6 J  @; k. ]3 s1 h
在链码实例化之后,我们可以查询:
; @; y" Q5 X8 v
1
. v- F9 t' M( j/ U
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
# [! O# Z$ D0 X6 o/ X! u

- z3 P7 S1 w2 W9 ?STEP 4:调用set()设置新值并从另一个节点查询: q* E5 j( |. W: k6 J
出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。! M, h2 d. q% a$ I7 D
12 j, L3 c- B# V/ b8 E
2
8 W8 l! I, G% L& R1 H- S5 q0 |8 \3
+ H  u: o- N; U" G1 }* O4) S! i! J4 F7 `/ y) Y, r
5
2 \- {2 @! T& N& I% B6, m* I& U7 S7 x. ~' O
7- b2 }3 B; }, ]) S4 [; h- Q
8  c$ u/ ], {+ W) S* f1 P
9
6 o" o7 {4 u5 ]/ ?10
/ ?+ r' g# ]' U% @11; o' @: E/ {8 D7 a6 I6 N
12: I. J! R2 q8 R8 W8 x( e2 `
13* E, C2 ?% j0 {1 I" D7 o! r$ p
149 ]) {& b3 U: |9 v* g
# peer0.org14 ^4 z$ A1 L& G3 ^2 D; J
docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \3 Z& ~3 j! ?1 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 \
. o- I! `* A: q, v8 R/ B- A+ M9 \7 S  --peerAddresses peer0.org1.example.com:7051 \  [5 i% A# |+ S% ^* u
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \" b* K8 ~& V) \% u+ \; 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 \0 M* Z3 ~/ y3 ^1 q( a) y
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
  |/ l0 {5 @1 @+ {0 `7 M/ f" Q8 J  - B0 o) Y5 Z5 q$ @* d
  # peer0.org20 u/ ]/ Q  `# o; v9 G0 ?! g0 b
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 \9 A& ^. E) h; }$ }0 C! ]
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
- K8 q" y) l8 D  -e CORE_PEER_LOCALMSPID="Org2MSP" \# |- O7 w0 f2 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 \
5 h. G! y6 I) \+ c( h! }9 ~+ p  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'$ ^9 o. ?+ G- a8 V

1 w6 J! Y' M+ ?9 X7 M1 K4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。
3 _! [0 b8 L4 |* d$ ?下面是演示步骤:
! P3 d9 ^5 v# P' m0 A* n无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:3 v5 |* @/ I( x! Y; j+ b+ ~
1; e6 e" `5 d0 ]( @  X5 J1 c2 h
28 o: f( s; W  @; ~4 F
cd fabric-samples/first-network8 g. d7 D# Z  p7 q' I
./byfn.sh up -n
' l7 J) v: L! A% v3 R
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。
+ c( j# ^/ N# p- G) X  ESTEP 2:打包SACC链码0 V! b  [$ Z8 t# G0 O% l. N/ E7 @( L
首先我们处理依赖问题:$ `4 z9 l# P$ Z
1, a" a1 q) o# a/ A
2
2 a% E/ S* C: J8 m/ t3; p, a5 C( l& P. c( O
cd fabric-sample/chaincode/sacc1 C- S5 L) C# g/ x- `* k; s. q
GO111MODULE=on go mod vendor
6 t; c. H  k+ W% ]; X- Qcd fabric-sample/first-network
: Z8 x* E) N) b2 E( z
然后打包链码:
& }7 z, L0 d+ ^5 C& f
11 S, ?3 i4 K* i! E8 h
2. W' U" o4 C# a6 \8 W
34 j, I1 s# ~. d$ l% {) b% w& z9 v
docker exec cli peer lifecycle chaincode package sacc.tar.gz \+ \+ h! w; S4 d& |
  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \) F1 s* A" }9 A
  --label sacc_1
+ X2 O: |5 C" y# h- P: t
在CLI容器内可以看到生成了新的文件sacc.tar.gz:+ N1 z* a' f6 j2 A# K6 R
STEP 3:在指定peer节点上安装SACC链码包
1 z! T) Y* w$ k) e! w9 }现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。
* J! ?! k% G# H/ ?9 o$ G4 U' `& K
13 q( g9 U8 h0 Z0 T6 w
2
; |8 P, w% a( x- ~# t* o3
  A# Q- S4 c7 u2 g* u' C: U4. r' \$ p! r1 P+ K9 T- G9 T
5% [! N9 O' ^3 d  R( W6 p
6
6 s* o, |; z+ K& J7 ^% j+ {7
9 y: c; C# q0 A; `88 t9 @/ a' i6 ]3 \3 a1 g) C
9
- k3 ^" `5 [* Q) @3 p: f: J7 t# i10
/ f, X2 O" B7 a+ \# V5 e
# peer0.org1( H1 ?( ^2 L; l  N: q" A0 J
docker exec cli peer lifecycle chaincode install sacc.tar.gz
3 c  I; z0 O, S5 C' q" C# peer0.org2
, n; U- P& q, I* l( ~4 A( jdocker exec \3 ]$ I6 j5 b: h
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \& m4 b9 [& e8 V# N/ u$ d& }9 `# W
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \8 ^+ H; M5 e4 T. h7 {- d4 D0 D0 t! S
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
/ d- b" N; |4 ^  -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 \/ i- q# P( n' ~2 B1 R1 |+ C
  cli peer lifecycle chaincode install sacc.tar.gz
8 M( ~7 j9 }* r' p

, t- J& f8 E& R2 ?3 R$ I" [我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。
3 S" R+ K/ P/ p$ C0 s  M3 ~; T" ?我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。
/ D; p( m  s9 ^/ M0 v' L5 J! `
1& @9 {* D5 f4 ?7 G
28 }) @7 A7 G3 {' e0 T5 f3 n( k
3
5 N% g) s( @& s' y8 I5 R4! U% s! _! A2 A3 N0 W. A. p  O9 ]
5
" @: _! Z' C1 T" H  l6
, c4 m/ H4 `' Z5 t7 D0 S- e3 ~7
1 y- V2 [/ Q0 m7 C" b4 K* G8
6 D9 t- d* }) B2 M* v9 w1 w3 ^9
7 y( D+ {0 L  s. A! C8 v' L10% V1 y. L6 H" h$ ?: e0 v9 C
# peer0.org1
% L9 b: F6 Z7 W3 `" r0 S/ f. Fdocker exec cli peer lifecycle chaincode queryinstalled2 d: D1 ?& P# C6 H1 O& }+ `
# peer0.org2
0 k  `& m2 c5 fdocker exec \& i: `9 i5 G% a5 N
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \3 }) p/ K1 `' Z6 d4 P
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \1 K. b; g2 P0 J! @& U! i
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
0 K9 ]' E! e! 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 \1 _* B$ l$ u! o- a
  cli peer lifecycle chaincode queryinstalled1 d0 Q4 E) D" u9 @- c# N# f
STEP 4:审批链码$ p) ~" w. E0 g
根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。
/ Z5 ]! d* x" U0 c- o( v- y8 M首先是Org1批准链码:
7 Z% x( i3 W- L3 ^' _* n
19 [8 K* Y" g. ^$ n9 f
2
# W  D* ?6 p) T& p7 o) x# J37 j3 y8 @$ W' G  W
42 b* C3 b# L% g: \0 l
5
/ y( ^4 u$ X0 F  R6 S
docker exec cli peer lifecycle chaincode approveformyorg \8 t8 W2 |& c  e% G
  --tls \2 m8 Z5 W0 P) s: w7 J# 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 \
, h5 Q: C! y# D. d) d  --channelID mychannel --name mycc --version 1 \$ X4 V( I3 ~! z9 Q
  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}2 Z4 x5 V  [# m# V0 O& M7 z
3 F" H/ r" ~8 B  M& ?% ^
如果我们现在看下peer节点的日志,可以看到出了新块#3。
" P$ `& Y+ d) e类似的,我们让Org2批准链码:
: O- t, D0 y  g& y
1
; P4 c) ^' O4 J2 ^0 {+ b, q3 G$ _7 @2& K) o! K" Y1 `9 C
3% P, l1 {0 J$ H3 f
4
$ Q/ s' ?2 E/ {0 h+ O( m( t  r5, z1 W7 b* z+ v
6
& v  W+ \6 r# a) `& R' Q0 L9 {7
2 o3 w% U5 a0 F  p8
$ t% r7 f6 Y$ j9 Q' v- _96 n1 d' z) F3 ^7 ]
104 _+ |0 T5 l9 ^$ h$ F- ~
docker exec \
$ @. Z/ K1 t) W; D+ |, _3 }  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \% r8 b2 @  y; v( O4 c* W
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \( ^0 ~& `* g9 h) a! V+ o7 e% M
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
7 X+ \- Q" A0 w: 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 \
% Z6 n+ @1 T2 H) \  cli peer lifecycle chaincode approveformyorg \
: w. J% i8 R! M$ I  --tls \. n1 a( m# R, 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 \, i! n. {: M1 W
  --channelID mychannel --name mycc --version 1 --init-required \1 S1 W; ]: h' e
  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}
/ A. z; F; p& j/ I; Z  W
, X. ~7 g- {" U. B" Y2 q# N; }
不出意外,可以看到出了新块block#4:
6 G! P! ~' y- p7 g$ v/ C9 r注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。
6 ?# }( S1 C# t可以随时使用如下命令查看链码的提交状态:
! P3 R. Q6 _; ^' e- L
1/ P1 G$ g; s" {- d1 {: |" ]/ C
2
. r! Z3 {' D1 P  p9 ~- {
docker exec cli peer lifecycle chaincode checkcommitreadiness \6 Z$ K- b& \) P! E* Q
  --channelID mychannel --name mycc --version 1 --sequence 1 --output json* m- w0 K0 T  m1 d. B
& q% L, f) Y  D3 k
两个机构都已经批准了链码,现在可以提交了。2 Q6 H6 V- B5 K4 k7 Y  _4 J1 S
STEP 5:向通道mychannel提交链码
* D5 l2 @8 N/ D# C& x' Y# {链码提交可以在一个peer节点上完成:4 v, R5 X  }+ t% Z! S7 o5 j, \' n6 y
1
+ ?/ y. V$ V2 r. H$ S2/ W* n1 a$ R( {' Z" m
3* k. o- b" h# }) l  Z
4% d! U1 J( M" l; ^5 \- H+ f
5% Z  E7 w9 l. F& O- w( E7 N- y( P
64 ~2 ^- ]2 X4 r" S3 l
7) ?; [2 K- o; v
8+ H+ o0 Z% R! g  O9 f
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \9 z( Q8 n! W$ s" J+ g7 C* c& X+ `
  --tls \7 A( j3 K) O, {% y6 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 \5 X" k2 h+ C( \- {) @9 d) }( e
  --peerAddresses peer0.org1.example.com:7051 \
$ Z7 m0 J# T, o* I7 a1 A5 q* N  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
1 o: \; M8 J7 e  --peerAddresses peer0.org2.example.com:9051 \5 n9 ~  T" C- }/ r( Q$ r0 P
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \+ ~6 E* ?. n/ f7 {0 ?+ m' W6 K
  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required
7 `5 C/ a7 k  B0 J1 L' ?0 i

4 F- q( x' p7 t# J5 [; L1 ~可以看到出了新块#5:& r2 K5 n0 \  M: C4 Q9 k9 P* ?
注意我们在commit命令中已经包含了init所需的参数。
2 o2 U8 t$ q+ O0 X同样,我们可以使用querycommited命令来查看链码的提交状态:
5 @0 b% L* b; ^6 [' ^: }+ j
1: ]( g# I# v6 t* E( g
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc
; f. [2 l0 i0 J

3 h3 J- c2 J- k; |在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。0 x2 R  X( ^: X, I( _% P! Q
STEP 6:调用链码的Init方法
3 M/ r# U; |8 `# iSACC链码的Init方法需要首先调用。, K3 K* i: M1 O% ^1 E2 c
1
! U; s! |- I' g! G& N; j$ s2& z6 G* L5 g+ K
38 H: a" ^! w# [7 A
4
& c' f7 f9 c$ U) Y9 u$ a5
3 G7 i! p( V& D9 f7 n3 V% O6
1 O% K; [9 \! x. ^, ]8 g7& Z. C' v& X( Q4 t8 k0 V, H& v
8: ^8 j0 E- L5 O; f
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \9 k  t1 o" e) X' V2 I
  --tls \
  V  r9 ]/ f; E6 x2 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 \/ A; z, k( Y4 D. C
  --peerAddresses peer0.org1.example.com:7051 \. a+ A, ^6 V* g3 P
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
' M% l+ \5 r# l2 v  --peerAddresses peer0.org2.example.com:9051 \1 }0 Y! h1 z" b1 ^
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \' c4 B6 U  [, f% f* C) n7 q% T
  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}', A4 G8 R- P2 }" k& s3 w* q
' U- B* ?4 `+ N1 i; E
现在可以查询 链码:
2 `  q) v+ s0 V- L* i0 j
1
( p1 q3 ~. \: @: E
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'" M4 w" z* F7 F  P4 |, d

9 p# U6 M# R- B) z! `* FSTEP 7:调用链码的set()方法并从另一个peer节点查询
& ~' g- U9 K$ C# L" j- l和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:
5 P( h0 Y! {3 O
1
' ^; s4 W! _# G( j  @' f. l24 `! E, m! h  v( K
3
: Q7 W( L' ^; }4 F" H  n- p5 X6 w4  H1 a$ ?* c5 b" w2 y$ |+ g
51 Z3 S/ f, w$ U
6
6 B- w  r; t: |: |9 Q% `" ^73 V( w+ q1 M8 S0 c* {) x8 f
8
3 u, M6 j9 [. X( }9% p- r( Y  [- Z6 Z, a) s5 {" ]) |+ d
10
& I+ Q% ?: [" U( J  z11# J, |4 t$ l3 L( m( e4 k  Q5 w# W
12) j' i' \' t; v
13! P% m+ N9 i  l. u& I5 r
14
) j/ q+ `4 q6 ]% R! T15
4 p$ v* g, I% V" _, ]9 {9 G16( `7 N. ~$ z( r) m7 U9 N
17
* E  K+ ~% V/ Q& k185 {; Q6 E4 Q% @1 K: ^6 [& E( t
# peer0.org11 T4 [& m4 g9 p3 f* S
docker exec cli peer chaincode invoke \
% k. d% a3 P4 K0 H  -o orderer.example.com:7050 \" T% f1 }' o! O$ g. ~
  --tls \
% }- t& k) K' V. T! r( P  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
, B8 `9 @" m: ?1 Y: D- c' R  --peerAddresses peer0.org1.example.com:7051 \) m$ v9 o9 ~! P' H  {# @# I3 O
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
7 \2 P; m/ q" X  {  Y( E0 E5 w) ?  --peerAddresses peer0.org2.example.com:9051 \
+ @5 q% j! |0 k  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
# O" s6 a/ F3 y: B; x1 E! |3 |  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
: z7 I1 t9 ^+ F  8 P3 R& k; p* H# N' n
  # peer0.org2
6 N! R/ q! P3 i3 [6 T- V. C5 ~1 Rdocker exec \
7 K/ z4 \2 _1 `! x  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \; z: ^$ V) s, v5 j& R$ N
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \5 {2 j% `# p% N- f+ H
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
6 ], ~/ x$ h. V7 {2 @  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 \
1 a1 v4 X; \' n  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'8 b( A- f3 _5 q, Q; u& n7 W5 `

( V$ Q4 t  Q, v, m$ k" @3 Q一切正常。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11