使用Chainlink外部适配器构建RFID区块链集成系统

  • Chainlink
  • 更新于 2021-01-28 09:39
  • 阅读 2429

目前的物联网追踪了比以往任何时候都更多的真实世界对象和流程,也产生了大量的且不断增长的数据。Chainlink外部适配器非常适合...

目前的物联网追踪了比以往任何时候都更多的真实世界对象和流程,也产生了大量的且不断增长的数据。Chainlink外部适配器非常适合将物联网数据通过安全、可靠的预言机网络传送到各种物联网智能合约用例中,例如链上供应链业务逻辑或追踪温度数据用于智能合约保险理赔。将RFID扫描器(射频识别)数据整合到区块链中就是这样一个例子。

Chainlink黑客马拉松中获得最佳开放项目奖的开发者Aram Moghaddassi和Aaron Wasserman使用Chainlink外部适配器将Arduino RFID连接到Chainlink预言机,用于一个去中心化的图书借阅和跟踪系统,称为开放图书馆项目

在这篇教程文章中,Aram Moghaddassi解释了他们如何实现这个项目。

<figure class="Editable-styled" data-block="true" data-editor="eldop" data-offset-key="cff2d-0-0" contenteditable="false" style="margin: 1.4em 0px; color: rgb(18, 18, 18); font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div class="Editable-divider FocusPlugin--unfocused" style="overflow: hidden;"><hr style="margin: 4em auto; width: 240px; max-width: 100%; border-right: none; border-bottom: none; border-left: none; border-image: initial; border-top: 1px solid rgb(211, 211, 211);"/></div></figure>

作者:Aram Moghaddassi

在区块链上启用的硬件系统是智能合约开发者的新领域。本篇文章将介绍构建此类系统的灵感、应用和技术设计,并作为教程(含实例),介绍如何将Chainlink节点上的RFID传感器的模拟硬件后端集成到智能合约中。

物联网硬件和智能合约的发展潜力

区块链和智能合约有能力确保目前部署的数百亿物联网设备的安全,并每年产生的数十亿字节的数据。从智能家居、城市、工厂、供应链,物联网设备正在彻底改变传统的基础设施,自动化系统有可能在这个领域创造强大的效率和商业逻辑。为此,我们开发了自定义的外部适配器,使智能合约能够与实时硬件系统对接。目前我们正在运营一个带有虚拟硬件后端的RFID外部适配器,您可以跟随本教程亲手实践一下。

<figure class="Editable-styled" data-block="true" data-editor="eldop" data-offset-key="9nfuv-0-0" contenteditable="false" style="margin: 1.4em 0px; color: rgb(18, 18, 18); font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div class="Image-resizerContainer" data-size="normal"><div><div class="Image-captionContainer" data-size="normal"><div><img class="Image FocusPlugin--unfocused Image--isBlock" src="https://pic2.zhimg.com/v2-1a1daa2e94b415daa15ca595372d3431_b.png" data-size="normal" data-rawwidth="1600" data-rawheight="522" data-watermark="watermark" data-original-src="https://pic2.zhimg.com/v2-1a1daa2e94b415daa15ca595372d3431_b.jpg" data-watermark-src="https://pic4.zhimg.com/v2-e746710d4bd02d35e84342d7efe86673_b.jpg" style="max-width: 100%; margin: 0px auto; display: block;"/></div></div></div></div></figure>

Chainlink去中心化的预言机网络如何将物联网数据安全地反馈给智能合约

我们的目标是:在10分钟内,您将部署一个可以从我们的RFID适配器查询数据的智能合约。我们希望让现有的Web3开发人员尽可能直观地开始在您的dApps中构建硬件集成。

您需要具备的知识

  • 熟悉使用Chainlink进行Solidity开发很重要。我们将在Kovan testnet上使用Remix Ethereum IDE
  • 不需要任何硬件!我们现在已经上线了一个RFID传感器的集成(很快会有更多设备出现)。它发送样本数据,您可以使用这些数据来快速启动和运行一个dApp。

本教程将是我们GitHub代码上的演示的书面版本,你可以在开始之前熟悉一下。

<figure class="Editable-styled" data-block="true" data-editor="eldop" data-offset-key="8sr57-0-0" contenteditable="false" style="margin: 1.4em 0px; color: rgb(18, 18, 18); font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div class="ZVideoLinkCard FocusPlugin--unfocused" target="_blank" rel="noopener noreferrer" data-za-not-track-link="true" data-za-module="Content" data-za-module-info="{"card":{"content":{"type":"Zvideo","token":"1329848163969712128","video_id":"1329848158886248448"}}}" style="border-radius: 8px; box-sizing: border-box; display: block; margin: 1em auto; max-width: 100%; overflow: hidden; position: relative; text-decoration: none; border: none !important; color: inherit !important;"><div class="ZVideoLinkCard-image" style="background-size: cover; background-position: 50% center; position: relative; padding-bottom: 369.594px; background-image: url("https://pic2.zhimg.com/v2-8c59ead25399094aaa7c236e18a48739_r.jpg?source=12a79843&#34;);">&lt;svg viewBox="0 0 72 72" class="ZVideoLinkCard-playIcon"><circle cx="36" cy="36" fill="#fff" fill-opacity=".95" r="36"></circle><path d="M50.835 37.06L29.477 49.97a1.203 1.203 0 0 1-1.664-.43 1.25 1.25 0 0 1-.17-.631V23.091c0-.682.543-1.234 1.213-1.234.219 0 .433.06.62.173l21.359 12.91a1.245 1.245 0 0 1 0 2.12z" fill="#444" fill-rule="nonzero"></path></svg><div class="ZVideoLinkCard-duration" style="bottom: 10px; color: rgb(255, 255, 255); font-size: 14px; line-height: 16px; position: absolute; right: 12px;">01:29</div></div><div class="ZVideoLinkCard-info" style="background-color: rgb(246, 246, 246); padding: 12px;"><div class="ZVideoLinkCard-title" style="color: rgb(18, 18, 18); font-size: 16px; line-height: 22px; font-weight: 600;">RFID adapter demo</div></div></div></figure>

构建RFID数据提供商智能合约

Job/Oracle Spec

我们将使用这个在Kovan testnet上运行的Job节点

RFID扫描仪适配器将以字节格式返回一个示例卡UID。

合约概要

这里是一个基本的合约,它调用节点的RFID作业,并将响应存储在一个变量中。

在Remix中部署这个合约

<pre class="public-DraftStyleDefault-pre" data-offset-key="28m6f-0-0" style="margin: 1.4em 0px; padding: 0.88889em; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: auto; background: rgb(246, 246, 246); border-radius: 4px; color: rgb(18, 18, 18); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><pre class="Editable-styled" data-block="true" data-editor="eldop" data-offset-key="28m6f-0-0" style="margin: 0px; padding: 0px; font-size: 0.9em; word-break: normal; overflow-wrap: normal; white-space: pre; overflow: initial; background: rgb(246, 246, 246); border-radius: 0px;"><div data-offset-key="28m6f-0-0" class="public-DraftStyleDefault-block public-DraftStyleDefault-ltr" style="max-width: 100%;"><span data-offset-key="28m6f-0-0"><span data-text="true">pragma solidity </span></span><span class="prism-token token operator" style="background: rgba(255, 255, 255, 0.5); color: rgb(194, 164, 105);"><span data-offset-key="28m6f-1-0"><span data-text="true">^</span></span></span><span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-2-0"><span data-text="true">0.6</span></span></span><span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-3-0"><span data-text="true">.0</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-4-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-5-0"><span data-text="true">

</span></span><span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);"><span data-offset-key="28m6f-6-0"><span data-text="true">import</span></span></span><span data-offset-key="28m6f-7-0"><span data-text="true"> </span></span><span class="prism-token token string" style="background-color: inherit !important; color: grey;"><span data-offset-key="28m6f-8-0"><span data-text="true">"https://github.com/smartcontractkit/chainlink/blob/develop/evm-contracts/src/v0.6/ChainlinkClient.sol&#34;&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-9-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-10-0"><span data-text="true">

contract Client is ChainlinkClient </span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-11-0"><span data-text="true">{</span></span></span><span data-offset-key="28m6f-12-0"><span data-text="true"> </span></span><span class="prism-token token comment" style="background-color: inherit !important; color: rgb(112, 128, 144);"><span data-offset-key="28m6f-13-0"><span data-text="true">// where to store the last id scanned</span></span></span><span data-offset-key="28m6f-14-0"><span data-text="true"> bytes32 </span></span><span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);"><span data-offset-key="28m6f-15-0"><span data-text="true">public</span></span></span><span data-offset-key="28m6f-16-0"><span data-text="true"> last_uid</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-17-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-18-0"><span data-text="true"> </span></span><span class="prism-token token comment" style="background-color: inherit !important; color: rgb(112, 128, 144);"><span data-offset-key="28m6f-19-0"><span data-text="true">// Chainlink vars for communicating with the RFID external adapter</span></span></span><span data-offset-key="28m6f-20-0"><span data-text="true"> address </span></span><span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);"><span data-offset-key="28m6f-21-0"><span data-text="true">private</span></span></span><span data-offset-key="28m6f-22-0"><span data-text="true"> oracle</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-23-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-24-0"><span data-text="true"> bytes32 </span></span><span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);"><span data-offset-key="28m6f-25-0"><span data-text="true">private</span></span></span><span data-offset-key="28m6f-26-0"><span data-text="true"> jobId</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-27-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-28-0"><span data-text="true"> uint256 </span></span><span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);"><span data-offset-key="28m6f-29-0"><span data-text="true">private</span></span></span><span data-offset-key="28m6f-30-0"><span data-text="true"> fee</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-31-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-32-0"><span data-text="true">

&lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-33-0">&lt;span data-text="true">constructor&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-34-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-35-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-36-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);">&lt;span data-offset-key="28m6f-37-0">&lt;span data-text="true">public&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-38-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-39-0">&lt;span data-text="true">{&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-40-0">&lt;span data-text="true">
    &lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-41-0">&lt;span data-text="true">setPublicChainlinkToken&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-42-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-43-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-44-0">&lt;span data-text="true">;&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-45-0">&lt;span data-text="true">
    oracle &lt;/span>&lt;/span>&lt;span class="prism-token token operator" style="background: rgba(255, 255, 255, 0.5); color: rgb(194, 164, 105);">&lt;span data-offset-key="28m6f-46-0">&lt;span data-text="true">=&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-47-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-48-0">&lt;span data-text="true">0x42149D794A135989319b66Dbcb770Ad36075a92e&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-49-0">&lt;span data-text="true">;&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-50-0">&lt;span data-text="true">
    jobId &lt;/span>&lt;/span>&lt;span class="prism-token token operator" style="background: rgba(255, 255, 255, 0.5); color: rgb(194, 164, 105);">&lt;span data-offset-key="28m6f-51-0">&lt;span data-text="true">=&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-52-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token string" style="background-color: inherit !important; color: grey;">&lt;span data-offset-key="28m6f-53-0">&lt;span data-text="true">&#34;785558e0bed6466b9567322cc2f4ca91&#34;&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-54-0">&lt;span data-text="true">;&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-55-0">&lt;span data-text="true">
    fee &lt;/span>&lt;/span>&lt;span class="prism-token token operator" style="background: rgba(255, 255, 255, 0.5); color: rgb(194, 164, 105);">&lt;span data-offset-key="28m6f-56-0">&lt;span data-text="true">=&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-57-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-58-0">&lt;span data-text="true">1&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-59-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token operator" style="background: rgba(255, 255, 255, 0.5); color: rgb(194, 164, 105);">&lt;span data-offset-key="28m6f-60-0">&lt;span data-text="true">*&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-61-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-62-0">&lt;span data-text="true">10&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-63-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token operator" style="background: rgba(255, 255, 255, 0.5); color: rgb(194, 164, 105);">&lt;span data-offset-key="28m6f-64-0">&lt;span data-text="true">**&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-65-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-66-0">&lt;span data-text="true">18&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-67-0">&lt;span data-text="true">;&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-68-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token comment" style="background-color: inherit !important; color: rgb(112, 128, 144);">&lt;span data-offset-key="28m6f-69-0">&lt;span data-text="true">// 0.1 LINK&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-70-0">&lt;span data-text="true">
&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-71-0">&lt;span data-text="true">}&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-72-0">&lt;span data-text="true">

&lt;/span>&lt;/span>&lt;span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);">&lt;span data-offset-key="28m6f-73-0">&lt;span data-text="true">function&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-74-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-75-0">&lt;span data-text="true">requestData&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-76-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-77-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-78-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);">&lt;span data-offset-key="28m6f-79-0">&lt;span data-text="true">public&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-80-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-81-0">&lt;span data-text="true">returns&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-82-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-83-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token parameter" style="background-color: inherit !important;">&lt;span data-offset-key="28m6f-84-0">&lt;span data-text="true">bytes32 requestId&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-85-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-86-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-87-0">&lt;span data-text="true">{&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-88-0">&lt;span data-text="true">
    &lt;/span>&lt;/span>&lt;span class="prism-token token comment" style="background-color: inherit !important; color: rgb(112, 128, 144);">&lt;span data-offset-key="28m6f-89-0">&lt;span data-text="true">// creates the Request&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-90-0">&lt;span data-text="true">
    Chainlink&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-91-0">&lt;span data-text="true">.&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-92-0">&lt;span data-text="true">Request memory req &lt;/span>&lt;/span>&lt;span class="prism-token token operator" style="background: rgba(255, 255, 255, 0.5); color: rgb(194, 164, 105);">&lt;span data-offset-key="28m6f-93-0">&lt;span data-text="true">=&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-94-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-95-0">&lt;span data-text="true">buildChainlinkRequest&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-96-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-97-0">&lt;span data-text="true">jobId&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-98-0">&lt;span data-text="true">,&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-99-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-100-0">&lt;span data-text="true">address&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-101-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);">&lt;span data-offset-key="28m6f-102-0">&lt;span data-text="true">this&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-103-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-104-0">&lt;span data-text="true">,&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-105-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);">&lt;span data-offset-key="28m6f-106-0">&lt;span data-text="true">this&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-107-0">&lt;span data-text="true">.&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-108-0">&lt;span data-text="true">fulfill&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-109-0">&lt;span data-text="true">.&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-110-0">&lt;span data-text="true">selector&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-111-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-112-0">&lt;span data-text="true">;&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-113-0">&lt;span data-text="true">
    &lt;/span>&lt;/span>&lt;span class="prism-token token comment" style="background-color: inherit !important; color: rgb(112, 128, 144);">&lt;span data-offset-key="28m6f-114-0">&lt;span data-text="true">// Sends the request&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-115-0">&lt;span data-text="true">
    &lt;/span>&lt;/span>&lt;span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);">&lt;span data-offset-key="28m6f-116-0">&lt;span data-text="true">return&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-117-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-118-0">&lt;span data-text="true">sendChainlinkRequestTo&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-119-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-120-0">&lt;span data-text="true">oracle&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-121-0">&lt;span data-text="true">,&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-122-0">&lt;span data-text="true"> req&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-123-0">&lt;span data-text="true">,&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-124-0">&lt;span data-text="true"> fee&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-125-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-126-0">&lt;span data-text="true">;&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-127-0">&lt;span data-text="true">
&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-128-0">&lt;span data-text="true">}&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-129-0">&lt;span data-text="true">

&lt;/span>&lt;/span>&lt;span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);">&lt;span data-offset-key="28m6f-130-0">&lt;span data-text="true">function&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-131-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-132-0">&lt;span data-text="true">fulfill&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-133-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token parameter" style="background-color: inherit !important;">&lt;span data-offset-key="28m6f-134-0">&lt;span data-text="true">bytes32 _requestId&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-135-0">&lt;span data-text="true">,&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token parameter" style="background-color: inherit !important;">&lt;span data-offset-key="28m6f-136-0">&lt;span data-text="true"> bytes32 uid&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-137-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-138-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);">&lt;span data-offset-key="28m6f-139-0">&lt;span data-text="true">public&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-140-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);">&lt;span data-offset-key="28m6f-141-0">&lt;span data-text="true">recordChainlinkFulfillment&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-142-0">&lt;span data-text="true">(&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token parameter" style="background-color: inherit !important;">&lt;span data-offset-key="28m6f-143-0">&lt;span data-text="true">_requestId&lt;/span>&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-144-0">&lt;span data-text="true">)&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-145-0">&lt;span data-text="true"> &lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-146-0">&lt;span data-text="true">{&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-147-0">&lt;span data-text="true">
    last_uid &lt;/span>&lt;/span>&lt;span class="prism-token token operator" style="background: rgba(255, 255, 255, 0.5); color: rgb(194, 164, 105);">&lt;span data-offset-key="28m6f-148-0">&lt;span data-text="true">=&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-149-0">&lt;span data-text="true"> uid&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-150-0">&lt;span data-text="true">;&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-151-0">&lt;span data-text="true">
&lt;/span>&lt;/span>&lt;span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);">&lt;span data-offset-key="28m6f-152-0">&lt;span data-text="true">}&lt;/span>&lt;/span>&lt;/span>&lt;span data-offset-key="28m6f-153-0">&lt;span data-text="true">

</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-154-0"><span data-text="true">}</span></span></span></div></pre></pre>

部署合约并与交互

按照Chainlink文档,如何部署合约并获取testnet LINK。我们建议用至少10个LINK来存到合约中。

合约中的requestData方法会对RFID作业进行Chainlink请求,完成后会把最后一次扫描的UID放到last_uid变量中。

应用及后期集成

我们的RFID集成目前还处在概念证明阶段,目前可以在智能合约上运行一个实时硬件设备。我们希望不断地建立硬件集成案例,最终在Chainlink社区内引导一个硬件生态系统。不过,最终还是要靠开发者找到使用这项技术的杀手级应用。

以下是我们对RFID适配器的一些想法,你现在就可以进行研究。

  • 实物的保管管理--贴有RFID芯片的物品可以在不同的航点进行扫描,安全地追踪位置。这个系统可以帮助到基于区块链的供应链管理应用。
  • 酒店入住/退房系统--Airbnb/酒店可以在用户入住某地时自动初始化租赁合约。智能合约可以自动实时收取任何逾期费用。
  • 签署数字协议的物理验证系统--使用RFID扫描来验证用户的真实存在。
  • 发挥创意吧! RFID接口的通用性很强,你能想象到的任何东西都有可能构建。

最好的链上硬件应用将利用智能合约的独特属性,获得比传统软件更多的优势。智能合约是确定性的、去中心化的、数字化的协议。在硬件方面,区块链实现的最有价值的好处是:(1)强大的机器对机器通信协议和(2)来自传感器的不可篡改的数据馈送。

构建自己的硬件外部适配器

在构建开放图书馆项目时,我们的团队学到了一些经验。如果你正在考虑自己构建硬件外部适配器,这些原则是我们认为有用的。虽然我们这些经验是在构建RFID扫描仪的硬件适配器时做出的,但这些原则应该适用于任何实时硬件传感器集成。

原则0:适配器服务器结构与其他所有的适配器服务器结构是一样的。你可以使用任何现有的外部适配器模板作为起点。主要的区别在于以下原则。

原则1:硬件必须有一些外部适配器可以调用的软件接口/API。

对于RFID扫描器,我们使用pyserial写了一个自定义的解析器,创建了一个简单的接口来从每次扫描中获取UID代码。然后我们可以写一个简单的flask服务器,接受POST请求来读取UID。

对于不太能自定义的硬件(比如不是Arduino),这个软件接口可能由一个开箱即用的API提供。在这种情况下,你只需要关心编写外部适配器接口的问题。

原则2:外部适配器必须在本地运行(忽略虚拟硬件后端)。

对于那些熟悉在云服务器上部署适配器的人来说,这可能看起来很奇怪。然而,考虑到我们正在将数据从本地硬件传感器转移到远程Chainlink节点,向节点提供数据的适配器服务器必须在本地运行。我们想象的最佳设置是使用一个专用的树莓派来运行硬件和服务器(尽管我们在开发过程中使用了笔记本电脑)。

<figure class="Editable-styled" data-block="true" data-editor="eldop" data-offset-key="bl1kl-0-0" contenteditable="false" style="margin: 1.4em 0px; color: rgb(18, 18, 18); font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div class="Editable-divider FocusPlugin--unfocused" style="overflow: hidden;"><hr style="margin: 4em auto; width: 240px; max-width: 100%; border-right: none; border-bottom: none; border-left: none; border-image: initial; border-top: 1px solid rgb(211, 211, 211);"/></div></figure>

今天就开始使用外部适配器进行构建

如果你是一名开发者,想要将你的智能合约连接到底层区块链之外的现有硬件或数据,请在这里联系或访问开发者文档

如果你在这里学到了一些新的东西,想要展示你所构建的东西,或者为一些演示仓库开发了一个前端,请确保你在TwitterDiscordReddit上分享它,并且用#Chainlink来标记你的仓库。

Website | Twitter |Discord | Reddit | YouTube | Telegram | Events | GitHub | Price Feeds | DeFi

<figure class="Editable-styled" data-block="true" data-editor="eldop" data-offset-key="cg6ks-0-0" contenteditable="false" style="margin: 1.4em 0px; color: rgb(18, 18, 18); font-family: -apple-system, system-ui, "Helvetica Neue", "PingFang SC", "Microsoft YaHei", "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif; font-size: 16px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial;"><div target="_blank" href="https://blog.chain.link/rfid-blockchain-integration-with-chainlink-external-adapters/" data-draft-node="block" data-draft-type="link-card" data-image="https://pic3.zhimg.com/v2-d0b9b3aaeb63c0a4fdf59178d83384f6_180x120.jpg" data-image-width="1920" data-image-height="1080" class="LinkCard FocusPlugin--unfocused LinkCard--hasImage" data-offset-key="cg6ks-0-0" style="position: relative; display: block; margin: 1em auto; width: 390px; box-sizing: border-box; border-radius: 12px; max-width: 100%; overflow: hidden; text-decoration: none; border: none !important; color: inherit !important;"><span class="LinkCard-backdrop" style="position: absolute; inset: 0px; background-repeat: no-repeat; filter: blur(20px); background-size: cover; background-position: 50% center; background-image: url("https://pic3.zhimg.com/v2-d0b9b3aaeb63c0a4fdf59178d83384f6_180x120.jpg&#34;);">&lt;/span>&lt;span class="LinkCard-content" style="position: relative; display: flex; -webkit-box-align: center; align-items: center; -webkit-box-pack: justify; justify-content: space-between; padding: 12px; border-radius: inherit; background-color: rgba(246, 246, 246, 0.88);"><span class="LinkCard-text" style="overflow: hidden;"><span class="LinkCard-title" data-text="true" style="display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; max-height: 40px; font-size: 16px; font-weight: 500; line-height: 1.25; color: rgb(18, 18, 18);">RFID Blockchain Integration With Chainlink External Adapters</span><span class="LinkCard-meta" style="display: flex; margin-top: 4px; font-size: 14px; line-height: 20px; color: rgb(153, 153, 153); white-space: nowrap;"><span style="display: inline-flex; align-items: center;"><svg class="Zi Zi--InsertLink" fill="currentColor" viewBox="0 0 24 24" width="17" height="17"><path d="M13.414 4.222a4.5 4.5 0 1 1 6.364 6.364l-3.005 3.005a.5.5 0 0 1-.707 0l-.707-.707a.5.5 0 0 1 0-.707l3.005-3.005a2.5 2.5 0 1 0-3.536-3.536l-3.005 3.005a.5.5 0 0 1-.707 0l-.707-.707a.5.5 0 0 1 0-.707l3.005-3.005zm-6.187 6.187a.5.5 0 0 1 .638-.058l.07.058.706.707a.5.5 0 0 1 .058.638l-.058.07-3.005 3.004a2.5 2.5 0 0 0 3.405 3.658l.13-.122 3.006-3.005a.5.5 0 0 1 .638-.058l.069.058.707.707a.5.5 0 0 1 .058.638l-.058.069-3.005 3.005a4.5 4.5 0 0 1-6.524-6.196l.16-.168 3.005-3.005zm8.132-3.182a.25.25 0 0 1 .353 0l1.061 1.06a.25.25 0 0 1 0 .354l-8.132 8.132a.25.25 0 0 1-.353 0l-1.061-1.06a.25.25 0 0 1 0-.354l8.132-8.132z"></path></svg></span>blog.chain.link</span></span><span class="LinkCard-imageCell" style="margin-left: 8px; border-radius: 6px;"><img class="LinkCard-image LinkCard-image--horizontal" alt="图标" src="https://pic3.zhimg.com/v2-d0b9b3aaeb63c0a4fdf59178d83384f6_180x120.jpg" style="background-color: rgb(235, 235, 235); display: block; width: 90px; height: 60px; object-fit: cover; border-radius: inherit; max-width: none;"/></span></span></div></figure>

本文首发于:https://mp.weixin.qq.com/s/yckxAbnVW5wXAv-LxaI1rA

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Chainlink
Chainlink
顶尖的智能合约去中心化预言机网络解决方案 https://chain.link/