Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

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

青丝暮雪780
155 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。
6 ~+ y4 D) {  D0 V: b5 o1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。
" s* o9 Y2 U  D链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。; ]( R9 n  ?2 d+ G: W# O, S$ I
下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:
( ~! q* z" C6 m3 [& |' p1 c: N在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。
5 G( Z  b3 g% |& z在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。. m: r( E" }1 [8 t& x) X
Fabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。
5 L2 s8 c: B9 q3 W下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。
2 _# d# |' R1 n6 g% U8 b: V宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。
: R1 q8 W' o$ O9 e链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。) U* D: s3 c2 R% U6 {
安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。
- O$ H. d- p* Z# U) B# n+ v/ m7 A机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。  z, d: w7 H- Z/ R& N
当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。% l/ b, a7 E/ Y% w
在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。
/ \* P9 X# W8 u7 ]链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。
( }/ K# K6 t5 h1 s现在链码就可以使用了。( k6 [- {. I: i9 n2 q
2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。" S5 G5 z2 `+ U2 D6 }
First Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。
7 k) U/ a* [+ z0 D1 g" _SACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。
- F( \- Q. x. O- x, l好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。% ]# z* [# X. }$ v: C2 Y4 V
3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。) W# w6 N6 H/ N; Q4 ]0 i
下面是演示步骤:3 w% Y: r1 L+ L  u3 S! }
无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:; h7 s, E! c, [8 \* R4 W
13 e6 U1 M3 S/ m  D' `8 t3 j0 i
2
6 ?; c( P$ ?/ e: [. d- m
cd fabric-samples/first-network3 @# W4 Q: Q( M# C/ Z
./byfn.sh up -n2 S: B7 M& O& Y  ?
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。$ m: f% |; C# s) v5 L5 Y
现在我们可以开始链码部署操作。
) x) s  Y% |1 @  J& ySTEP 2:在指定peer节点上安装链码# e1 h# z$ J! C5 [
这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。6 a+ C* D8 R* A/ ^
1
$ {- z+ H; E6 Z; p1 U4 V% J21 \# b" R5 G3 A4 N
3& S& p/ \+ @5 s0 N! l( i
4
* D+ a- T+ D# J+ [; ^1 N5) v1 W" e) |  Z, x1 [0 F: X
6
5 k! P- q4 t( A9 I, c" l78 [3 Q; }# U# b, S& J" t9 Z
82 \9 h5 w0 M- A3 l- x( z
9
& n8 K& b) a; d# D) B* G' t9 f9 a10" m0 B; S, d+ }( r
# peer0.org1# h  x+ S; h5 x
docker exec cli peer chaincode install -n mycc -v 1 \, |9 t- Z9 o+ M: P
  -p github.com/chaincode/sacc
1 x1 l# D4 }7 @  5 P- Y$ K7 ]3 L: k: C$ @
# peer0.org2  
5 Z- p+ N3 [2 A! {docker exec \
4 w/ v) W: W. z* O( w0 }. u/ ~* {  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \
4 c6 u' P7 x$ V9 _* i# f# X3 K  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \% `. f8 {$ ]( }1 s& x  S4 X2 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 \+ P' g( g1 h: O5 H! K
  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc) w/ `( L4 a) z: J3 j

. e0 X: ~; b- N7 WSTEP 3:在通道mychannel上实例化链码并查询
- Z' @! M2 n" D" Q8 z/ J: G1 S5 L注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:
% E2 H: ]8 ^5 z1 X$ A' b
1
& j- O4 C2 q- T; \2
/ z/ ~. P+ X7 f0 j' t  ^& o3+ ~& H  ^7 i4 w# M! n' I
4% o2 V% h2 O+ ]# H6 L) I- Z, W) U
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \
( h3 [- E8 N% K7 ?# 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 \( J% N% w: A; n# U7 l% R3 j
  -C mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \
7 M! R* @" T/ g* U' W* {. S  -P "AND ('Org1MSP.peer','Org2MSP.peer')"
: Y$ D' d6 f+ v# e2 l2 v
7 G# W0 T( d6 \9 n  C/ w' H
如果现在看看peer节点的日志,我们可以看到出了新区块#3。
& J+ B. W; x; ?* f& `" f在链码实例化之后,我们可以查询:
8 Q! w' g6 F* x
1
! K: a3 p* e- c- v
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
/ I: f: ^- A3 [
% X, }$ H* i& J( x
STEP 4:调用set()设置新值并从另一个节点查询
9 G: M9 \( B* l6 v! }9 Y出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。
( K7 ~" Y' @) a1 U+ Y7 ~
1# F/ a) ?: i! v; U7 f8 n/ U, q: F
2
% q! R/ P( P* N% C% @3, ?3 w* i0 x- _" `  K" p
4
: M+ {* S# e5 F( N+ h1 j5
; `" L) L4 k9 m- c; s: D60 |( b7 c; p6 J  i% Y3 w
7; M( o3 b4 p5 N. B0 v0 P( N+ U
83 ~4 n" b( I( C  Z
9
; l: j6 z- V1 ?5 i, G10
' q$ V3 |& m( P' s+ a( d9 V119 Z3 k0 ]! M4 O! x5 {
12- e- ^9 A( @% n5 Y" u- X
135 E# E0 s2 q. @7 ]& j$ W% I
14& @- W: q3 w9 t  i% f' l
# peer0.org1( G: u9 y+ R8 e! |- {7 p, ?
docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \
- B& E+ z  E% H) ~# 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 \
" [1 Z% W; _. g5 I* x4 Y: X( K  --peerAddresses peer0.org1.example.com:7051 \- \& Y2 R2 r# r
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \. ^. P6 M. j9 e, Z
  --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 \, P  l6 u0 E2 t# ^$ p/ Y
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
2 P7 R# O/ o1 B$ E  f- ]  7 S: w& Z' t& F: p
  # peer0.org2
5 f# ~; u( G3 V& L& l% qdocker exec -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \. `2 d9 t8 n- I% R, m% P
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
* _1 R$ I1 @$ b4 |8 _  -e CORE_PEER_LOCALMSPID="Org2MSP" \: @3 ?3 I/ y; [' q) n- p
  -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 \, w3 V3 c# D! V7 s8 T
  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
, Z7 S7 _, |+ w7 z
2 C2 H) `* u5 R. r
4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。! W8 |* T* E; ]' \9 T3 w
下面是演示步骤:
0 Q! Y8 H0 e% S( b+ I- t无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:$ `* h$ ]  {, U; d- Z8 c9 n+ N
1  X+ `$ z0 F& @/ M. t# d# s" p
2
( R4 o* o8 {0 H4 z
cd fabric-samples/first-network+ U( \3 p( W; z* p0 H5 O. I
./byfn.sh up -n
: L& a7 j" q# y. B
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。
" D& n. @6 w6 h/ k0 W) a6 [STEP 2:打包SACC链码3 l7 A0 d8 i/ I: N8 b4 m, |! ~
首先我们处理依赖问题:
- O8 V( A7 {  q, N
1
0 d! b& F/ O& R/ W! J/ }. V' j* Z/ m  I# R2
' N, A; ?! _. y5 O% Q3
" n" _) U( p$ \9 f3 p' z! ?
cd fabric-sample/chaincode/sacc
  U  A, [& h# t8 q, ^GO111MODULE=on go mod vendor- W5 M4 M& t' _
cd fabric-sample/first-network* I$ v8 s% M8 |: d
然后打包链码:  R3 s" Y( w* l* k1 k$ b- M
1) _: L4 U6 z8 ^9 {
2$ C) r- a. t3 s$ j
36 f, w9 K' A7 n4 X+ w
docker exec cli peer lifecycle chaincode package sacc.tar.gz \
; G3 p5 U: f' T$ q( `. M  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \/ M/ t/ P. }0 _5 H3 e
  --label sacc_1% _$ ^0 ?( o  I
在CLI容器内可以看到生成了新的文件sacc.tar.gz:
) Z0 ^3 B7 C3 J# _; Y  Z% ~5 fSTEP 3:在指定peer节点上安装SACC链码包
9 R! Y& z; l* T1 e, l9 v现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。
, Q1 Z% s1 U/ L3 e2 {, V* J
1+ ]: z$ F7 b0 g9 M8 F+ B# B3 a
2# d1 e' B5 e1 F' [( _. y  ]
3: C/ I3 G$ [1 e$ N/ ?3 @
4* V8 k: I: O; M1 v9 ]  h% T
5
* l7 U/ Z( B& T" S( A4 G9 k6/ f! s; W) m- e4 p7 Y3 z6 d( Z
7
9 t1 s, ?, H( g8
0 b# y$ G) ]5 G* v3 w0 l; q' H9) K) A" p0 d% \/ G, c) L8 c
10
# r' }# o1 W1 a  {- P- c5 N
# peer0.org1) ?' [( t! }% e( k
docker exec cli peer lifecycle chaincode install sacc.tar.gz
2 N! Y# h7 W' `+ w1 a$ J1 j# peer0.org29 c0 f! t8 ], A; k
docker exec \8 Z/ @3 z/ |4 v" p* d
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \$ p, m1 L- T. @9 S8 v4 }- m9 C
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \0 b% c5 @) t3 R; s; G7 s
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
# T2 o0 n7 G# O& O: S$ M7 B8 k2 C  -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 \" {  j& e, o& J# f( u
  cli peer lifecycle chaincode install sacc.tar.gz3 h- P8 ]$ k, c* c" o1 ^
. q: |4 t+ y- ]% d
我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。
) A+ e' a' z5 s* g4 T我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。
) @! O' C5 ~9 O* w5 \# V, A5 f# q
1
- Z* f2 E; U2 D+ F% p2
, X! b* I& R, V. l( B3
2 Q' ?; N! M, M" V! D  Z4
$ z# Q/ m+ _0 w; L9 s5 n3 a5, I# h+ [* B! J: }# n
6  a1 F# @- l* m) Q: v1 [
73 z# Z2 H; [( S3 I
8
0 m. P" o8 V+ G1 Q7 p( h( l1 U' x+ Q9
0 ]! B, }+ g; G1 w2 }+ u10
: ?6 V* W- w9 f% R/ h9 M
# peer0.org10 ?5 W: p1 I: I! c
docker exec cli peer lifecycle chaincode queryinstalled
* h3 Y' A3 ]0 z# peer0.org2
! l5 S) s6 a# xdocker exec \
' Y- L7 N* `7 u; b  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \& o# Z* h7 T( Y  K+ d0 n. J7 M- L
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \7 @3 _, @' r1 ~
  -e CORE_PEER_LOCALMSPID="Org2MSP" \! J% a: O& T* b
  -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 \
/ n0 U% j5 d, @, `) M) I  cli peer lifecycle chaincode queryinstalled$ Z, ^/ T2 z7 |; I  I( g
STEP 4:审批链码5 d" L$ ~5 e5 M* `
根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。8 A+ R$ C* a% ^9 H
首先是Org1批准链码:
5 H3 p- k$ P% O5 ^% W% ^
1; E( |8 t7 c7 \( E
2
) H3 C4 n, C% m. v- p# r30 l9 H$ b  j9 g  r
46 `: H. p$ E  k- h
5
" w) _# o! V  F" f) W: f6 R
docker exec cli peer lifecycle chaincode approveformyorg \$ S8 y. j3 f! {
  --tls \
" u  j" c6 i+ F  d/ \1 i2 ?1 Y+ E  --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$ ?/ M6 F! X+ `6 [+ c, H- ^
  --channelID mychannel --name mycc --version 1 \
; u/ X! Q/ y! J0 N  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}+ t1 `; l& w, S5 T, ~" r. z

$ W7 |, x+ k% c3 \& \6 a( t) O如果我们现在看下peer节点的日志,可以看到出了新块#3。
% D! D( _' S8 N8 ]9 N类似的,我们让Org2批准链码:
1 l- A  a4 G) f# U9 T
11 Y$ i; J9 U" t6 X
21 Z# J: X+ L( D& m: Q! H
3. r0 a- q6 K. P0 B2 }( a  A1 W# N* ?( d
4
% m& N1 T; Q% s5# h9 R. J4 a$ o  ?6 Q
63 g' |  |4 h* ?- t- I7 r; y/ `
7
" f! {0 I. [* k6 b0 o' I1 E5 }8# I. ^" M# X8 a: @4 _! g% ]
9. `. C% @) ^& |% G0 o- S4 X" `& F
10
3 Z3 g1 F4 Z3 E5 k9 E' i
docker exec \7 x3 X4 L1 A8 O9 J: J
  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \- r9 {/ y8 f) Q
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
0 h' ]$ ?" m. e" B% [% s; T  -e CORE_PEER_LOCALMSPID="Org2MSP" \
7 _4 d4 `7 P6 ~( {  -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 \
; D: ?" z/ P% t! c  cli peer lifecycle chaincode approveformyorg \" `+ i& ]7 f3 k
  --tls \9 j7 R: n& u) ^- s8 Q& t
  --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 J: C6 h2 Q- |3 ~4 L  --channelID mychannel --name mycc --version 1 --init-required \9 ]* A( p- R! E1 B3 D, q
  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}, U% Y/ `3 W4 S( W" S) [

- Z; d  r2 N& d' P* d* I: Y不出意外,可以看到出了新块block#4:/ b& H: }3 P$ J
注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。4 q( p0 n! }# ]  f; J2 }
可以随时使用如下命令查看链码的提交状态:
5 Q( V9 h$ S8 K8 p% `7 y
16 K, X: N3 i+ p9 [0 T& b
2  Z; Q( K, W! u3 x, K3 n. C5 E
docker exec cli peer lifecycle chaincode checkcommitreadiness \
. N$ V, N8 f9 T$ Y4 x  --channelID mychannel --name mycc --version 1 --sequence 1 --output json; {9 b* b- e2 f

  {* l! W+ M) F4 D( ?两个机构都已经批准了链码,现在可以提交了。
6 I5 Q, T+ P' r: S5 I8 h7 ?STEP 5:向通道mychannel提交链码  l" u+ D; [" X9 g4 s1 `
链码提交可以在一个peer节点上完成:! O0 t3 c" k& f2 l" r! W
1. A% `. ^/ w6 @4 b' i
2* _. p4 B+ `" Y* D& T6 r' H
3- N) O: v9 N& a3 ?% B
46 K! W! i2 r0 b" ]
53 w. U) a5 ^/ w; F0 Z+ A
6/ q) {9 i# b# T. w
72 ^& A! O8 }7 {) D& p
8" Q- `- |( q4 Z4 J- t
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \8 s" c- V6 r5 z% g& a; i
  --tls \
9 Y# ?8 N9 `+ v& ^4 f+ 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 \! Q( Y! I  K2 K( j8 B. u% [7 W$ |
  --peerAddresses peer0.org1.example.com:7051 \7 N. f! O8 _$ E4 k! H3 ^# b) O
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
' a' j- ?! v- E3 [  --peerAddresses peer0.org2.example.com:9051 \
+ `3 h7 f8 v" R* D1 K* c  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
4 k2 P* q- ?$ u  V3 y6 @! p  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required, D. r7 o* J3 d8 a

. J. O0 G" Y$ E* ]可以看到出了新块#5:
* t; j6 ~2 R/ T! ]# |( b注意我们在commit命令中已经包含了init所需的参数。. }$ S4 d: n! N7 O0 f
同样,我们可以使用querycommited命令来查看链码的提交状态:
8 Z5 v7 L. J& ^
1& |3 N5 @6 D" X+ d$ v; a( \1 c
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc+ t, y6 n- J5 R$ m4 m* ~7 @

: M4 {/ Y+ `% u$ z在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。/ ~9 K  v0 y) b) h5 h
STEP 6:调用链码的Init方法# m$ P% b' R( y2 m! K6 z0 a
SACC链码的Init方法需要首先调用。+ I0 L* `* D. [! G
17 t! q, y0 t1 q" D: Y( A
27 b  Y5 g: \) C5 K8 W3 B& G+ w1 {
3+ R$ b3 H# N% Y. t
4
- w, Q6 U- I* W' z6 h7 V& ^51 S. O! H8 U5 P0 k; k  F2 f5 t
69 O+ y$ c2 ^. i4 e! P
76 e$ ]! l0 p6 f% m
8
4 [. f7 x; }* l/ d% {" }. Z$ S2 x
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \- \6 W7 `0 X% X% ]" T4 u' P( I
  --tls \
* o! |) ]) h/ Y$ w: o6 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 \
4 o7 l- @" E. r  --peerAddresses peer0.org1.example.com:7051 \, E* u1 V+ r# G& ?1 l# l
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
: f* l; F0 B! c5 {* ?$ a4 Q1 a  --peerAddresses peer0.org2.example.com:9051 \
8 s4 P9 k3 l: e3 a2 q6 D* t& [  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
1 C( X# y, H; ~* k& a6 x  G6 I  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'1 ^/ o  Z6 O" Q: w, r, U

* U0 Z  P1 a9 \- g: }5 T% Q现在可以查询 链码:8 q) v& W  o6 v) ?
13 H: W' ?2 v$ z
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'
% r) Z! S5 t4 O8 d- N" x

, R1 `/ M7 n+ b; e! J3 l; ISTEP 7:调用链码的set()方法并从另一个peer节点查询
0 e8 J# Q1 @( {. l- ?( p和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:
: Y: r4 ?9 I( H! A" h
1
& ^/ Y. M9 _8 k1 D6 `: ]+ C' {28 S  a. m' h, L) r4 w( d& N
3
3 H) c0 a4 p! X! o/ f4
% Y1 e3 Z6 d% [3 {# }5
5 ]; z. t. B) p: C# n% U65 J* L' x4 n* i0 Q1 e
7
! J! o1 j4 @; V, _& d8
  Q' r5 V3 u) [$ L9
5 X- f( ?7 S7 C100 Y6 M, q- t* {+ D& x3 u$ _
11
' f2 c: |: D( C& b8 F/ q12
+ P4 R. F' G: x$ G. c, E13% S+ y* v1 m1 x) o" K" V9 N. W
14
6 D" i) e% n, L  S: T15
% O5 P$ y7 ~$ i" y16
, Z9 J# j. S5 W  g17* O. Z. I1 l! ?: }& @
18# J( j, l  t2 l
# peer0.org1
+ r" {& P( O2 U7 B/ p6 u7 Rdocker exec cli peer chaincode invoke \: z! R" W" a0 P* m, b0 y
  -o orderer.example.com:7050 \9 i) z) C8 e/ u& _: @& t
  --tls \
, d( k" ?& \' `- k: 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 \' v0 O6 r+ A2 q8 W' c+ y
  --peerAddresses peer0.org1.example.com:7051 \
) O/ @2 ?3 M1 t/ J! c4 R: t# b  R5 O  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
: b! w; j* W; [- b/ E  --peerAddresses peer0.org2.example.com:9051 \7 I( W4 L, O/ H9 S! b7 d! R
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt \
# B( \4 M" L% M$ Q! V: G6 }' U0 _  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'5 }, h: c! l1 n! f; E7 S
  
; J" R' ^& v% t  # peer0.org2* M1 {8 C" _) X& B. F8 V$ d
docker exec \
( d* O* z$ A4 k& Q) T& S  -e CORE_PEER_MSPCONFIGPATH=/opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp \$ p/ G9 p$ p, w) A% Q- q9 A
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
% {" |2 V- ~2 z  -e CORE_PEER_LOCALMSPID="Org2MSP" \
' H' K  J7 r% r0 f9 [1 k6 f- y  ^  -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 \
) L0 ?# c' `. o6 K  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'0 `- x/ D8 D+ {! B. _  q

* G2 r# Q/ S/ |/ n+ w一切正常。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

青丝暮雪780 初中生
  • 粉丝

    0

  • 关注

    2

  • 主题

    11