Hi Guest

More contents, please log on!

Bitmere.com 区块链技术 Content

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

青丝暮雪780
36 0 0
Hyperledger Fabric 2.0最近已经发布,其中最引人关注的一点是 链码操作。官方文档虽然对此提供了详细的说明,但本文将通过与 Hyperledger Fabric前一个版本中链码操作的对比,来帮助你更好的 理解新版本中链码操作的不同之处以及幕后的一些技术细节。
1、链码操作:Fabric 1.4 vs Fabric 2.0我们将首先快速介绍在HF 1.4和HF 2.0中的整个链码操作过程。
链码操作指的是在Hyperledger fabric网络通道上部署链码的操作,这样区块链 之外的应用可以调用或查询链码方法。在链码开发完成并测试后,首先需要 将Fabric链码安装到指定的peer节点。在这个阶段链码还不能使用,直到 链码被提交(Fabric 2.0中的术语)到通道中或在通道上实例化(Fabric 1.4中的 术语),这样链码就可以被授权用户访问了。
下面是两个版本的Hyperledger Fabric中链码操作流程的对比图:
在Hyperledger Fabric 1.4中,链码操作过程包含以下步骤:打包、安装、实例化。 如果链码属于多个参与方,那么就需要打包这一环节。如果不存在多方属主的问题, 那么直接安装链码就可以(其中隐含了打包环节)。在Fabric链码安装时需要指定 要安装链码的目标节点。
在这个阶段,安装好的Fabric链码还不能使用,因为它还没有在通道上实例化。 当Fabric链码包被安装在指定的节点上之后,我们就可以执行链码实例化操作, 从而让链码在通道上可用。技术上来说,链码实例化实际上就是调用LSCC系统链码 的方法来初始化通道上的一个链码。
Fabric链码实例化之后就可以使用了,可以接受通道上的调用或查询请求。
下面我们看在Hyperledger Fabric 2.0中的链码操作步骤有何区别。
宽泛地来讲,在Fabric 2.0中链码操作基本遵循同样的流程,但是在命令和某些 后台处理中做了一些调整。整体的流程可以分为四个步骤:打包、安装、机构审批、 链码提交。大致可以认为前两个环节对应于Fabric 1.4中的链码安装,后面两个 环节对应于Fabric 1.4中的链码实例化,但是实例化(instantiation)这个词不再 用了。
链码打包这一步是创建一个打包文件(tar格式),其中包含Fabric链码以及一些元数据。 虽然不同的机构可以分别进行打包处理,更常见是由一个机构打包然后分发给其他 机构以便确保所有的机构使用相同的链码。
安装步骤是将打包的Fabric链码文件安装在指定的peer节点上。和之前的版本一样, 只有需要接受链码调用的节点才需要安装链码。在这个节点,Fabric链码还不可用, 因为还没有提交到通道中。链码安装的结果是得到一个包标识符,其格式为.。
机构审批是在Hyperledger Fabric 2.0中增加的步骤。在之前的版本中我们可以让 一个机构实例化链码。在Fabric 2.0中,需要机构显式地审批链码。需要多少机构 审批则是由生命周期背书策略来决定,默认情况下设置为需要大多数机构(超过半数)。 如果Fabric网络中包含两个机构,那么就需要这两个机构同时批准。在审批过程中 需要排序节点的参与,因为每次审批都会生成一个新的区块,这意味着所有的peer 节点都了解审批的状态。
当审批环节完成后,我们就需要指定要在哪个通道上部署链码。这需要提交一些信息, 例如背书策略、是否需要执行Init代码等等。在这里也有些与Fabric 1.4不同的地方: 在Fabric 1.4中,当链码实例化时会自动调用链码的Init方法,然而在Fabric 2.0中, 需要在提交链码后显式地调用Init方法。
在批准机构达到指定数量后,链码就可以提交了。我们现在就进入了最后一个步骤: 链码提交。
链码提交可以由任何机构发起。该流程首先需要批准机构的背书,然后交易提交到 排序服务并生成新的区块,最后所有的对等节点在账本中提交该区块。
现在链码就可以使用了。
2、First Network和SACC链码简介出于完整性考虑,下面给出关于First Network和SACC链码的一些信息,这些内容 都来自fabric-samples仓库。
First Network是一个双机构设置,每个机构中包含两个peer节点。通道mychannel 创建后加入所有的4个peer节点。在byfn.sh中完整的实现了First Network的部署, 并包含一些可选的参数。在下面的演示中,我们不使用默认的链码(在Fabric 1.4 中式chaincode_example02,在Fabric 2.0中式abstore),而是使用SACC链码。
SACC式Simple Asset ChainCode的缩写,表示简单资产链码。它在账本中模拟一个 键/值存储。当初次部署后,需要一个初始的键/值对。SACC链码定义了两个方法: Set()和Get(),分别用来设置或读取某个键的值。
好了,现在我们可以开始演示Fabric 1.4和Fabric 2.0中链码操作的不同了。
3、Fabric 1.4.4链码操作演示我们首先以无链码方式(使用-n选项)启动First Network,然后我们再加载 SACC链码以便聚焦链码的生命周期。
下面是演示步骤:
无链码方式启动First Network在指定的peer节点上安装SACC链码在mychannel通道上实例化SACC链码并查询结果调用set()设置新值并从另一个peer节点查询结果STEP 1:首先启动First Network:
1
2
cd fabric-samples/first-network
./byfn.sh up -n
上面的命令会启动First Network、创建通道mychannel并将所有的peer节点加入该通道。 注意在Fabric 1.4.4中,First Network使用solo排序服务实现,只有一个排序节点。 另外,我们看到有4个对等节点在运行,以及一个CLI用于链码操作。
现在我们可以开始链码部署操作。
STEP 2:在指定peer节点上安装链码
这里我们跳过打包环节,直接在目标节点peer.org1和peer0.org2上安装链码, 因为在这个演示中我们只需要这两个节点进行链码调用和查询。
1
2
3
4
5
6
7
8
9
10
# peer0.org1
docker exec cli peer chaincode install -n mycc -v 1 \
  -p github.com/chaincode/sacc
  
# peer0.org2  
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 \
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 -e CORE_PEER_LOCALMSPID="Org2MSP" \
  -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 \
  cli peer chaincode install -n mycc -v 1 -p github.com/chaincode/sacc

STEP 3:在通道mychannel上实例化链码并查询
注意在sacc链码中有Init()代码。当我们实例化链码时,我们需要 提供Init()所需的参数:
1
2
3
4
docker exec cli peer chaincode instantiate -o orderer.example.com:7050 --tls \
  --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 mychannel -n mycc -v 1 -c '{"Args":["name","kc"]}' \
  -P "AND ('Org1MSP.peer','Org2MSP.peer')"

如果现在看看peer节点的日志,我们可以看到出了新区块#3。
在链码实例化之后,我们可以查询:
1
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'

STEP 4:调用set()设置新值并从另一个节点查询
出于演示目的,我们在peer0.org1上调用set(),然后在peer0.org2上 调用get(),以此说明链码是否工作正常。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# peer0.org1
docker exec cli peer chaincode invoke -o orderer.example.com:7050 --tls \
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --peerAddresses peer0.org1.example.com:7051 \
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
  --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 \
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
  
  # peer0.org2
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 \
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
  -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 \
  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'

4、Fabric 2.0链码操作演示类似的,在Fairc 2.0.0中,我们也先以无链码方式启动First Network, 然后再启动SACC链码以便聚焦链码的生命周期。
下面是演示步骤:
无链码方式启动First Network打包SACC链码在指定peer节点上安装SACC链码包机构审批链码在mychannel通道上提交链码调用SACC链码的Init方法调用SACC链码的set方法并从另一个peer节点查询结果STEP 1:以无链码方式启动First Network:
1
2
cd fabric-samples/first-network
./byfn.sh up -n
现在First Network已经启动,通道mychannel已经创建并且所有peer节点 已经加入mychannel通道。注意在Fabric 2.0.0中,First Network使用Raft 作为排序服务,所有5个排序节点都在运行。在这个演示中,我们只使用 orderer.example.com,不过使用其他排序节点也是一样的。
STEP 2:打包SACC链码
首先我们处理依赖问题:
1
2
3
cd fabric-sample/chaincode/sacc
GO111MODULE=on go mod vendor
cd fabric-sample/first-network
然后打包链码:
1
2
3
docker exec cli peer lifecycle chaincode package sacc.tar.gz \
  --path github.com/hyperledger/fabric-samples/chaincode/sacc/ \
  --label sacc_1
在CLI容器内可以看到生成了新的文件sacc.tar.gz:
STEP 3:在指定peer节点上安装SACC链码包
现在我们在peer0.org1和peer0.org2上安装SACC练马报,因为在这个 演示中我们只需要使用这两个节点进行链码调用和查询。
1
2
3
4
5
6
7
8
9
10
# peer0.org1
docker exec cli peer lifecycle chaincode install sacc.tar.gz
# peer0.org2
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 \
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
  -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 \
  cli peer lifecycle chaincode install sacc.tar.gz

我们会收到链码包的标识符,在下面的链码审批阶段会用到。我们 收到的链码标识符为:sacc_1:bf57…6399。
我们可以使用peer lifecycle chaincode queryinstalled命令随时 检查节点上的链码安装情况,如果我们需要找出链码包的标识ID,这个命令 会很有用。
1
2
3
4
5
6
7
8
9
10
# peer0.org1
docker exec cli peer lifecycle chaincode queryinstalled
# peer0.org2
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 \
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
  -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 \
  cli peer lifecycle chaincode queryinstalled
STEP 4:审批链码
根据默认策略,需要超过半数的机构审批链码后才能向通道提交链码, 具体可参考configtx.yaml中的Application/Policies/LifecycleEndorsement部分。 目前的设置中包含两个机构,因此需要两个机构同时批准链码。
首先是Org1批准链码:
1
2
3
4
5
docker exec cli peer lifecycle chaincode approveformyorg \
  --tls \
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --channelID mychannel --name mycc --version 1 \
  --init-required --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}

如果我们现在看下peer节点的日志,可以看到出了新块#3。
类似的,我们让Org2批准链码:
1
2
3
4
5
6
7
8
9
10
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 \
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
  -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 \
  cli peer lifecycle chaincode approveformyorg \
  --tls \
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --channelID mychannel --name mycc --version 1 --init-required \
  --sequence 1 --waitForEvent --package-id ${PACKAGE_ID}

不出意外,可以看到出了新块block#4:
注意我们在approval命令中指定了init相关的参数,以便向SACC链码的 Init方法传入所需的参数。
可以随时使用如下命令查看链码的提交状态:
1
2
docker exec cli peer lifecycle chaincode checkcommitreadiness \
  --channelID mychannel --name mycc --version 1 --sequence 1 --output json

两个机构都已经批准了链码,现在可以提交了。
STEP 5:向通道mychannel提交链码
链码提交可以在一个peer节点上完成:
1
2
3
4
5
6
7
8
docker exec cli peer lifecycle chaincode commit -o orderer.example.com:7050 \
  --tls \
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --peerAddresses peer0.org1.example.com:7051 \
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
  --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 \
  --channelID mychannel --name mycc --version 1 --sequence 1 --init-required

可以看到出了新块#5:
注意我们在commit命令中已经包含了init所需的参数。
同样,我们可以使用querycommited命令来查看链码的提交状态:
1
docker exec cli peer lifecycle chaincode querycommitted --channelID mychannel --name mycc

在链码提交到通道之后,链码的生命周期就完成了,链码已经可以访问。 现在我们回到链码的调用和查询,这和之前的版本是一致的。
STEP 6:调用链码的Init方法
SACC链码的Init方法需要首先调用。
1
2
3
4
5
6
7
8
docker exec cli peer chaincode invoke -o orderer.example.com:7050 \
  --tls \
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --peerAddresses peer0.org1.example.com:7051 \
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
  --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 \
  -C mychannel -n mycc --isInit -c '{"Args":["name","kc"]}'

现在可以查询 链码:
1
docker exec cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'

STEP 7:调用链码的set()方法并从另一个peer节点查询
和之前一样,我们在peer0.org1上调用链码的set()方法,在peer0.org2上 进行查询:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# peer0.org1
docker exec cli peer chaincode invoke \
  -o orderer.example.com:7050 \
  --tls \
  --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem \
  --peerAddresses peer0.org1.example.com:7051 \
  --tlsRootCertFiles /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt \
  --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 \
  -C mychannel -n mycc -c '{"Args":["set","name","Peter"]}'
  
  # peer0.org2
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 \
  -e CORE_PEER_ADDRESS=peer0.org2.example.com:9051 \
  -e CORE_PEER_LOCALMSPID="Org2MSP" \
  -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 \
  cli peer chaincode query -C mychannel -n mycc -c '{"Args":["get","name"]}'

一切正常。
BitMere.com is Information release platform,just provides information storage space services.
The opinions expressed are solely those of the author,Does not constitute advice, please treat with caution.
You have to log in before you can reply Login | 立即注册

Points Rules

Write the first review

青丝暮雪780 初中生
  • Follow

    0

  • Following

    2

  • Articles

    11

币圈江左盟
Promoted