目前的物联网追踪了比以往任何时候都更多的真实世界对象和流程,也产生了大量的且不断增长的数据。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>
在区块链上启用的硬件系统是智能合约开发者的新领域。本篇文章将介绍构建此类系统的灵感、应用和技术设计,并作为教程(含实例),介绍如何将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中构建硬件集成。
本教程将是我们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");"><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>
我们将使用这个在Kovan testnet上运行的Job和节点。
RFID扫描仪适配器将以字节格式返回一个示例卡UID。
这里是一个基本的合约,它调用节点的RFID作业,并将响应存储在一个变量中。
<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"</span></span></span><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">
</span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-33-0"><span data-text="true">constructor</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-34-0"><span data-text="true">(</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-35-0"><span data-text="true">)</span></span></span><span data-offset-key="28m6f-36-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-37-0"><span data-text="true">public</span></span></span><span data-offset-key="28m6f-38-0"><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-39-0"><span data-text="true">{</span></span></span><span data-offset-key="28m6f-40-0"><span data-text="true">
</span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-41-0"><span data-text="true">setPublicChainlinkToken</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-42-0"><span data-text="true">(</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-43-0"><span data-text="true">)</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-44-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-45-0"><span data-text="true">
oracle </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-46-0"><span data-text="true">=</span></span></span><span data-offset-key="28m6f-47-0"><span data-text="true"> </span></span><span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-48-0"><span data-text="true">0x42149D794A135989319b66Dbcb770Ad36075a92e</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-49-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-50-0"><span data-text="true">
jobId </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-51-0"><span data-text="true">=</span></span></span><span data-offset-key="28m6f-52-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-53-0"><span data-text="true">"785558e0bed6466b9567322cc2f4ca91"</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-54-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-55-0"><span data-text="true">
fee </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-56-0"><span data-text="true">=</span></span></span><span data-offset-key="28m6f-57-0"><span data-text="true"> </span></span><span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-58-0"><span data-text="true">1</span></span></span><span data-offset-key="28m6f-59-0"><span data-text="true"> </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-60-0"><span data-text="true">*</span></span></span><span data-offset-key="28m6f-61-0"><span data-text="true"> </span></span><span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-62-0"><span data-text="true">10</span></span></span><span data-offset-key="28m6f-63-0"><span data-text="true"> </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-64-0"><span data-text="true">**</span></span></span><span data-offset-key="28m6f-65-0"><span data-text="true"> </span></span><span class="prism-token token number" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-66-0"><span data-text="true">18</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-67-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-68-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-69-0"><span data-text="true">// 0.1 LINK</span></span></span><span data-offset-key="28m6f-70-0"><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-71-0"><span data-text="true">}</span></span></span><span data-offset-key="28m6f-72-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-73-0"><span data-text="true">function</span></span></span><span data-offset-key="28m6f-74-0"><span data-text="true"> </span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-75-0"><span data-text="true">requestData</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-76-0"><span data-text="true">(</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-77-0"><span data-text="true">)</span></span></span><span data-offset-key="28m6f-78-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-79-0"><span data-text="true">public</span></span></span><span data-offset-key="28m6f-80-0"><span data-text="true"> </span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-81-0"><span data-text="true">returns</span></span></span><span data-offset-key="28m6f-82-0"><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-83-0"><span data-text="true">(</span></span></span><span class="prism-token token parameter" style="background-color: inherit !important;"><span data-offset-key="28m6f-84-0"><span data-text="true">bytes32 requestId</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-85-0"><span data-text="true">)</span></span></span><span data-offset-key="28m6f-86-0"><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-87-0"><span data-text="true">{</span></span></span><span data-offset-key="28m6f-88-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-89-0"><span data-text="true">// creates the Request</span></span></span><span data-offset-key="28m6f-90-0"><span data-text="true">
Chainlink</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-91-0"><span data-text="true">.</span></span></span><span data-offset-key="28m6f-92-0"><span data-text="true">Request memory req </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-93-0"><span data-text="true">=</span></span></span><span data-offset-key="28m6f-94-0"><span data-text="true"> </span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-95-0"><span data-text="true">buildChainlinkRequest</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-96-0"><span data-text="true">(</span></span></span><span data-offset-key="28m6f-97-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-98-0"><span data-text="true">,</span></span></span><span data-offset-key="28m6f-99-0"><span data-text="true"> </span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-100-0"><span data-text="true">address</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-101-0"><span data-text="true">(</span></span></span><span class="prism-token token keyword" style="background-color: inherit !important; color: rgb(0, 102, 255);"><span data-offset-key="28m6f-102-0"><span data-text="true">this</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-103-0"><span data-text="true">)</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-104-0"><span data-text="true">,</span></span></span><span data-offset-key="28m6f-105-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-106-0"><span data-text="true">this</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-107-0"><span data-text="true">.</span></span></span><span data-offset-key="28m6f-108-0"><span data-text="true">fulfill</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-109-0"><span data-text="true">.</span></span></span><span data-offset-key="28m6f-110-0"><span data-text="true">selector</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-111-0"><span data-text="true">)</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-112-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-113-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-114-0"><span data-text="true">// Sends the request</span></span></span><span data-offset-key="28m6f-115-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-116-0"><span data-text="true">return</span></span></span><span data-offset-key="28m6f-117-0"><span data-text="true"> </span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-118-0"><span data-text="true">sendChainlinkRequestTo</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-119-0"><span data-text="true">(</span></span></span><span data-offset-key="28m6f-120-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-121-0"><span data-text="true">,</span></span></span><span data-offset-key="28m6f-122-0"><span data-text="true"> req</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-123-0"><span data-text="true">,</span></span></span><span data-offset-key="28m6f-124-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-125-0"><span data-text="true">)</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-126-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-127-0"><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-128-0"><span data-text="true">}</span></span></span><span data-offset-key="28m6f-129-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-130-0"><span data-text="true">function</span></span></span><span data-offset-key="28m6f-131-0"><span data-text="true"> </span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-132-0"><span data-text="true">fulfill</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-133-0"><span data-text="true">(</span></span></span><span class="prism-token token parameter" style="background-color: inherit !important;"><span data-offset-key="28m6f-134-0"><span data-text="true">bytes32 _requestId</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-135-0"><span data-text="true">,</span></span></span><span class="prism-token token parameter" style="background-color: inherit !important;"><span data-offset-key="28m6f-136-0"><span data-text="true"> bytes32 uid</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-137-0"><span data-text="true">)</span></span></span><span data-offset-key="28m6f-138-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-139-0"><span data-text="true">public</span></span></span><span data-offset-key="28m6f-140-0"><span data-text="true"> </span></span><span class="prism-token token function" style="background-color: inherit !important; color: rgb(255, 51, 102);"><span data-offset-key="28m6f-141-0"><span data-text="true">recordChainlinkFulfillment</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-142-0"><span data-text="true">(</span></span></span><span class="prism-token token parameter" style="background-color: inherit !important;"><span data-offset-key="28m6f-143-0"><span data-text="true">_requestId</span></span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-144-0"><span data-text="true">)</span></span></span><span data-offset-key="28m6f-145-0"><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-146-0"><span data-text="true">{</span></span></span><span data-offset-key="28m6f-147-0"><span data-text="true">
last_uid </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-148-0"><span data-text="true">=</span></span></span><span data-offset-key="28m6f-149-0"><span data-text="true"> uid</span></span><span class="prism-token token punctuation" style="background-color: inherit !important; color: rgb(153, 153, 153);"><span data-offset-key="28m6f-150-0"><span data-text="true">;</span></span></span><span data-offset-key="28m6f-151-0"><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-152-0"><span data-text="true">}</span></span></span><span data-offset-key="28m6f-153-0"><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适配器的一些想法,你现在就可以进行研究。
最好的链上硬件应用将利用智能合约的独特属性,获得比传统软件更多的优势。智能合约是确定性的、去中心化的、数字化的协议。在硬件方面,区块链实现的最有价值的好处是:(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>
如果你是一名开发者,想要将你的智能合约连接到底层区块链之外的现有硬件或数据,请在这里联系或访问开发者文档。
如果你在这里学到了一些新的东西,想要展示你所构建的东西,或者为一些演示仓库开发了一个前端,请确保你在Twitter,Discord或Reddit上分享它,并且用#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");"></span><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>
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!