区块链和物联网解决方案实用指南(二)
原文:
zh.annas-archive.org/md5/9b82e4292467bac72ed9aef40681c09a译者:飞龙
第六章:设计解决方案架构
在本章中,我们将审查我们基于物联网和区块链的食品物流网络解决方案的架构,探讨以下主题:
-
商业方面:我们将审查商业组件和商业方面的主要参与者,以及生产和消费者之间发生的过程。
-
技术:我们将呈现我们将要设计的技术解决方案的图表。
-
软件:我们将呈现一个详细描述软件层次和集成的解决方案图表。
我们还将更详细地审查一些涉及到我们基于物联网和区块链的解决方案的概念和架构。
食品业务
现代食品链非常庞大且复杂。有许多参与者参与影响产品的制造和交付,无论是直接还是间接的。
我们将研究这种现代食品生产过程,了解现代链条的挑战,并基于区块链和物联网提出一个新的链条:
在上图中显示的业务流程是现代食品链的简化版本。该链可能比此处所代表的要复杂得多。例如,许多超市都有自己的配送中心。然而,由于我们的主要目标是简化,我们没有代表其他因素,例如港口和海关。
对于我们的用例,我们将试图从制造商交付的时间开始考虑产品。这个产品可以是任何物品,但我们将用鸡腿作为例子。
我们链条中要管理的资产将是一箱装满鸡腿的箱子,我们的另一个资产将是一托盘装满装有鸡腿的箱子。在食品链中,我们将研究以下参与者的流程:制造商、配送中心和零售商。
如前所述,现代食品链中有很多参与者。请记住,我们遵循的是更简化的流程,不一定是实际生活中遵循的流程。我们的目标是理解物联网和区块链如何帮助食品链内的各方和流程。
过程的挑战
我们选择关注的食品链的一部分面临着许多挑战。我们在这里简要列出了它们:
-
从农民的角度来看的挑战:确保关于原材料的关键信息的文件化,例如产品描述、检验日期、屠宰日期和库存信息
-
制造商的挑战:确保产品来源和产品的安全交付和接收,将产品与电子产品包装在一起,为监管机构和消费者使用条形码/二维码信息标签,以及将产品聚合成包装
-
**零售商的挑战:**检查包装完整性,并通过日期、仓库验证和质量控制,保持产品包装在整个运输线上的可见性
-
**消费者的挑战:**对产品的来源以及包装中的信息有信心,快速识别商品,并在必要时从货架上移除可疑产品以及消费
食品工厂的过程
让我们从我们的目标过程开始。在我们的用例中,产品以大块形式到达工厂,在那里将被切割、包装,并放入销售用箱子中。这些产品被储存,并在交付之前装到托盘上。
托盘是用于移动货物的木质、金属或塑料平台,如下图所示:
接下来,我们将看到产品在转到下一阶段之前必须注册的重要数据。当产品到达时,捕获并记录以下数据:
-
库存管理单位(SKU)
-
动物来源
-
制造商名称
-
动物信息
-
质量控制
-
淘汰日期
-
冷冻
-
技术监督员详细信息
-
发货日期
-
温度和运输细节
在注册箱子或托盘时捕获以下细节:
-
SKU
-
日期
-
工厂地址
-
冷冻温度
-
质量记录
-
托盘代码
现在让我们检查链条中下一环节的过程。
配送中心的过程
产品在被切割、包装和运送后,到达配送中心,被接收并检查以供存储。根据过程的不同,产品可能会放在更适合运输的更大托盘上,可以通过火车或卡车运输:
为了避免产品出现任何问题,配送中心会审核工厂发送的数据。如果有任何额外的移动,如托盘转移,需要将新的信息添加到包装中:
-
对于产品,如下:
-
收货日期
-
托盘编号
-
收到的温度
-
存储温度
-
运输公司
-
质量封条
-
-
对于托盘,如下:
-
目的地代码
-
托盘代码
-
日期
-
发货温度
-
运输公司
-
检查后,产品被发送给零售商。
超市和商店的过程
商店将会接收产品并检查商品是否符合要求。如果符合,托盘被拆卸并箱子被打开。这结束了我们对资产的监控:
必须在这个阶段注册以下重要数据,产品才能到达消费者:
-
收货日期
-
托盘编号
-
收到的温度
-
存储温度
-
运输公司
-
质量封条
现在轮到商店负责给产品贴标签了,之后可能会直接放到货架上,也可能不会。
技术方法
现在我们对我们的流程和潜在问题有了更好的理解,让我们看看技术如何对我们有用。以下是标准区块链 Hyperledger Fabric 架构的表示:
前述图表向我们展示了三个重要层次:前端应用程序(左侧)、API/SDK(中心)、以及 Hyperledger Fabric 和物联网平台(右侧)。
让我们更详细地审查每一层。
前端应用程序
此层负责数据输入,可以是来自 SAP、Salesforce 或 Siebel 的数据包,也可以是自定义应用程序。它还可以与物联网设备交互,收集数据并在区块链分类帐中注册。开发前端应用程序的现代架构包括以下层次:
好的,我知道每一层都有很多其他工具,而不仅仅是这里介绍的,但我只是用我更熟悉的那些。
这种前端架构允许我们将服务从单一界面中分离出来。通过这样做,我们可以将用户体验(UX)扩展到多个平台,而无需重建整个应用程序。
基于物联网的资产追踪
物联网在食品链中发挥着重要作用。物联网设备可以跟踪资产,有大量可用的模型可以做到这一点。有用于测量温度的传感器,位置可以使用 GPS、信标、SigFox、Wi-Fi、4G 和 Sub1Ghz 来确定。这些设备和网络可以被农场、工厂、运输公司、分销中心和零售店使用,覆盖食品链中的所有参与者。
食品链中的主要挑战是运输。许多食品需要特殊关照,温度是最重要的关注点之一。由于许多食品易腐,温度控制对于防止污染和损坏至关重要。
让我们看看如何利用物联网设备来缓解这一挑战。 粒子电子资产追踪器(如下图所示)可用于收集温度和环境数据,并识别 GPS 位置和蜂窝三角测量等信息:
此追踪器允许我们连接到 u-blox M8 GNSS GPS 接收器和 Adafruit LIS3DH 三轴加速度计。我们也可以连接 Grove 传感器。
让我们看看这种物联网解决方案的高层架构:
此图表向我们展示了解决方案的一些重要组件。让我们看看它们是什么:
-
消息队列遥测传输(MQTT):这是一种基于发布-订阅的消息传输协议,通过 TCP 工作。它专为需要小代码占用空间或网络带宽有限的远程连接设计。发布-订阅消息传输模式需要一个消息代理。
-
Node-RED:Node-RED 是一种用于在易于使用的流程编辑器中简单地连接硬件设备、API 和在线服务的编程工具。
-
IBM Cloud:这是一套面向企业的云计算服务。
-
Bosch IoT Rollouts: 这是 Bosch IoT Suite 中的一个云服务,可以让用户管理边缘设备、控制器和网关的软件更新的推出。
那么,这些组件如何组合在一起以帮助食品供应链中的各种流程?以下是:
-
Node-RED 控制面板仪表板使我们能够选择资产跟踪器,并检查位置、数据、设备状态和其他信息
-
资产跟踪设备可以通过蜂窝网络进行激活或更新
-
地理位置数据可以定期传输,并且可以在 Node-RED 中的仪表板上进行跟踪
-
资产跟踪设备查询温度数据,然后可能查询位置或速度数据
-
Node-RED 可以将温度、位置和速度数据写入 Hyperledger Fabric
-
Node-RED 仪表板查询 Hyperledger Fabric 以获取各种任务和信息,例如交易历史记录、日期和时间数据和地理传感器数据
API/SDK
SDK 或 API 是一个负责在区块链网络中建立连接的集成层。通常使用 Node.js 开发,并在调用智能合约中起着重要作用。今天,我们可以找到覆盖 Go 和 Java 的 API/SDK 文档,并且 Python 的文档正在制定中。
您可以参考此链接以获取有关如何使用 API/SDK 将您的应用程序与区块链网络集成的更多信息:hyperledger-fabric.readthedocs.io/en/release-1.3/fabric-sdks.html。
以下图示显示了一个与通过 API/SDK 与 Hyperledger Fabric 交互的应用程序集成:
Composer JavaScript SDK 源自 Node.js,允许开发人员将您的应用程序与他们的业务网络集成。
有两个 npm 模块:
-
composer-client:这个模块通常作为应用程序的本地依赖项安装。它提供了业务应用程序用来连接业务网络以访问资产和参与者并提交交易的 API。在生产中,这是需要作为应用程序的直接依赖项添加的唯一模块。 -
composer-admin:此模块通常作为管理应用程序的本地依赖项安装。此 API 允许创建和部署业务网络定义。
现在让我们继续到我们解决方案的最后一层。
Hyperledger Composer – 高级概览
Hyperledger Composer 是创建您的区块链网络的简单方法,与 Hyperledger Composer 架构站点提供的全栈工作解决方案集成在一起。
从高层次来看,Hyperledger Composer 由以下组件组成:
-
执行运行时
-
JavaScript SDK
-
命令行界面(CLI)
-
REST 服务器
-
LoopBack 连接器
-
游乐场 Web 用户界面
-
Yeoman 代码生成器
-
VS Code 和 Atom 编辑器插件
在本书范围之外详细审查这些内容将超出范围。您可以访问此链接简要探索这些组件:hyperledger.github.io/composer/latest/introduction/solution-architecture。
软件组件
现在我们将从架构师的角度查看我们解决方案的软件组件。这是一个熟悉所有组件并更好地了解它们如何集成的好方法。
首先,让我们探索一下最重要的组件之一:身份验证过程。
我们如何确保区块链的每个成员在我们的前端应用程序中具有正确的访问权限?在回答这个问题之后,我们将深入研究 Hyperledger Composer 的最重要的组件:建模语言和事务处理器函数。
Composer REST 服务器
要验证客户端,我们将需要设置一个 REST 服务器。在这个选项可用之后,客户端在被允许调用 REST API 之前应该被验证。
REST 服务器使用一个名为 PASSPORT 的开源软件,这是一个用于 Node.js 的身份验证中间件。它灵活且模块化,支持通过用户名和密码、Facebook、Twitter、Google 和轻量级目录访问协议(LDAP)等方式进行身份验证。在第七章中,创建您的区块链和物联网解决方案,我们将有关于此的更多细节。现在,让我们回顾一下这些组件将如何工作。
在下图中,我们可以看到使用 Composer REST 服务器的高级认证架构:
下图描述了以下组件:一个前端应用程序、一个 Composer REST 服务器、LDAP 和 Cloudant,一个 NoSQL 数据库。
如果您正在进行测试或需要快速创建概念验证,我强烈建议使用 Facebook、Google 或 Twitter 进行身份验证。这比其他方法更容易更快。
要使用先前的方法将 Composer REST 服务器用作自定义实现,我们需要进行一些自定义。执行以下步骤:
- 在
composer-rest-server安装中有一行需要在该行之前执行的:
apk del make gcc g++ python git
在使用此方法之前,请确保您有一个干净的环境,清理所有先前的安装。
- 要自定义我们的 composer REST 服务器 Dockerfile,在 RUN 语句中添加以下命令:
su -c "npm install -g passport-ldapauth" - composer && \
- 创建以下环境变量:
export COMPOSER_CARD=admin@interbancario
export COMPOSER_NAMESPACES=require
export COMPOSER_AUTHENTICATION=true
export COMPOSER_MULTIUSER=true
- 如果你检查 API 调用并收到
404,意味着你未登录:
export COMPOSER_PROVIDERS='{
"ldap": {
"provider": "ldap",
"authScheme": "ldap",
"module": "passport-ldapauth",
"authPath": "/auth/ldap",
"successRedirect": “<redirection URL. will be overwritten by the property 'json: true'>”,
"failureRedirect": "/?success=false",
"session": true,
"json": true,
"LdapAttributeForLogin": “< CHANGE TO LOGIN ATTRIBUTE >",
"LdapAttributeForUsername": "<CHANGE TO USERNAME ATTRIBUTE>",
"server": {
"url": “<URL DO LDAP>",
"bindDN": “<DISTINGUISHED USER NAME FOR A SEARCH>",
"bindCredentials": “<USER PASSWORD FOR A SEARCH>",
"searchBase": “<PATH WITH USERS LIST WILL BE STORED>",
"searchFilter": "(uid={{username}})"
}
}
}'
- 检查我们的钱包中是否有 API:
TestValideteLastProcess:A Transaction named TestValideteLastProcess
UpdateOpportunityStatus: A Transaction named UpdateOpportunityStatus
Wallet:Business network cards for the authenticated user
为了更好地理解过程认证,让我们探索这个执行流程:
每个composer-rest-server的 API 调用必须包含access_token,这是由身份验证带回的。有关更多信息,请参阅hyperledger.github.io/composer/v0.16/integrating/enabling-rest-authentication。
使用 curl 的一些例子包括:
curl -v http://localhost:3000/api/system/ping?access_token=xxxxx
这是另一个例子:
curl -v -H 'X-Access-Token: xxxxx' http://localhost:3000/api/system/ping
- 这是设置你的
composer-rest-server的最后一步:使用 Cloudant 创建一个名片。
创建具有以下属性的成员卡:
-
ID:
wallet-data/admin@system name -
密钥:
wallet-data/admin@system name -
值:
{"rev" : "5-1af3gs53gwh...."}
根据以下截图上传附件:
在第七章,创建您的区块链和物联网解决方案中,我们将部署此实现。
Hyperledger Composer 模型
有许多方法来识别区块链用例。让我们记住第三章中描述的一些重要指标,解释区块链技术并使用 Hyperledger 工作:
-
是否涉及业务网络?
-
如果有,是否有需要验证和审计的交易?
-
透明度和数据不可变性是否重要?
确定了这些问题的答案后,头脑风暴也是详细解决方案和确定最佳解决方案平台(如 IBM 食品安全)的良好方式,或者开始为用例创建自定义开发。
使用 Hyperledger Composer 建模语言可以很容易地定义将作为交易进行处理并存储在分类账上的资源的结构。
CTO 文件创建了具有三个主要元素的业务网络定义的域模型:
-
包含文件中所有资源声明的单个命名空间
-
包含资产、交易、参与者和事件的一组资源定义
-
可选的导入声明,导入来自其他命名空间的资源
在第七章,创建您的区块链和物联网解决方案中,我们创建了一个业务网络。让我们更详细地探讨我们在代码中使用的代码:
命名空间是资产、事件、参与者和交易的基本定义,如下所示:
// **
* Sample business network definition.
*/
namespace org.example.basic
资源和枚举类型的声明如下所示:
asset SampleAsset identified by assetId {
o String assetId
--> SampleParticipant owner
o Double value
}
participant SampleParticipant identified by participantId {
o String participantId
o String firstName
o String lastName
}
事务处理函数是通过使用业务网络连接 API 提交事务时由运行时自动调用的:
transaction SampleTransaction {
--> SampleAsset origin
--> SampleAsset target
o Double txTransferAmount
}
event SampleEvent {
--> SampleAsset origin
--> SampleAsset target
o Double txTransferAmount
}
有关 Hyperledger Composer 建模语言的更多信息,请访问以下链接:
-
hyperledger.github.io/composer/v0.16/reference/cto_language.html -
hyperledger.github.io/composer/v0.16/reference/js_scripts.html
Hyperledger Composer 访问控制语言
Hyperledger Composer 有一个访问控制文件(.acl),您可以使用它来编程业务访问控制和网络访问控制。业务访问控制适用于业务网络内的资源,而网络访问控制则是指对管理网络更改的控制。
这是一个授予网络访问控制的例子:
rule networkControlPermission {
description: "networkControl can access network commands"
participant: "org.acme.foodchain.auction.networkControl"
operation: READ, CREATE, UPDATE
resource: "org.hyperledger.composer.system.Network"
action: ALLOW
}
下面是另一个例子:
rule SampleConditionalRuleWithTransaction {
description: "Description of the ACL rule"
participant(m): "org.foodchain..SampleParticipant"
operation: ALL
resource(v): "org.example.SampleAsset"
transaction(tx): "org.example.SampleTransaction"
condition: (v.owner.getIdentifier() == m.getIdentifier())
action: ALLOW
}
您可以通过访问以下链接了解有关 Hyperledger Composer 访问控制语言的更多信息:hyperledger.github.io/composer/v0.16/reference/acl_language.html。
Hyperledger Composer 事务处理函数
Hyperledger Composer 业务网络定义由一组模型文件和一组脚本组成。脚本可以包含实现业务网络定义模型文件中定义的事务的事务处理函数。
下面是一个带有事务的脚本文件的示例:
Sample transaction processor function.
* @param {org.example.basic.SampleTransaction} tx The sample transaction instance.
* @transaction
*/
async function sampleExchange(tx) {
// Get the asset registry for the asset.
const assetRegistry = await getAssetRegistry('org.example.basic.SampleAsset');
//Ensure the balance is greather than the amount to be transfered
if(tx.origin.value > tx.txTransferAmount) {
//charge from receiver account
tx.origin.value = (tx.origin.value - tx.txTransferAmount);
//add to receiver account
tx.target.value = (tx.target.value + tx.txTransferAmount);
// Update the asset in the asset registry.
await assetRegistry.update(tx.origin);
await assetRegistry.update(tx.target);
// Emit an event for the modified asset.
let event = getFactory().newEvent('org.example.basic', 'SampleEvent');
event.origin = tx.origin;
event.target = tx.target;
event.txTransferAmount = tx.txTransferAmount;
emit(event);
}else{
throw Error(`You do not have enough balance for this transaction:
Balance US$: ${tx.origin.value}
Transfer Amount: ${tx.txTransferAmount}`);
}
}
正如我们所看到的,当使用 BusinessNetworkConnection API 提交事务时,事务处理函数会由运行时自动调用。文档注释内的装饰器用于为函数提供运行时处理所需的元数据,并且每种事务类型都有一个关联的注册表用于存储事务。
摘要
本章描述的架构涉及许多组件,实现可能看起来有点复杂。到目前为止,我们已经确定了物联网和区块链的组合可以缓解多个问题并转变现代食品链的运作方式。例如,这样的实现可以在成员之间带来透明度,使他们更有效地控制数据;增加他们的安全性;使流程自动化和动态化;移除中间人;并且整体上使链条变得不那么复杂。
我们还看到物联网作为设备和传感器的计算和网络功能的延伸工作,使它们能够以最少或没有人类输入的方式进行机器对机器的交互。这些技术组件带来了诸如前所未有的自动化、为供应提供成本削减、节能、增值服务和高效管理等优势。
区块链与物联网的整合会使传感器、条形码和二维码扫描事件以及基于射频识别(RFID)的资产等边缘设备之间的数据交换成为可能。连接传感器的资产将能够记录敏感信息,例如特定仓库的位置和温度,并且这些信息可以自动记录或更新在区块链上。
通过更好地理解架构以及构成其技术组件的要素,我们将能够充分实施用于现代食品链的物联网和区块链解决方案。
在下一章中,我们将看到如何使用物联网创建自己的区块链。
问题
Q. 物联网安全不足如何威胁区块链网络中的数据?
A. 有时,公司在使用物联网时并不关注安全性。也许因为这是一项新技术,他们并不认为会带来立即的风险。事实是,企业正在将不安全的设备引入其网络,然后未能及时更新软件。不应用安全补丁并非新现象,但是带有互联网连接的不安全物联网设备是一场灾难等待发生;想想黑客和分布式拒绝服务(DDoS)攻击。应为物联网设备制定强有力的安全计划,类似于互联网服务的安全计划。强大的设备识别和更新可以帮助减轻大多数问题。
Q. 区块链技术对于这种应用已经足够成熟了吗?
A. 如今,市面上有许多区块链平台供应商。家乐福、沃尔玛等已经是这些平台的成员。因此,这表明大公司已经在区块链平台上经营业务,而这样的平台适用于这类应用。
Q. 使用物联网和区块链实施解决方案有多复杂?
A. 本章描述的大多数技术都是开源的并被许多公司使用。这表明我们讨论的不是什么复杂的东西,而是大多数开发人员可以使用的东西。
Q. 有多复杂的方案能够覆盖整个食物链?
A. 是的,这并不是一项容易的任务。您可以通过验证用例来开始;一个好的用例是至关重要的。此外,检查是否涉及业务网络;记住,物联网也在追踪资产方面发挥着重要作用,并且您应该为资产追踪制定安全计划。
Q. 使用 Hyperledger Fabric 或 Composer 等开源工具是否需要担心?
A. 超级账本是 Linux 基金会的一部分,拥有 250 多家公司作为成员,包括金融、银行、供应链、制造和技术领域的领导者。例如,IBM、思科、美国运通、富士通、英特尔和摩根大通都在使用 Linux 基金会的技术。换句话说,只要在设备上采用标准的安全措施,这些工具就是安全的。
进一步阅读
-
有关 Hyperledger Composer 的更好描述可以在 Composer 网站上找到:
hyperledger.github.io/composer/v0.19/introduction/solution-architecture。 -
本章的主要焦点是 Hyperledger Composer。如果你想探索 Hyperledger Fabric 的架构,可以在这里找到更多信息:
hyperledger-fabric.readthedocs.io/en/release-1.3/arch-deep-dive.html。 -
Yeoman 是创建您的前端结构的开源框架。有关更多信息,请访问
yeoman.io/。 -
Passport 是用于 Node.js 的身份验证中间件。有关更多信息,请访问[www.passportjs.org/] (www.passportjs.org/)。
-
您可以通过访问以下链接了解有关 Hyperledger Composer 访问控制语言的更多信息:
hyperledger.github.io/composer/v0.16/reference/acl_language.html。 -
您可以通过以下链接获取有关 Hyperledger Composer 建模语言的更多信息:
-
有关 composer-rest-server 的信息可以在此找到:
hyperledger.github.io/composer/v0.16/integrating/enabling-rest-authentication。
第七章:创建您的区块链和 IoT 解决方案
在正确理解了上一章节中提出的项目目标后,现在是让解决方案开始运行的时候了。在本章中,我将引导你创建一个使用 Hyperledger Composer 的区块链网络。
在本章中,我们将涵盖以下主题:
-
创建区块链网络
-
使用 Hyperledger Composer 定义资产、参与者、交易和访问控制清单
-
将网络发布到 Hyperledger 环境
我们还将从第二章借用代码,即创建您的第一个 IoT 解决方案,以创建一个将监视货物运输并与区块链网络交互的设备。
技术要求
要访问完整的代码,您需要在您的计算机上安装 Hyperledger Fabric/Composer 环境,包括先决条件,以及能够开发 Node.js 应用程序的 IDE(推荐使用 Visual Studio Code)。
解决方案概述
在这里,我们将处理食品工厂到杂货店的产品移动中最重要的部分之一。
下图显示了应针对每个给定阶段实施的解决方案:
让我们详细看看前述的图表。我们将从四个参与者开始:
-
工厂: 这是食品安全解决方案的起点。它负责从农场收集原材料,并创建一个发送到仓库的货箱。此参与者被允许的操作是添加新的货箱和将货箱转移至运输者。
-
运输者: 这是负责在受控温度下从工厂到仓库,以及从仓库到杂货店进行运输的公司。运输者定义的操作包括向其控制的资产添加温度测量数据,以及将资产转移到仓库或杂货店。
-
杂货店: 这是一家向消费者出售食品盒的公司。杂货店是这一链条的终点,消费者可以从食品盒中获取信息。杂货店可以检查货物托盘和货箱数据。
-
消费者: 他们是食品盒的目标受众。消费者对跟踪货箱链条很感兴趣,因此有一个查看货箱信息的映射操作。
我们将使用每个参与者的名片创建一个Composer REST 服务器的实例,因此总共将拥有四个Composer REST 服务器实例。还有盒子和托盘。这些资产的定义如下:
-
食品盒:代表在工厂生产并在整个链条中处理的产品
-
托盘:代表一批箱子,这些箱子被组合在一起从仓库送到杂货店
让我们开始我们的区块链网络解决方案。
创建区块链网络
要开发区块链网络,首先需要使用 Yeoman 命令行创建一个业务网络项目,然后命名业务网络:
$ yo hyperledger-composer
Welcome to the Hyperledger Composer project generator
? Please select the type of project: Business Network
You can run this generator using: 'yo hyperledger-composer:businessnetwork'
Welcome to the business network generator
? Business network name: food-safety-b10407
? Description: Hands-on IoT solutions with Blockchain
? Author name: Maximiliano and Enio
? Author email: max.santos@gmail.com
? License: Apache-2.0
? Namespace: com.packtpublishing.businessnetwork.foodsafety
? Do you want to generate an empty template network? Yes: generate an empty template network
create package.json
create README.md
create models/com.packtpublishing.businessnetwork.cto
create permissions.acl
create .eslintrc.yml
Yeoman 生成器生成一个基本空结构的 Hyperledger Composer 业务网络的文件夹。
.cto文件包含业务网络的定义:资产、参与者、交易和查询,而.acl文件包含了资产和交易的访问控制列表。
在后续的部分中,我们将编写业务网络定义,所以打开 Visual Studio Code 并打开 Yeoman 创建的文件夹。
要开始开发区块链解决方案,请打开models/com.packtpublishing.businessnetwork.cto文件并开始编码。
概念和枚举
创建常见数据类型的组合,这些类型在资产、参与者和交易中是常见的,可以通过在 Hyperledger Composer 中创建更可读的结构来实现。这些结构是概念和枚举。
我们将在解决方案中使用以下结构:
// Tracking information when an asset arrives or leaves a location
enum LocationStatus {
o ARRIVED
o IN_TRANSIT
o LEFT
}
// Location Types
enum LocationType {
o FACTORY
o WAREHOUSE
o TRANSPORTER
o STORE
}
// A measurement sent by the transporter sensor
concept Measurement {
o DateTime date
o Double value
}
// Check if it's in the factory, warehouse
concept Location {
o DateTime date
o LocationType location
o String locationIdentifier
o LocationStatus status
}
接下来,我们将看看如何定义业务网络中的资产。
资产定义
在定义了区块链网络的一般结构后,让我们定义将在其中使用的资产。在我们的解决方案中,将有FoodBox和FoodBoxPallet资产。
以下代码定义了它们:
// Definition of a food box
asset FoodBox identified by foodBoxIdentifier {
o String foodBoxIdentifier
o Location[] assetTrackingInformation
o Measurement[] measureTrackingInformation
--> FoodSafetyParticipant owner
}
// Definition of a pallet that groups food boxes
asset FoodBoxPallet identified by foodBoxPalletIdentifier {
o String foodBoxPalletIdentifier
--> FoodBox foodBoxInPallet
o Location[] assetTrackingInformation
o Measurement[] measureTrackingInformation
--> FoodSafetyParticipant owner
}
参与者
参与者是与区块链网络交互的行为者。每个参与者定义都是业务网络中不同角色的权限在访问控制列表中的定义,如下所示:
abstract participant FoodSafetyParticipant identified by identifier {
o String identifier
o String name
}
participant FoodFactory extends FoodSafetyParticipant {
}
participant Warehouse extends FoodSafetyParticipant {
}
participant Transporter extends FoodSafetyParticipant {
}
participant Store extends FoodSafetyParticipant {
}
participant Consumer extends FoodSafetyParticipant {
}
部署和测试用于 Hyperledger 的业务网络
为了测试目的,我们将授予所有参与者对区块链网络的所有资源完全访问权限:
- 为了实现这一点,我们将在
permissions.acl文件中添加以下行(不删除任何现有规则):
rule Default {
description: "Allow all participants access to all resources"
participant: "ANY"
operation: ALL
resource: "com.packtpublishing.businessnetwork.foodsafety.**"
action: ALLOW
}
定义了这条规则后,我们将能够部署和测试账本,而无需任何其他额外的权限。
- 在定义了网络后,我们将生成一个业务网络归档(
.bna文件)并部署到 Hyperledger 环境中。在此之前,请确保您的环境已经正常运行。要创建.bna文件,请转到项目的根目录并运行以下命令:
$ composer archive create -t dir -n .
Creating Business Network Archive
Looking for package.json of Business Network Definition
Input directory: /hands-on-iot-solutions-with-blockchain/ch7/food-safety-b10407
Found:
Description: Hands-on IoT solutions with Blockchain
Name: food-safety-b10407
Identifier: food-safety-b10407@0.0.1
Written Business Network Definition Archive file to
Output file: food-safety-b10407@0.0.1.bna
Command succeeded
- 如果你尚未生成
PeerAdminCard,现在是时候这样做,并将其与在我们下载了fabric-dev servers的目录中使用createPeerAdminCard.sh脚本导入:
$ ~/fabric-dev-servers/createPeerAdminCard.sh
Development only script for Hyperledger Fabric control
Running 'createPeerAdminCard.sh'
FABRIC_VERSION is unset, assuming hlfv12
FABRIC_START_TIMEOUT is unset, assuming 15 (seconds)
Using composer-cli at v0.20.4
Successfully created business network card file to
Output file: /tmp/PeerAdmin@hlfv1.card
Command succeeded
Successfully imported business network card
Card file: /tmp/PeerAdmin@hlfv1.card
Card name: PeerAdmin@hlfv1
Command succeeded
The following Business Network Cards are available:
Connection Profile: hlfv1
┌─────────────────┬───────────┬──────────────────┐
│ Card Name │ UserId │ Business Network │
├─────────────────┼───────────┼──────────────────┤
│ PeerAdmin@hlfv1 │ PeerAdmin │ │
└─────────────────┴───────────┴──────────────────┘
Issue composer card list --card <Card Name> to get details a specific card
Command succeeded
Hyperledger Composer PeerAdmin card has been imported, host of fabric specified as 'localhost'
- 当你设置好一切后,将
.bna文件安装到环境中,并通过运行以下命令启动网络:
$ composer network install --card PeerAdmin@hlfv1 --archiveFile food-safety-b10407\@0.0.1.bna
√ Installing business network. This may take a minute...
Successfully installed business network food-safety-b10407, version 0.0.1
Command succeeded
$ composer network start --networkName food-safety-b10407 --networkVersion 0.0.1 --networkAdmin admin --networkAdminEnrollSecret adminpw --card PeerAdmin@hlfv1 --file networkadmin.card
Starting business network food-safety-b10407 at version 0.0.1
Processing these Network Admins:
userName: admin
√ Starting business network definition. This may take a minute...
Successfully created business network card:
Filename: networkadmin.card
Command succeeded
- 最后,导入启动过程生成的网络管理员卡,并 ping 网络以确保它在环境中运行:
$ composer card import --file networkadmin.card
Successfully imported business network card
Card file: networkadmin.card
Card name: admin@food-safety-b10407
Command succeeded
$ composer network ping --card admin@food-safety-b10407
The connection to the network was successfully tested: food-safety-b10407
Business network version: 0.0.1
Composer runtime version: 0.20.4
participant: org.hyperledger.composer.system.NetworkAdmin#admin
identity: org.hyperledger.composer.system.Identity#f48a787ac40102cc7753336f8b15dd20fa3765e7b9049b2aeda4dcc3816d30c1
Command succeeded
在这一点上,我们已经创建了我们网络的第一个版本;生成了用于部署的包(.bna文件);创建了PeerAdminCard;将网络安装到 Hyperledger Fabric 环境;生成了负责管理区块链网络的NetworkAdminCard;并启动了网络。
使用管理员卡,我们将发送ping命令以确保网络已经启动并正常运行。现在,让我们改进我们的网络。
通过区块链中交易操作资产
交易是在 Hyperledger Composer 定义的业务网络中执行的原子操作,运行在 Hyperledger Fabric 环境和定义的业务网络的范围内。
在这里演示的用例中,我们创建的交易将会使用 IoT 设备提供的信息来更新托盘和嵌套的食品箱。
它由两个结构组成。第一个是交易的定义,并在业务网络定义模型(.cto文件)中创建:
transaction updateTransportationData {
--> FoodBoxPallet pallet
o Location locationInformation
o Measurement measurementInformation
}
下一个结构是实现之前定义的交易的函数,并在 JavaScript ES5 兼容的脚本中创建(一个.js文件):
/**
* Update pallets and boxes with measurements function.
* @param {com.packtpublishing.businessnetwork.foodsafety.UpdateTransportationData} tx Update pallets and boxes with measurements.
* @transaction
*/
async function updateTransportationData(tx) {
// Get transaction parametes
let newValue = tx.asset;
let location = tx.locationInformation;
let measurement = tx.measurementInformation;
// Update Pallet data with measurements
if( !newValue.assetTrackingInformation || newValue.assetTrackingInformation == undefined)
newValue.assetTrackingInformation = [];
if ( !newValue.measureTrackingInformation || newValue.measureTrackingInformation == undefined)
newValue.measureTrackingInformation = [];
newValue.assetTrackingInformation.push(location);
newValue.measureTrackingInformation.push(measurement);
// Update Boxes data with measurements
let foodBox = newValue.foodBoxInPallet;
if( !foodBox.assetTrackingInformation || foodBox.assetTrackingInformation == undefined)
foodBox.assetTrackingInformation = [];
if ( ! foodBox.measureTrackingInformation || foodBox.measureTrackingInformation == undefined)
foodBox.measureTrackingInformation = [];
foodBox.assetTrackingInformation.push(location);
foodBox.measureTrackingInformation.push(measurement);
// Get the asset registry for both assets.
let assetRegistryFoodBoxPallet = await getAssetRegistry('com.packtpublishing.businessnetwork.foodsafety.FoodBoxPallet');
let assetRegistryFoodBox = await getAssetRegistry('com.packtpublishing.businessnetwork.foodsafety.FoodBox');
// Update the assets in the asset registry.
await assetRegistryFoodBoxPallet.update(newValue);
await assetRegistryFoodBox.update(foodBox);
}
生成并导出参与者名片
为了正确使用网络,我们将为每一个类(工厂,仓库,运输商,商店,和消费者)创建一个参与者,生成他们各自的名片,并将它们导入 Composer CLI 钱包:
- 首先,我们将创建参与者:
$ composer participant add -c admin@food-safety-b10407 -d '{"$class":"com.packtpublishing.businessnetwork.foodsafety.Consumer","identifier":"5","name":"Consumer"}'
Participant was added to participant registry.
Command succeeded
$ composer participant add -c admin@food-safety-b10407 -d '{"$class":"com.packtpublishing.businessnetwork.foodsafety.Store","identifier":"4","name":"Store"}'
Participant was added to participant registry.
Command succeeded
$ composer participant add -c admin@food-safety-b10407 -d '{"$class":"com.packtpublishing.businessnetwork.foodsafety.Transporter","identifier":"2","name":"Transporter"}'
Participant was added to participant registry.
Command succeeded
$ composer participant add -c admin@food-safety-b10407 -d '{"$class":"com.packtpublishing.businessnetwork.foodsafety.Warehouse","identifier":"3","name":"Warehouse"}'
Participant was added to participant registry.
Command succeeded
$ composer participant add -c admin@food-safety-b10407 -d '{"$class":"com.packtpublishing.businessnetwork.foodsafety.FoodFactory","identifier":"1","name":"Factory"}'
Participant was added to participant registry.
Command succeeded
- 然后,我们将发行一个身份并使用以下命令导入它们各自的名片:
composer identity issue -c admin@food-safety-b10407 -f <name of the output file for the card> -u <participant name> -a <participant class# Participant id>
- 对每个参与者重复执行此命令:
Transporter 1、Store 1、Warehouse 1和Factory 1。
$ composer identity issue -c admin@food-safety-b10407 -f consumer.card -u "Consumer" -a "resource:com.packtpublishing.businessnetwork.foodsafety.Consumer#1"
Issue identity and create Network Card for: Consumer
√ Issuing identity. This may take a few seconds...
Successfully created business network card file to
Output file: consumer.card Command succeeded
- 为每个参与者/生成的名片将每张名片导入 Composer CLI 钱包,并检查所有名片是否已成功导入:
$ composer card import -f consumer.card
Successfully imported business network card
Card file: consumer.card
Card name: Consumer 1@food-safety-b10407
Command succeeded
$ composer card list
The following Business Network Cards are available:
Connection Profile: hlfv1
┌──────────────────────────────────┬───────────────┬────────────────────┐
│ Card Name │ UserId │ Business Network │
├──────────────────────────────────┼───────────────┼────────────────────┤
│ Factory 1@food-safety-b10407 │ Factory │ food-safety-b10407 │
├──────────────────────────────────┼───────────────┼────────────────────┤
│ Warehouse 1@food-safety-b10407 │ Warehouse │ food-safety-b10407 │
├──────────────────────────────────┼───────────────┼────────────────────┤
│ Store 1@food-safety-b10407 │ Store │ food-safety-b10407 │
├──────────────────────────────────┼───────────────┼────────────────────┤
│ Consumer 1@food-safety-b10407 │ Consumer │ food-safety-b10407 │
├──────────────────────────────────┼───────────────┼────────────────────┤
│ Transporter 1@food-safety-b10407 │ Transporter │ food-safety-b10407 │
├──────────────────────────────────┼───────────────┼────────────────────┤
│ admin@food-safety-b10407 │ admin │ food-safety-b10407 │
├──────────────────────────────────┼───────────────┼────────────────────┤
│ PeerAdmin@hlfv1 │ PeerAdmin │ │
└──────────────────────────────────┴───────────────┴────────────────────┘
Issue composer card list --card <Card Name> to get details a specific card
Command succeeded
定义访问控制列表(ACLs)
为了强制执行网络上的权限,我们将为参与者对资产定义一些访问控制规则,具体规则如下:
- 只有工厂可以创建
FoodBoxes:
rule FoodBoxFactoryCreation {
description: "Factories can create FoodBoxes"
participant: "com.packtpublishing.businessnetwork.foodsafety.FoodFactory"
operation: CREATE
resource: "com.packtpublishing.businessnetwork.foodsafety.FoodBox"
action: ALLOW
}
- 由于食品工厂也能够看到他们的
FoodBoxes并将它们转移到运输商,我们可以使用条件规则来定义这些限制:
rule FoodBoxFactoryUpdateAndRead {
description: "Factories can update and read owned FoodBoxes"
participant(p): "com.packtpublishing.businessnetwork.foodsafety.FoodFactory"
operation: UPDATE, READ
resource(b): "com.packtpublishing.businessnetwork.foodsafety.FoodBox"
condition: (p == b.owner)
action: ALLOW
}
- 下一个规则涉及
运输商。他们可以读取和更新他们自己的FoodBoxes。我们将对FoodBoxPallets做同样的操作:
rule FoodBoxTransportersUpdateAndRead {
description: "Transporters can update and read owned FoodBoxes"
participant(p): "com.packtpublishing.businessnetwork.foodsafety.Transporter"
operation: UPDATE, READ
resource(b): "com.packtpublishing.businessnetwork.foodsafety.FoodBox"
condition: (p == b.owner )
action: ALLOW
}
rule FoodBoxPalletTransportersUpdateAndRead {
description: "ransporters can update and read owned FoodBoxes"
participant(p): "com.packtpublishing.businessnetwork.foodsafety.Transporter"
operation: UPDATE, READ
resource(b): "com.packtpublishing.businessnetwork.foodsafety.FoodBoxPallet"
condition: (p == b.owner )
action: ALLOW
}
- 仓库也可以读取和更新他们的
FoodBoxes,以及创建,更新和读取FoodBoxPallets:
rule FoodBoxPalletWarehouseCreate {
description: "Warehouses can create FoodBoxPallets"
participant: "com.packtpublishing.businessnetwork.foodsafety.Warehouse"
operation: CREATE
resource: "com.packtpublishing.businessnetwork.foodsafety.FoodBoxPallet"
action: ALLOW
}
rule FoodBoxWarehouseUpdateAndRead {
description: "Warehouses can update and read owned FoodBoxes"
participant(p): "com.packtpublishing.businessnetwork.foodsafety.Warehouse"
operation: UPDATE, READ
resource(b): "com.packtpublishing.businessnetwork.foodsafety.FoodBox"
condition: (p == b.owner )
action: ALLOW
}
rule FoodBoxPalletWarehouseUpdateAndRead {
description: "Warehouses can update and read owned FoodBoxes"
participant(p): "com.packtpublishing.businessnetwork.foodsafety.Warehouse"
operation: UPDATE, READ
resource(b): "com.packtpublishing.businessnetwork.foodsafety.FoodBoxPallet"
condition: (p == b.owner)
action: ALLOW
}
- 最后,商店可以读取他们拥有的
FoodBoxes,而消费者可以读取所有的FoodBoxes:
// Store Rules
rule StoreCanReadFoodBoxes {
description: "Stores can update and read owned FoodBoxes"
participant(p): "com.packtpublishing.businessnetwork.foodsafety.Store"
operation: READ
resource(b): "com.packtpublishing.businessnetwork.foodsafety.FoodBoxPallet"
condition: (p == b.owner )
action: ALLOW
}
// Consumer Rules
rule ConsumersCanReadFoodBoxes {
description: "Factories can update and read owned FoodBoxes"
participant: "com.packtpublishing.businessnetwork.foodsafety.Consumer"
operation: READ
resource: "com.packtpublishing.businessnetwork.foodsafety.FoodBox"
action: ALLOW
}
应用了这些规则后,网络可以被测试了。
将业务网络升级为新版本
升级部署的业务网络只需要四个步骤:
- 打开
package.json文件并更新应用程序的版本号。在我们的情况下,它将更新为0.0.2,看起来像这样:
{
"engines": {
"composer": "⁰.20.4"
},
"name": "food-safety-b10407",
"version": "0.0.2",
...
- 通过运行
composer archive create -t dir -n .命令创建一个新的 BNA 文件:
$ composer archive create -t dir -n .
Creating Business Network Archive
Looking for package.json of Business Network Definition
Input directory: /projects/hands-on-iot-solutions-with-blockchain/ch7/food-safety-b10407
Found:
Description: Hands-on IoT solutions with Blockchain
Name: food-safety-b10407
Identifier: food-safety-b10407@0.0.2
Written Business Network Definition Archive file to
Output file: food-safety-b10407@0.0.2.bna
Command succeeded
- 在 Hyperledger 环境中安装新的归档文件:
$ composer network install --card PeerAdmin@hlfv1 --archiveFile food-safety-b10407\@0.0.2.bna
√ Installing business network. This may take a minute...
Successfully installed business network food-safety-b10407, version 0.0.2
Command succeeded
- 最后,将网络版本
upgrade到新版本:
$ composer network upgrade --card PeerAdmin@hlfv1 --networkName food-safety-b10407 --networkVersion 0.0.2
Upgrading business network food-safety-b10407 to version 0.0.2
√ Upgrading business network definition. This may take a minute...
Command succeeded
如果所有命令都成功运行,那么业务网络现在将在新版本上运行,包括在前面的章节中创建的交易和 ACLs。
为每个参与者设置 Composer REST 服务器
作为安装 Hyperledger Composer 开发环境的先决条件的一部分,您还将安装了 Composer REST 服务器。
这个组件是基于 Loopback 框架(loopback.io)的 API 服务器,包括一个loopback-connector-composer用于连接到 Hyperledger Composer 环境,以及一个动态收集资产、参与者和交易模型的脚本。
启动 Composer REST 服务器的最简单方法是运行cli命令并正确填写启动问卷。为了我们的方便,我们将使用以下命令运行它:
composer-rest-server -c "<business card name>" -n never -u true -w true -p <port defined for the participant server>
为每个参与者打开一个终端窗口,以启动专用的 Composer REST 服务器:
composer-rest-server -c "Factory@food-safety-b10407" -n never -u true -w true -p 3000
composer-rest-server -c "Warehouse@food-safety-b10407" -n never -u true -w true -p 3001
composer-rest-server -c "Store@food-safety-b10407" -n never -u true -w true -p 3002
composer-rest-server -c "Consumer@food-safety-b10407" -n never -u true -w true -p 3003
composer-rest-server -c "Transporter@food-safety-b10407" -n never -u true -w true -p 3004
每个运行实例都与单个用户相关联,这意味着通过监听端口3003的 Composer REST 服务器调用的所有操作都与具有标识符 5**的Consumer相关。例如,如果创建了一个新的Consumer参与者(假设 ID 为 6),那么必须向参与者发放新的名片,并使用新的名片启动另一个 Composer REST 服务器实例。
在大多数情况下,一个商业名片就足以满足整个组织的需求。其他发放名片的规则可以由治理定义,例如每个分支/子公司一个名片,或者每个用户必须有自己的名片。
此时,您的计算机上应该有五个 Composer REST 服务器实例正在运行,每个服务器都可以通过浏览器访问以下地址:http://localhost:<port>。
创建解决方案的物联网部分
在定义了整个区块链网络并使一切正常运行之后,我们现在将设置和开发将用于更新盒子和托盘测量值的设备。
为了完成这一点,我们将使用与第二章相同的方法创建一个新的设备,创建您的第一个物联网解决方案,并创建一个应用程序,该应用程序接收测量事件并使用 Composer REST 服务器提供的 API 更新区块链账本。
硬件设置
为了组装这个监控设备,我们将应用一些可能与生产环境相关的假设:
-
运输车辆有可用的 Wi-Fi 连接,使设备可以连接到互联网
-
监测设备时间与应用程序时间同步,包括时区
-
所有的箱子都是同时运输,使用相同的车辆,因此对于托盘上的所有箱子都适用相同的条件和测量标准。
在生产级应用中,必须使用诸如缓存未发布的事件和使用不同的网络提供商(Sigfox,LoRAWan,移动连接等)等技术来处理这些限制/假设,并且实际时间必须与设备位置同步。
此项目中使用的零件如下所示:
此图像是使用 Fritzing 创建的,并在 CC BY-SA 3.0 下许可;请参阅 creativecommons.org/licenses/by…
组件的描述如下表所示。鉴于它们是第二章创建您的第一个物联网解决方案中所使用的子集,您应该对它们很熟悉。
| 数量 | 组件 |
|---|---|
| 1 | 英特尔 Edison 模块 |
| 1 | 英特尔 Edison Arduino 扩展板 |
| 1 | Grove 基本盾牌 v2 |
| 1 | Grove 温度传感器 v1.2 |
| 1 | Grove 通用 4 针线缆 |
在这些假设的前提下,用于此应用程序的设备如下图所示连接。在这里,我们已经将 Grove 温度传感器连接到基本盾牌上的A3连接插孔。
此图像是使用 Fritzing 创建的,并在 CC BY-SA 3.0 下许可;请参阅 creativecommons.org/licenses/by…
这样就完成了监测食品箱运输的设备。
固件开发
下面的代码是从第二章创建您的第一个物联网解决方案中借用的,因为它具有相同的硬件特性和相同的目标。
唯一的修改是在已发布的 JSON 中:在从工厂运输到仓库时,我们必须移除soilMoisture属性,并在从仓库运输到商店时添加箱子 ID,并在添加托盘 ID 时进行运输。
它获取 Grove 传感器的温度并将其发布到 Watson IoT 平台:
var iotf = require("ibmiotf");
var mraa = require('mraa');
var config = require("./device.json");
var deviceClient = new iotf.IotfDevice(config);
var temperatureSensor = new mraa.Aio(3);
var RESISTOR = 100000;
var THERMISTOR = 4250;
var getTemperature = function() {
var sensorReading = temperatureSensor.read();
var R = 1023 / sensorReading - 1;
R = RESISTOR * R;
var temperature = 1 / (Math.log(R/RESISTOR)/THERMISTOR+1/298.15)-273.15;
return temperature;
};
deviceClient.connect();
deviceClient.on('connect', function(){
console.log("connected");
setInterval(function function_name () {
// When transporting from Factory to Warehouse
deviceClient.publish('status','json','{ "foodBoxId":"1", "temperature":+ getTemperature()}', 2);
// When transporting from Warehouse to Store
// deviceClient.publish('status','json','{ "palletId":"1", "temperature":+
// getTemperature()}', 2);
},300000);
});
应用程序开发
由于我们在本地运行 Hyperledger 环境,因此在此开发的应用程序必须在与 Hyperledger 相同的网络上运行。鉴于我们不是在 IBM Cloud/Bluemix 上运行它,配置将存储在 JSON 文件中,在与应用程序的主.js文件相同的目录中运行。
配置 JSON 文件的内容结构列在这里,并且必须更新为在第二章创建您的第一个物联网解决方案中定义的详细信息。
{
"org": "<your IoT organization id>",
"id": "sample-app",
"auth-key": "<application authentication key>",
"auth-token": "<application authentication token>"
}
应用程序代码接收设备发布的所有事件,并使用收集的温度更新托盘中的FoodBoxes:
// Composer Rest Server definitions
var request = require('request');
var UPDATE_BOX_URL = "http://<composer rest server url>:3004/api/UpdateFoodBoxTransportationData"
var UPDATE_PALLET_URL = "http://<composer rest server url>:3004/api/UpdateTransportationData"
// Watson IoT definitions
var Client = require("ibmiotf");
var appClientConfig = require("./application.json");
var appClient = new Client.IotfApplication(appClientConfig);
appClient.connect();]
appClient.on("connect", function () {
appClient.subscribeToDeviceEvents();
});
appClient.on("deviceEvent", function (deviceType, deviceId, eventType, format, payload) {
// update food box
// updateFoodBox(payload.temperature);
// update pallet
// updatePallet(payload.temperature);
});
以下代码通过 Composer REST 服务器调用区块链网络中定义的交易:
var updateFoodBox = function (temperature) {
var options = {
uri: UPDATE_BOX_URL,
method: 'POST',
json: {
"$class": "com.packtpublishing.businessnetwork.foodsafety.UpdateFoodBoxTransportationData",
"asset": "resource:com.packtpublishing.businessnetwork.foodsafety.FoodBox#<YOUR FOODBOX ID>",
"locationInformation": {
"$class": "com.packtpublishing.businessnetwork.foodsafety.Location",
"date": "2018-12-24T15:08:27.912Z",
"location": "<LOCATION TYPE>",
"locationIdentifier": "<LOCATION ID>",
"status": "<LOCATION STATUS>"
},
"measurementInformation": {
"$class": "com.packtpublishing.businessnetwork.foodsafety.Measurement",
"date": "2018-12-24T15:08:27.912Z",
"value": 0
}
}
};
}
var updatePallet = function (temperature) {
var options = {
uri: UPDATE_BOX_URL,
method: 'POST',
json: {
"$class": "com.packtpublishing.businessnetwork.foodsafety.UpdateTransportationData",
"asset": "resource:com.packtpublishing.businessnetwork.foodsafety.FoodBoxPallet#<YOUR PALLET ID>",
"locationInformation": {
"$class": "com.packtpublishing.businessnetwork.foodsafety.Location",
"date": "2018-12-24T15:09:02.944Z",
"location": "<LOCATION TYPE>",
"locationIdentifier": "<LOCATION ID>",
"status": "<STATUS>"
},
"measurementInformation": {
"$class": "com.packtpublishing.businessnetwork.foodsafety.Measurement",
"date": "2018-12-24T15:09:02.944Z",
"value": 0
}
}
};
}
端到端测试
为了测试目的,我们将使用 Hyperledger Composer Playground 进行大部分操作,除了运输者更新。所以,在这一点上,您可以停止之前启动的所有 Composer REST 服务器,除了在传输者参与者上启动的服务器(监听端口 3004)。
如果您在开发环境设置期间安装了 Hyperledger Composer Playground,则您只需运行composer-playground命令,或者使用npm进行安装(npm install -g composer-playground)。
您的默认浏览器将打开 Composer-Playground Web 应用程序,如下截图所示:
Composer playground 登陆页面
你可以看到之前创建的相同参与者。
创建一个食品箱
根据我们授予的权限,工厂可以创建FoodBoxes。让我们来看看如何:
-
找到 Factory 1 @food-safety-b10407 名片,选择 Connect now 选项。然后,点击屏幕左上角的测试。
-
在左侧面板中,选择资产 -> 食品箱,并在右上角点击 + 创建新资产:
- 用以下内容填写 JSON 并使用“创建新建”按钮创建资产:
{
"$class": "com.packtpublishing.businessnetwork.foodsafety.FoodBox",
"foodBoxIdentifier": "2015",
"assetTrackingInformation": [],
"measureTrackingInformation": [],
"owner": "resource:com.packtpublishing.businessnetwork.foodsafety.FoodFactory#1"
}
将资产转移给运输者
使用 Hyperledger Composer Playground 转移食品安全网络的资产,请按照以下步骤进行:
-
在应用程序的右上角,选择“我的业务网络”选项,并作为运输者连接。
-
如果您选择测试,资产 → 食品箱,您将看到没有可用的资产:
- 返回到“工厂”身份,选择资产数据右侧的编辑按钮,并使用以下数据更新 JSON 文件:
{
"$class": "com.packtpublishing.businessnetwork.foodsafety.FoodBox",
"foodBoxIdentifier": "1",
"assetTrackingInformation": [],
"measureTrackingInformation": [],
"owner": "resource:com.packtpublishing.businessnetwork.foodsafety.Transporter#2"
}
- 保存资产;它将从工厂视图中消失。当您返回到运输者视图时,您会发现运输者现在可以看到该资产。
在运输过程中测量温度
在这一点上,我们将模拟运输过程中的温度测量。
我们在 IoT 应用程序代码中创建了以下注释代码,因为我们在不同时间处理传输收集的数据。
首先是当一个FoodBox从工厂运到仓库时,这是由updateFoodBox函数实现的,而updatePallet函数旨在处理从仓库到商店的运输:
appClient.on("deviceEvent", function (deviceType, deviceId, eventType, format, payload) {
// update food box
// updateFoodBox(payload.temperature);
// update pallet
// updatePallet(payload.temperature);
});
此时,我们正在处理从 工厂 到 仓库 的运输,因此取消注释代码的第 19 行—updateFoodBox(payload.temperature);— 然后更新第 30、34、35 和 36 行,提供正确的数据值。
确保运输车的 Composer REST 服务器正在运行,并且设备代码的第 2 和第 3 行中定义的 URL 指向正确的 Composer REST 服务器主机。
启动设备应用程序。
将资产转移到仓库
当资产转移到运输车时,情况也是如此。转到运输车的资产视图,编辑 JSON 文件,并使用相应的值更改所有者:
"owner": "resource:com.packtpublishing.businessnetwork.foodsafety.Warehouse#3"
创建一个托盘并将箱子添加到其中
要创建托盘,我们需要按照与 FoodBox 相同的过程进行操作:
-
在左侧面板中,选择 Assets → FoodBoxPallet,然后在右上角点击 + 创建新资产。
-
然后,使用以下数据填充 JSON。确保您在
foodBoxInPallet字段中使用相同的 FoodBox ID,而在owner字段中使用 Warehouse ID (3):
{
"$class": "org.hyperledger.composer.system.AddAsset",
"resources": [
{
"$class": "com.packtpublishing.businessnetwork.foodsafety.FoodBoxPallet",
"foodBoxPalletIdentifier": "3485",
"foodBoxInPallet": "resource:com.packtpublishing.businessnetwork.foodsafety.FoodBox#2473",
"assetTrackingInformation": [],
"measureTrackingInformation": [],
"owner": "resource:com.packtpublishing.businessnetwork.foodsafety.Warehouse#3"
}
],
"targetRegistry": "resource:org.hyperledger.composer.system.AssetRegistry#com.packtpublishing.businessnetwork.foodsafety.FoodBoxPallet",
"transactionId": "0dfe3b672a78dd1d6728acd763d125f813ed0ca74450a2596b9cf79f47f054ad",
"timestamp": "2018-12-24T14:43:34.217Z"
}
- 创建托盘后,像以前一样将托盘和箱子转移到运输车上。 JSON 的所有者值应如下所示:
"owner": "resource:com.packtpublishing.businessnetwork.foodsafety.Transporter#2"
在运输托盘时测量温度
这与 FoodBox 运输的测量规则相同,但您必须注释设备代码的第 19 行并取消注释第 20 行,以及更新第 53、57、58 和 59 行的正确值以适用于您的托盘。
在运输结束时,通过使用托盘的 owner 和以下行将资产转移到仓库中的箱子:
"owner": "resource:com.packtpublishing.businessnetwork.foodsafety.Store#4"
跟踪食品盒
要跟踪食品盒作为消费者,我们将通过 composer-playground 使用 Hyperledger Composer Historian。
要访问已应用于资产的操作历史记录,请使用 Consumer business card 连接到 Hyperledger 环境,并从游乐场的左侧面板中选择 All Transactions 选项。
我们将能够查看对资产执行的所有交易,从其创建到托盘及其内部箱子到达仓库为止:
Composer 游乐场 - 历史学家
我们还可以通过单击查看记录链接来查看交易详细信息,如下所示:
摘要
在本章中,我们学习了如何使用 Hyperledger Composer 和 Watson IoT 平台创建业务网络。
在开发解决方案的过程中,我们能够使用 Yeoman 创建 Hyperledger Composer 项目;定义共享数据结构;创建资产、参与者交易和访问控制列表;以及创建网络的第一个版本并将其升级为新版本。
我们还能够创建一个设备,负责从工厂到仓库的食品箱的假设运输中读取温度,并且后来,从仓库到商店,将该信息添加到区块链网络的共享账本中的食品箱资产中。
食品箱的消费者还能够追踪与该箱相关的信息,从生产链的最初开始。
尽管 Hyperledger Composer 和 Watson IoT 开发相当简单,但我们所创建的解决方案解决了食品链安全方面的重大问题。
以下章节将向您介绍作者对实际项目中所学到的教训、实践和模式的观点,以及在当前工业 4.0 情景下,物联网和区块链如何成为创造业务模型和解决新挑战的必要工具。
第八章:物联网、区块链和工业 4.0
物联网和区块链并不是推动新经济和制造革命演进的唯一技术集合。工业 4.0 是一个概念,发生在一个新方法、新技术和空前的计算能力的时代,任何拥有互联网接入的人都可以使用。
在本章中,我们将探讨物联网(IoT)、区块链和云计算等关键技术的作用,重点关注这些因素如何推动工业 4.0 的演进。
本章将涵盖以下主题:
-
云计算在新经济模型中的作用
-
物联网如何帮助创新产业
-
区块链作为工业 4.0 的业务平台
工业 4.0
工业 4.0,又称为经济 4.0,是一个新的制造模式的名称,其中连接性、数据收集和处理广泛应用于整个制造链中。
智能工厂与自动化工厂的区别在于,智能工厂不仅仅是自动化的;它们是连接的、可监控的、协作的。
重要的是要知道,工业 4.0 不仅与制造业有关;它可以被理解为设计新的制造模式,旨在创造更个性化和引人入胜的体验。 新模式强调拥有数据是成功的关键因素,并且在当前业务模型的交叉点上正在创建新的商业模型。 云计算、物联网、认知计算和区块链是推动这一新模式的一些技术。
云计算作为创新平台
云计算为创建新业务模型提供了机会,同时提供了重新设计现有业务模型的工具。 云计算为高度技术化和创新化的服务生态系统提供了简单、自助、灵活和低成本的基础设施。 与其说是处理能力,不如说云计算的作用是成为一个创新平台。 让我们深入了解云计算的世界,以了解其与工业 4.0 发展的关系和重要性。
云计算模型
云计算是共享计算资源的概念,包括内存、计算、网络和存储能力,用于运行应用程序。 将计算模型定义为云模型的特征包括自助式资源分配、软件定义的资源和按需付费的货币化。 这些通常以商业化的三种模型呈现:基础设施即服务(IaaS)、平台即服务(PaaS)和软件即服务(SaaS)。 此外,它们可以以公共和私有的部署模式交付:
查看前面图表中的交付模型,可以了解服务消费者应关注的能力有哪些:
-
在 IaaS 模型中,正如其名称所示,云服务提供商负责维护网络、存储、服务器和虚拟机组件。包括其许可证、备份、更新和升级在内的每一层都是服务承包方的责任。
-
PaaS 提供了另外三个层次:操作系统、中间件和运行时能力,为服务使用者提供更多的基础设施和软件许可证管理抽象;他们只需处理应用程序代码和二进制文件以及其使用的数据。
-
SaaS 将计算提升到更高的抽象级别:服务使用者只需使用订阅的解决方案。
IBM Cloud Public(也称为 Bluemix)提供了此处描述的所有功能。通过其控制台提供 IaaS、PaaS 和 SaaS 解决方案。你可以实例化物理或虚拟机器和应用程序运行时,并订阅服务目录中提供的任何服务,包括 IBM Watson IoT 和 IBM Blockchain 平台。
当这些模型部署在公共网络(如互联网)的多租户环境中时,称为公共云,即一个人和一家公司共享相同的资源的地方。当公司或个人在私有或公共网络的单租户环境中使用其中任何模型时,称为私有云。
云计算对工业 4.0 的重要性
在云计算模型出现之前,IT 部门需要经历漫长、昂贵和困难的过程才能使解决方案对其客户可用。他们必须购买服务器;等待交付;在数据中心中为其提供空间;准备网络和虚拟化;安装操作系统、中间件、数据库和运行时;然后开发应用程序并将其部署到生产环境中。
当云计算在上述场景中发生时,提供相同的计算能力并开始开发应用程序只需几分钟。你只需要支付所使用资源的费用。
在开发创新解决方案时,最小可行产品(MVP)可能不会产生预期结果,导致基础设施、平台软件和附加服务不断变化。如果创建的 MVP 不符合目标用户的需求呢?在第一种情况下,你已经支付了所需的所有资源,因此即使关闭解决方案,你已经花费了资本支出。然而,在第二种情况下(云),你只支付了服务费用,所以只是运营支出。如果解决方案非常合适,人们使用得很多呢?在第一种情况下,你必须遵循更简单(但仍然困难)的路径来提供更多资源,而在云计算中,你可以在需要时随时扩展解决方案资源,而不是一直都需要。
云计算还提供了使用物联网、认知计算、区块链和其他在互联网上创建和提供的最佳服务和技术来测试新服务和创建新应用程序的能力。这些服务是创建新解决方案和商业模式的强大工具,为客户提供不同的体验,无论使用同一服务的人数是 1、10、100 还是 100 万人。
物联网
正如之前所述,数据是工业 4.0 成功的关键因素。收集和分析的数据越多,预测和建议就越有说服力。
物联网不仅是一种自动化框架技术,还是从连接的设备中收集大量数据的绝佳方式。通过结合不同的数据源(机器和机器人传感器、安全摄像头、心率监测器、环境和气象数据),可以定义和分析领域,了解业务背景的当前实际情况,并对其进行更加理性的分析。还可以洞察如何变得更加高效、更加可预测和更加灵活,因为可以实时处理数据的收集,如下图所示:
处理结果也可以成为改变机器和机器人当前运行的动作的触发器,甚至可以在继续处理之前修复正在创建的产品中的缺陷,以执行自我修复任务。
区块链——简化业务链
随着商业模式的发展,它们往往会采用更精益的方法。在这种情况下,精益产业意味着只专注于对产品的目标客户有价值的事物。任何不为产品提供价值的程序、产品的一部分或创建产品的过程都被视为无用的,必须予以删除或更改,以便为端到端解决方案增加更多的价值。以同样的方式,智能商业模式往往只包含为业务模型增加价值和知识的步骤,这意味着在这个领域外包仍然是一件大事。如果不知道如何将端到端服务链整合到业务中,要想变得精益并不容易和廉价。
当外包或分散业务任务对模型至关重要时,区块链会发挥作用,通过提供分散任务的机会来实现。让我们看一下下面的传统汽车销售流程图:
每当客户购买一辆汽车时,经销商的账簿中都会为该汽车创建一个新条目,并向汽车制造商下订单,后者会在其账簿中创建另一个条目,并向其供应商订购零件,这也会在他们的账簿中创建订单条目。区块链通过为过程的所有利益相关者使用共享账簿来简化该过程:
该过程本身现在具有审计性并且最终产品可以被端到端地追踪,使新车主对产品的来源有所了解。
区块链实现了一个既精简又可审计的以产品为驱动的业务流程。
摘要
在这一章中,您了解到了在工业 4.0 背景下关键技术如云计算、物联网和区块链的重要性。
云计算是一种提供低成本、可扩展和自助技术采用的计算模型,创建了一个适合创建创新业务模式的环境。
物联网不仅是一个自动化工具包,还可以被视为数据收集和创建数字化上下文的框架,类似于真实世界的上下文;它创造了一个数字化的现实环境,模拟了与真实世界相同的条件。
区块链通过简化去中心化流程实现了精益生产线,并帮助公司集中精力发挥自身优势,而不必在不为最终产品产生聚合价值的任务上花费时间和金钱。
在下一章中,我们将研究以往项目中获得的最佳实践和经验教训,解决了我们所面临的一些问题以及如何解决这些问题。
第九章:开发区块链和物联网解决方案的最佳实践
正如对每种新兴技术都是如此,成为早期采用者充满了挑战和需要学习的教训。本章的重点是提出一些解决方案,我们可以将其应用于现实项目中,以避免陷入麻烦。
本章将涵盖以下主题:
-
云应用的参考架构
-
如何使用 12 因素应用程序开发模型创建云原生应用程序
-
无服务器计算
-
使用 Hyperledger Composer 作为应用程序开发的加速器
开发云应用程序
与云应用程序相关的潜在问题很多,从资源的简单误用到无法解决的问题都有。应用简洁的架构并使用 12 因素应用程序开发模式可确保在应用程序扩展或缩减时不会陷入麻烦。
容器是将应用程序与其所有依赖项(包括其代码、运行时、中间件、库和操作系统)打包的标准化方式。Docker 和 Garden 是可以在 IBM 云平台上运行的容器,但也有其他容器类型可供使用,如 Rockt。使用容器增加了应用程序的可移植性,因此宿主操作系统是哪个特定的 Linux 发行版,以及您的应用程序是在不同的发行版上构建的都无关紧要,因为操作系统是容器化应用程序的一层,两个发行版一起交付。
以下图示了容器化应用程序的结构:
云平台使用容器化应用程序并将其部署到一组服务器中。我们可以将这些应用程序移到灵活的计算环境中,以更好地利用现有基础设施,并跟踪服务发现组件中部署的容器。
每个平台都有自己使用容器化应用程序部署模型的方式,如下图所示:
一个容器是基于容器镜像部署的,容器镜像是基本镜像、依赖项和应用程序的只读定义。每个相同应用的容器都是基于该镜像部署的,而在运行时对容器所做的任何更改仅在该容器处于活动状态时存在,并且仅适用于该容器的实例。
参考架构
云计算为部署应用程序创建了一个抽象的环境;我们使用虚拟运行时。这意味着我们没有位置意识,也不能保证我们的应用程序会留在同一个数据中心或虚拟机中。我们甚至不能确信应用程序的 IP 地址在 10 分钟后仍然相同。以下图表显示了使用 IBM Cloud Public(Bluemix)成功应用的云应用程序的参考架构:
云原生应用程序应该水平扩展,这意味着每当工作负载需求增加时,应用程序应该增加该应用程序的实例数量以处理新请求。同样,如果工作负载减少,应该减少应用程序实例的数量。
使用 12 因素应用程序模型进行开发
12 因素应用模型是一组应该遵循的实践,以使云应用程序具有可伸缩性。它为敌对的云环境变化提供支持。
该模型的 12 个原则如下:
-
**代码库:**我们的代码库在修订控制中被跟踪,并且被部署多次。
-
**依赖关系:**我们应该明确声明和隔离依赖关系。
-
**配置:**我们应该将应用程序配置参数存储在环境中。
-
**后端服务:**我们应该将后端服务视为附加资源。
-
**构建、发布、运行:**我们应该严格区分构建和运行阶段。
-
**进程:**我们应该将应用程序作为一个或多个无状态进程执行。
-
**端口绑定:**我们应该通过端口绑定导出服务。
-
**并发性:**我们应该通过进程模型进行横向扩展。
-
**可处置性:**我们应该通过快速启动和优雅关闭来最大程度地提高鲁棒性。
-
**开发/生产对等性:**我们应该尽可能地使开发、演示和生产保持相似。
-
**日志:**我们应该将日志视为事件流。
-
**管理进程:**我们应该将管理和管理任务作为一次性进程运行。
这些原则减少了与云计算相关的简单错误的数量。
您不必将所有这些概念都应用于您开发的所有云原生应用程序。例如,如果您不需要脚本来预加载数据库,则不需要应用管理进程原则。然而,如果您正在使用一个需要保持状态或与不同应用程序共享状态(如会话)的应用程序,那么使用后端服务是必不可少的,因为您永远不知道响应用户请求的容器所在的物理或虚拟计算机主机是什么。
无服务器计算
无服务器计算是部署模型,其中应用程序部署在环境中,但不一定始终运行。它的容器在首次执行时启动,并在请求需要执行它时保持活动。在空闲一段时间后,该应用程序的容器被停止。重要的是要注意,停止的容器需要一段时间才能启动,因此实时响应并不是无服务器应用程序的优势。
无服务器应用程序(或者像许多云服务提供商所称的云函数)是部署并附加到触发器的微服务,该触发器负责启动包含该功能的容器并运行它。触发器可以是数据库更改,传递给代理的消息,HTTP 请求或其他类型的请求。
云提供商通常根据云函数的执行持续时间和资源分配(通常是内存)收费。例如,一个云函数可能需要 500 毫秒,并使用 256MB 的内存。
一个成功的云函数不需要大量计算和大量请求(定期过程)。为了方便构建和部署无服务器应用程序过程,无服务器框架是一个不错的选择,因为它支持谷歌云、AWS、IBM 云和微软 Azure 对无服务器计算的实现。
使用 Hyperledger Composer 进行区块链开发
Hyperledger Composer 是 Linux Foundation 在 Hyperledger 品牌下托管的一个项目。该项目旨在创建一个框架和工具集,加速使用 Hyperledger Fabric 开发区块链应用程序,并简化与其他应用程序的集成。需要牢记的是,任何框架都意图通过抽象部分复杂性来简化解决方案的某个方面,但也会限制对所应用抽象的控制。
Hyperledger Composer 工具包
Hyperledger Composer 并不是解决 Hyperledger Fabric 提出的所有复杂性的通用解决方案。它剥夺了一些可以自定义的任务灵活性。然而,它所做的是提供一个工具包,用于创建链码项目,构建区块链应用程序包(.bna文件)并将它们部署到 Hyperledger Fabric。
使用 Hyperledger Composer 开发业务网络的重点是使用项目结构和通用语言创建资产、参与者、交易、查询和访问控制列表。在创建业务网络定义之后,Composer 有工具可以将应用程序打包并部署到 Hyperledger Fabric 平台。
Hyperledger Composer REST 服务器
为了简化与其他应用程序的集成,Hyperledger Composer 提供了 Composer REST 服务器,这是建立在 LoopBack 框架之上的 API 服务器,连接到定义的业务网络。它检索资产、交易和参与者的信息,并提供了一个 REST API 服务器和一个服务合同,以 swagger 格式描述,以便与业务网络进行交互。
Composer REST 服务器提供了许多有用的功能。最值得一看的是身份验证、多用户模式和数据源配置。
身份验证和多用户模式
当您创建业务应用程序时,请求进行身份验证并不少见。Composer REST 服务器提供了连接到许多身份验证和授权提供程序的手段,使用 Passport 中间件。虽然该项目声称 Passport 有超过 300 种身份验证和授权策略,但我们的经验表明,并非所有这些都能即插即用;有时,您必须创建自定义代码才能使它们正常工作。然而,我们已成功地实现了 Google、GitHub、Auth0 和 LDAP 的身份验证策略。
多用户模式允许多个参与者使用单个 Composer REST 服务器,而不是为每个参与者部署独立的 Composer REST 服务器。在这种模式下,使用主名片检索 API,但与业务网络的交互是使用其自己的名片。此模式需要启用用户身份验证。
数据源配置
Composer REST 服务器使用数据源存储用户会话数据。这并不意味着必须配置显式数据源;如果没有配置数据源,Composer REST 服务器将使用即插即用的内存连接器。
当使用多个 Composer REST 服务器实例以实现高可用性或负载平衡时,这些实例不共享内存,因此需要数据源。可以使用任何具有 loopback 连接器的数据源。在我们的经验中,MongoDB、Cloudant 和 Redis 可以即插即用;只需按照 Hyperledger 提供的步骤安装连接器并配置环境变量即可。
摘要
在本章中,我们已经了解了在云环境中开发和部署应用程序的影响。我们考虑了容器的工作原理,以及如何将容器化的应用程序部署到云平台,以及另一种模型:无服务器计算。我们还介绍了云原生应用程序开发的 12 因素模型原则。
然后,我们将 Hyperledger Composer 视为开发区块链解决方案的加速器。我们探讨了各种功能,包括使用身份验证、多用户模式和数据源配置。
这本书提供了有关使用 IBM Watson IoT 平台和 Hyperledger Compose 创建简单应用程序的信息。这些远非是唯一支持物联网和区块链解决方案的平台和工具,但概念是相同的,可以应用。如果您对使用所解释的工具进行扩展功能感兴趣,无论是 Watson IoT 还是 Hyperledger Fabric / Composer,都提供了详尽的文档以及大量社区提供的文章,但是,我们的观点是实践是了解它们是否适合特定解决方案的最佳方式,因此,即使您想学习如何使用工具包,也只需尝试一下,简单的用例是良好的教师。
进一步阅读
本章介绍的主题是一个概述,如果您需要更深入地了解任何主题,我们建议阅读以下参考资料:
-
12 因素应用程序方法论:
12factor.net/ -
无服务器框架:
serverless.com/ -
Hyperledger Composer:
hyperledger.github.io/composer