参考:http://hyperledger-fabric.readthedocs.io/en/latest/write_first_app.html

本文的目的就是基于Hyperledger Fabric network学习第一个application,blockchain上的application最基本的作用就是查询以及更新账本。看完本文后,将会对application(使用Node.js的fabric SDK)如何与fabric Ledger进行交互的有一个初步了解。

一.开始一个Test Network

首页需要确保Hyberledger Fabric所需要的环境已经安装完成。(安装可以参考http://www.cnblogs.com/studyzy/p/6973334.html

克隆一个fabric-samples仓库,然后进入fabcar子目录

git clone https://github.com/hyperledger/fabric-samples.git
cd fabric-samples/fabcar

fabcar目录下包括用于运行样例app的脚本以及应用程序,输入ls,能看到如下文件或文件夹

chaincode    invoke.js       network         package.json    query.js        startFabric.sh

我们使用startFabric.sh启动网络,接下来的命令会下载与安装Fabric docker镜像

./startFabric.sh

上述命令主要

1.启动了一个peer节点、一个ordering节点、一个CA以及CLI容器

2.创建了一个channel,同时把peer加入到channel中

3.在peer的文件系统上安装并实例化了智能合约(chaincode),启动了一个chaincode容器

4.调用了initLedger函数在channel Ledger上生成了10个car

上述操作由一个组织(organization)或者节点(peer)admin实现。startFaric.sh脚本使用CLI执行上述命令,具体参考Hyperledger Fabric Node SDK repo

使用docker ps -a命令查看刚启动的容器。

下图简要的说明了,application如何与fabric network进行交互的。

 

application如何与network进行交互:application使用API去调用智能合约(chaincode),这些chaincode被托管在network中,同时chaincode的名称与版本是得到认证的。例如,chaincode容器 - dev-peer0.org1.example.com-fabcar-1.0 - ,其中名称是fabcar,版本是1.0,peer是dev-peer0.org1.example.com

二.查询Ledger

查询就是从Ledger上读取数据,可以通过单键值或者多键值查询。假如Ledger使用类似json的富数据存储方式,那么其支持复杂查询(例如模糊查询)。

在fabcar目录下,我们可以使用query.js代码可以用于查询在Ledger上的car详情。

接下来运行JavaScript程序query.js,将会返回在Ledger上的car列表

node query.js

返回值为

Query result count =
Response is [{"Key":"CAR0", "Record":{"colour":"blue","make":"Toyota","model":"Prius","owner":"Tomoko"}},
{"Key":"CAR1", "Record":{"colour":"red","make":"Ford","model":"Mustang","owner":"Brad"}},
{"Key":"CAR2", "Record":{"colour":"green","make":"Hyundai","model":"Tucson","owner":"Jin Soo"}},
{"Key":"CAR3", "Record":{"colour":"yellow","make":"Volkswagen","model":"Passat","owner":"Max"}},
{"Key":"CAR4", "Record":{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}},
{"Key":"CAR5", "Record":{"colour":"purple","make":"Peugeot","model":"","owner":"Michel"}},
{"Key":"CAR6", "Record":{"colour":"white","make":"Chery","model":"S22L","owner":"Aarav"}},
{"Key":"CAR7", "Record":{"colour":"violet","make":"Fiat","model":"Punto","owner":"Pari"}},
{"Key":"CAR8", "Record":{"colour":"indigo","make":"Tata","model":"Nano","owner":"Valeria"}},
{"Key":"CAR9", "Record":{"colour":"brown","make":"Holden","model":"Barina","owner":"Shotaro"}}]

展示了10辆车,本例中,car1到car9是key值,record是value值。

我们来看看query.js里面有哪些内容,通过vim打开query.js

vim query.js

发现初始化的参数options包括了chaincode ID,channel名称以及network端点

var options = {
wallet_path : path.join(__dirname, './network/creds'),
user_id: 'PeerAdmin',
channel_id: 'mychannel',
chaincode_id: 'fabcar',
network_url: 'grpc://localhost:7051',
}

以下是我们构建的查询块

const request = {
chaincodeId: options.chaincode_id,
txId: transaction_id,
fcn: 'queryAllCars',
args: ['']
}

chaincode_id用于确定具体的chaincode,接下来调用在chaincode中定义的queryAllCars函数。

在我们执行node query.js时,调用了queryAllCars函数用于查询Ledger。除了queryAllCars函数之外,还有initLedger, queryCar, queryAllCars, createCar 以及 changeCarOwner函数可以调用。

接下来,我们打开fabcar.go,看看queryAllCars函数是如何实现查询所有car的。

func (s *SmartContract) queryAllCars(APIstub shim.ChaincodeStubInterface) sc.Response {
startKey := "CAR0"
endKey := "CAR999"
resultsIterator, err := APIstub.GetStateByRange(startKey, endKey)
}

该函数使用的fabric shim接口GetStateByRange,用于返回startKey与endKey之间的Ledger数据。这些定义分别被定义为CAR0以及CAR999,因此理论上我们可以创建1000辆车,一个queryAllCars函数即可查询所有车辆信息。

下图表示一个app是如何调用不同的chaincode的函数。

其中createCar用于更新Ledger,同时最终增加了一个新的block到链上。

回到查询功能上,让我们回到query.js程序,同时我们将代码中的queryAllCars改成queryCar,同时对key值进行修改,这里key值暂时使用CAR4,query.js将会包括如下代码:

const request = {
chaincodeId: options.chaincode_id,
txId: transaction_id,
fcn: 'queryCar',
args: ['CAR4']
}

输入node query.js后将会查出如下结果:

{"colour":"black","make":"Tesla","model":"S","owner":"Adriana"}

本次查询只查询一辆车,调用了queryCar函数,通过key值去查询。

三.更新Ledger

上面我们调用chaincode的查询函数对车辆信息进行了查询,接下来,我们需要尝试对Ledger进行修改。

首先application先生成一个transaction proposal。就想query的request的一样,这里也需要生成一个request。程序接下来调用channel.SendTransactionProposal API 把transaction proposal发送到endoring peer。

接着,network(也就是endorsing peer)会返回一个proposal response,application通过这个response对transaction request进行build与sign。然后把这个处理过的request通过channel.sendTransaction API发送至ordering serivce。ordering service将会把transaction打包至到block,接着把block发送到channel中的所有peer做验证。

最后,application使用eh.setPeerAddr API  连接到peer的事件监听端口,同时调用eh.registerTxEvent方法并使用具体的transactionID注册事件。该API使得application能够追踪到transaction的具体情况(提交成功还是失败)。其实就是一个通知机制。

通过执行invoke.js我们创建了一个新的asset(一辆车)。打开invoke.js,我们能够找到类似query.js中的request。

vim invoke.js

能够看到request内容

// createCar - requires 5 args, ex: args: ['CAR11', 'Honda', 'Accord', 'Black', 'Tom'],
// changeCarOwner - requires 2 args , ex: args: ['CAR10', 'Barry'],
// send proposal to endorser
var request = {
targets: targets,
chaincodeId: options.chaincode_id,
fcn: '',
args: [''],
chainId: options.channel_id,
txId: tx_id
}

接下来,我们将调用createCar 或 changeCarOwner生成一个新的车。参数如下所示

var request = {
targets: targets,
chaincodeId: options.chaincode_id,
fcn: 'createCar',
args: ['CAR11’, ‘Audi’, ‘A4’, ‘Black’, ‘Xiaohu Li’],
chainId: options.channel_id,
txId: tx_id
}

输入node invoke.js能够看到

peer发出了该事件通知,我们的application通过eh.registerTxEvent API收到了该通知。接下来,我们回到query.js,修改查询key值为CAR11,然后执行代码。

node query.js

接下来我们能够看到如下信息:

说明我们刚创建的车辆信息已经写入Ledger中了。

Hyberledger-Fabric 1.00 RPC学习(1)的更多相关文章

  1. Hyberledger-Fabric 1.00 RPC学习(2)尝试建立一个network

    本文参考:http://hyperledger-fabric.readthedocs.io/en/latest/build_network.html 这里我们学习建立第一个Hyperledger Fa ...

  2. HyberLedger Fabric学习(3)-chaincode学习(开发者)

    参考:http://hyperledger-fabric.readthedocs.io/en/latest/chaincode4ade.html chaincode是由go语言写的,实现了定义的接口. ...

  3. RPC学习--C#使用Thrift简介,C#客户端和Java服务端相互交互

    本文主要介绍两部分内容: C#中使用Thrift简介 用Java创建一个服务端,用C#创建一个客户端通过thrift与其交互. 用纯C#实现Client和Server C#服务端,Java客户端 其中 ...

  4. fabric私密数据学习笔记

    fabric私密数据学习笔记 私密数据分为两部分 一个是真正的key,value,它被存在 peer的私密数据库(private state)中. 另一部分为公共数据,它是真实的私密数据key,val ...

  5. HyberLedger Fabric学习(4)-chaincode学习(操作人员)

    参考:http://hyperledger-fabric.readthedocs.io/en/latest/chaincode4noah.html chaincode也能被称作“智能合约”,一般情况下 ...

  6. 【公司要求】- RPC学习(一)

    HADOOP-IPC(这里说的是1.0.4版本) 是轻量级RPC,在hadoop中主要用于2方面 1.TaskTracker和JobTracker 通讯. 2.NameNode和DataNode通讯. ...

  7. Hyperledger Fabric【区块链学习一】

    Hyperledger Fabric 学习 什么是区块链 什么是区块链在我们没有接触的时候,只知道它是一个去中心化的存储方式.当我们发生交易,或者动作的时候我们会将记录通知给所有参与者共同维护,达到去 ...

  8. [RPC学习]Dubbo+nacos实现动态更新内存RTree

    1.背景 服务架构一般都是从 单体架构 -> 微服务架构 -> 分布式架构 的迭代,我上一家公司就是在业务发展到一定规模时,开始拆老的单体服务,按业务维度拆成多个微服务,服务之间用的是HT ...

  9. RPC学习----Thrift快速入门和Java简单示例

    一.什么是RPC? RPC(Remote Procedure Call Protocol)——远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议. RPC协议 ...

随机推荐

  1. 最全android Demo

    1.BeautifulRefreshLayout-漂亮的美食下拉刷新 https://github.com/android-cjj/BeautifulRefreshLayout/tree/Beauti ...

  2. SQL Server 查询优化 索引的结构与分类

    一.索引的结构 关系型数据库中以二维表来表达关系模型,表中的数据以页的形式存储在磁盘上,在SQL SERVER中,数据页是磁盘上8k的连续空间,那么,一个表的所有数据页在磁盘上是如何组织的呢?分两种情 ...

  3. 将keras模型在django中应用时出现的小问题——ValueError: Tensor Tensor("dense_2/Softmax:0", shape=(?, 8), dtype=float32) is not an element of this graph.

    本文原出处(感谢作者提供):https://zhuanlan.zhihu.com/p/27101000 将keras模型在django中应用时出现的小问题 王岳王院长 10 个月前 keras 一个做 ...

  4. 各种排序算法思想复杂度及其java程序实现

    一.冒泡排序(BubbleSort)1. 基本思想: 设排序表长为n,从后向前或者从前向后两两比较相邻元素的值,如果两者的相对次序不对(A[i-1] > A[i]),则交换它们, 其结果是将最小 ...

  5. Coderforce-574C Bear and Poker(素数唯一分解定理)

    题目大意:给出n个数,问能不能通过让所有的数都乘以2的任意幂或乘以3的任意幂,使这n个数全都相等. 题目分析:最终n个数都是相等的,假设那个数为x,根据素数唯一分解定理,x能分解成m*2p3q.所以, ...

  6. The web application you are attempting to access on this web server is currently unavailable.......

    今天去服务器安装了个.net 4.0 framework(原本有1.0和2.0的),配置好站点后,选择版本为4.0,访问出错,错误代码如下 Server Application Unavailable ...

  7. VirtualBox使用物理硬盘建立磁盘

    VirtualBox,只能用命令行来 建立磁盘才可以使用物理硬盘. 1.运行cmd,cd进入你的VirtualBox目录,如:  cd C:\Program Files\Sun\VirtualBox ...

  8. Visio2010建立ER图并直接导出为SQL语句

    Visio2010建立ER图并直接导出为SQL语句 2013年08月20日 ⁄ 综合 ⁄ 共 2581字 ⁄ 字号 小 中 大 ⁄ 评论关闭 建立数据库时我们需要考虑数据之间的关系,为了理清数据之间的 ...

  9. Vim技能修炼教程(17) - 编译自己的Vim

    编译自己的Vim 前面我们已经对Vim有比较丰富的了解了.我们也知道Vim有很多编译时的选项,很多功能依赖于这些编译选项.其中最重要的就是脚本语言的支持,很多发行版本是不全的.为了支持我们所需要的功能 ...

  10. Yii隐藏单入口

    Yii进入项目首页时默认是index.php文件路径,如何把index.php去掉,方法如下: 打开apache配置文件http.conf,找到如下的代码: #LoadModule rewrite_m ...