Fabric链码中使用CouchDB(release 2.2)

Fabric链码中使用CouchDB(release 2.2),第1张

前言 1. 为什么使用 CouchDB
   Fabric 支持两种类型的节点数据库。LevelDB 是默认嵌入在 peer 节点的状态数据库。 LevelDB 用于将链码数据存储为简单的键-值对,仅支持键、键范围和复合键查询。 CouchDB 是一 个可选的状态数据库,支持以 JSON 格式在账本上建模数据并支持富查询,以便您查询实际数据 内容而不是键。 CouchDB 同样支持在链码中部署索引,以便高效查询和对大型数据集的支持。
   为了发挥 CouchDB 的优势,也就是说基于内容的 JSON 查询,你的数据必须以 JSON 格式 建模。 你必须在设置你的网络之前确定使用 LevelDB 还是 CouchDB 。 由于数据兼容性的问 题,不支持节点从 LevelDB 切换为 CouchDB 。 网络中的所有节点必须使用相同的数据库类型。 如果你想 JSON 和二进制数据混合使用,你同样可以使用 CouchDB ,但是二进制数据只 能根据键、键范围和复合键查询。
2. CouchDB 是什么

Couch ( Cluster Of Unreliable Commodity Hardware ) , 它反映了 CouchDB 的目标具有高度可伸缩性,提供了高可用性和高可靠性,即使运行在容易出现故障的硬件上也是如此。

Apache CouchDB是一个开源数据库,专注于易用性和成为"完全拥抱web的数据库"。 它是一个使用JSON作为存储格式,JavaScript作为查询语言,MapReduce和HTTP作为API的面向文档的NoSQL数据库。 其中一个显著的功能就是多主复制。CouchDB的第一个版本发布在2005年,在2008年成为了Apache的项目。

不同于关系型数据库,CouchDB没有将数据和关系存储在表格里。替代的,每个数据库是一个独立的文档集合。 每一个文档维护其自己独立的数据和自包涵的schema。 一个应用程序可能会访问多个数据库,比如其中一个位于用户的手机上,另一个位于在远程的服务器上。 文档的元数据包含版本信息,让其能够合并可能因为数据库链接丢失导致的任何差异。

CouchDB实现了一个多版本并发控制(MVCC)形式,用来避免在数据库写 *** 作的时候对文件进行加锁。 冲突留给应用程序去解决。解决一个冲突的通用 *** 作的是首先合并数据到其中一个文档,然后删除旧的数据。

其他功能包括文档级别的ACID语义和最终一致性,MapReduce,复制(Replication)。 它还支持通过一个做Futon的内置web应用程序来进行数据库管理。

3. CouchDB 特点 3.1 文档存储

CouchDB将数据存储为“文档”,其为用JSON表示的有一个或者多个字段/值的对。 字段的值可以是简单的东西比如字符串,数字,或者时间;但是数组和字典同样也可以使用。 CouchDB中的每一个文档有一个唯一的id但是没有必须的文档schema。

3.2 ACID 语义

CouchDB提供了ACID语义,其通过多版本并发控制的形式来实现,意味着CouchDB能够处理大量的并发读写而不会产生冲突。

3.3 Map/Reduce 视图 和 索引

存储的数据通过视图进行组装。在CouchDB中,每一个视图都是由作为map/reduce *** 作中的Map部分的Javascript函数构成。 该函数接受一个文档并且将其转换为一个单独的值来返回。 CouchDB能够对视图进行索引,同时在文档新增,修改,删除的时候对这些索引进行更新。

3.4 支持复制的分布式架构

CouchDB的设计基于支持双向的复制(同步)和离线 *** 作。这意味着多个复制能够对同一数据有其自己的拷贝,可以进行修改,之后将这些变更进行同步。

3.5 REST API

所有的数据都有一个唯一的通过HTTP暴露出来的URI。 REST使用HTTP方法 POST,GET,PUT和DELETE来 *** 作对应的四个基本 CRUD(Create,Read,Update,Delete) *** 作来 *** 作所有的资源。

3.5 最终一致性

CouchDB保证最终一致性,使其能够同时提供可用性和分割容忍。

3.6 离线支持

CoucbDB能够同步复制到可能会离线的终端设备(比如智能手机),同时当设置再次在线时处理数据同步。 CouchDB内置了一个的叫做Futon的通过web访问的管理接口。
#4.如何在 fabric 中使用 CouchDB

启动fabric网络

需要使用CouchDB的话需要在启动网络的时候加上-s CouchDB即可
需要先进入net-work目录下

./nework.sh up createChannel -s CouchDB

##安装链码

1.下载 hyperledger-fabric-contract-java-demo 合约源码到本地机器
cd ~fabric-samples/chaincode/
git clone https://gitee.com/kernelHP/hyperledger-fabric-contract-java-demo.git
2. 返回到test-network所在目录

返回到test-network所在目录,以便可以将链码与其他网络部件打包在一起。

cd ../../test-network
3. 将bin目录中二进制文件添加到CLI路径

所需格式的链码包可以使用peer CLI创建,使用以下命令将这些二进制文件添加到你的CLI路径。

export PATH=${PWD}/../bin:$PATH
4. 设置FABRIC_CFG_PATH为指向fabric-samples中的core.yaml文件
export FABRIC_CFG_PATH=$PWD/../config/
5.创建链码包
peer lifecycle chaincode package hyperledger-fabric-contract-java-demo.tar.gz --path ../chaincode/hyperledger-fabric-contract-java-demo/ --lang java --label hyperledger-fabric-contract-java-demo_1

命令解释:此命令将在当前目录中创建一个名为 hyperledger-fabric-contract-java-demo.tar.gz的软件包。–lang标签用于指定链码语言,–path标签提供智能合约代码的位置,该路径必须是标准路径或相对于当前工作目录的路径,–label标签用于指定一个链码标签,该标签将在安装链码后对其进行标识。建议您的标签包含链码名称和版本。

6.查询包ID
peer lifecycle chaincode queryinstalled

包ID是链码标签和链码二进制文件的哈希值的组合。每个peer节点将生成相同的包ID。你应该看到类似于以下内容的输出:

7.将链码包id设置为环境变量

通过链码时,我们将使用包ID,因此,将包ID保存为环境变量。将返回的包ID粘贴到下面的命令中。 注意:包ID对于所有用户而言都不相同,因此需要使用上一步中从命令窗口返回的包ID来完成此步骤(每个人运行完生成的链码不同,请根据自己的修改)

export CC_PACKAGE_ID=hyperledger-fabric-contract-java-demo_1:f61f9e5b97d2034aa864bccd148dac36d0583c13176dfd267af1c8f34e7c03ae
8.Org2通过链码

因为已经设置了环境变量为peer CLI作为Orig2管理员进行 *** 作,所以我们可以以Org2组织级别将 hyperledger-fabric-contract-java-demo 的链码定义通过。使用 peer lifecycle chaincode approveformyorg命令通过链码定义:

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name hyperledger-fabric-contract-java-demo --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
9.Org1通过链码
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051

用 peer lifecycle chaincode approveformyorg命令通过链码定义

peer lifecycle chaincode approveformyorg -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name hyperledger-fabric-contract-java-demo --version 1.0 --package-id $CC_PACKAGE_ID --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem
10.将链码定义提交给通道

使用peer lifecycle chaincode checkcommitreadiness命令来检查通道成员是否已批准相同的链码定义:

peer lifecycle chaincode checkcommitreadiness --channelID mychannel --name hyperledger-fabric-contract-java-demo --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --output json

该命令将生成一个JSON映射,该映射显示通道成员是否批准了checkcommitreadiness命令中指定的参数:

由于作为通道成员的两个组织都同意了相同的参数,因此链码定义已准备好提交给通道。你可以使用peer lifecycle chaincode commit命令将链码定义提交到通道。commit命令还需要由组织管理员提交。

peer lifecycle chaincode commit -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --channelID mychannel --name hyperledger-fabric-contract-java-demo --version 1.0 --sequence 1 --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt

如果将链码成功提交给通道,该querycommitted命令将返回链码定义的顺序和版本:

链码已安装成功。

添加数据并查询 1.调用合约中的createCat函数添加数据

示例代码中只是添加了一条数据:

peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile ${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C mychannel -n hyperledger-fabric-contract-java-demo --peerAddresses localhost:7051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt --peerAddresses localhost:9051 --tlsRootCertFiles ${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt -c '{"function":"createCat","Args":["cat-0" , "tom" ,  "3" , "蓝色" , "大懒猫"]}'

2.使用富查询查看效果

示例代码中只查询了一次:

peer chaincode query -C mychannel -n hyperledger-fabric-contract-java-demo -c '{"Args":["queryCatByName" , "tom"]}'

3.使用分页查询查看效果
peer chaincode query -C mychannel -n hyperledger-fabric-contract-java-demo -c '{"Args":["queryCatPageByName" , "tom","此值为PageSize","此值为bookmark"]}'

注:bookmark的值是执行完分页查询后返回的值,如果不穿则默认第一页,穿了值,则查询出的是查询出的bookmark后面的一页。

4.新建索引

示例代码新建了一个索引:
{
“index”:{
“fields”:[“docType”,“owner”] // Names of the fields to be queried
},
“name”:“indexOwner”,
“type”:“json”
}

5.添加索引 5.1创建Json文件添加索引。

将上一步的代码写为一个json文件,添加到链码的META-INF/statedb/couchdb/indexes路径下

5.2页面添加索引

通过进入客户端来创建索引
http://localhost:5984/_utils

密码和账号放在/test-network/docker/docker-compose-couch.yml里

找到合约名字

现在可以看到里面有三条数据和一个索引

点击索引即可进行编辑

注:如果用CouchDB进行查询时进行了排序则排序字段必须建索引,否则会报错!

6.编写合约时使用索引 6.1富查询

6.2分页查询

个人学习心得,如有错误望指正!
参考文献:https://gitee.com/kernelHP/hyperledger-fabric-contract-java-demo

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/1298384.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存