چگونه اینترنت اشیا و فناوری بلاک چین را در یک ایده پیاده کنیم؟

سال گذشته شاهد توجه بسیار زیاد رسانه‌ها به استارت‌آپ‌های بلاک چین بودیم. این استارت‌آپ‌ها از عموم مردم سرمایه جذب کردند سپس اکثر آنها بدون نشان یا محصولی ناپدید شدند. فارغ از اخلاقیات و قانونی بودن مدل جذب سرمایه آنها، چند مورد از ایده های این استارت آپ ها ارزش بازبینی دارند. یکی از این ایده ها، ترکیب اینترنت اشیا (IoT) و فناوری بلاک چین است.

معمولا هنگامی که محصول یا فناوری معرفی می‌شود، می‌توان درک کرد که چگونه و چرا فردی باید از این محصولات یا فناوری‌ها استفاده کند. در این مورد مشخص نبود که چرا و چگونه می‌توان از این ایده استفاده کرد.

شبکه‌های رایج IoT، با استفاده از دستگاه‌های کم مصرف و ارزان اطلاعات را جمع آوری می‌کنند و آن را به سرویس مرکزی انتقال می‌دهند. از طرف دیگر، بلاک چین ها تمایل به روش‌های گران برای ذخیره سازی اطلاعات دارند و به مقدار زیادی فضای ذخیره سازی و توان پردازشی برای تعامل کامل با آنها نیاز است. بلاک چین ها معمولا از رمزنگاری کلید عمومی و خصوصی استفاده می‌کنند. گفتنی است می‌توان کاربردهای مناسبی برای بلاک چین ها مشاهده کرد.

همخوانی نداشتن نکات مختلف

اولین مسأله ای که باید برطرف شود، استفاده کاملا کاربردی از کل سیستم لینوکس موجود نظیر نسخه Raspberry Pi در امکان پذیر ساختن ذخیره سازی اطلاعات توزیع شده، بدون نیاز به اعتماد و ایمن در دستگاه‌های خانگی (برای مثال تستر نان) است. زمان آماده به کار شدن دستگاه، مصرف برق و هزینه موجود باعث می‌شود که این فرایند به آرامی صورت بگیرد.

نوعی از معماری را در نظر بگیرید که دستگاه های IoT مختلف از طریق MQTT از سطوح مختلف امنیتی استفاده می‌کنند که کلیدهای عمومی و خصوصی دستگاه های مختلف را در شبکه نگهداری می‌کنند. در نتیجه، ذخیره کلیدها در هر دستگاه امکان پذیر می‌شود، اما از آنجایی که سرور باید این کلیدها را در Plaintext ذخیره کند (در رمزنگاری، Plaintext معمولا به معنای اطلاعات رمزگذاری شده است که به الگوریتم های رمزنگاری وارد می‌شوند)، باید از انتقال مکرر کلیدها اجتناب کنیم. هم چنین می‌توانیم سخت افزار مدیریت کلید اضافه ای را به ESP8266 اضافه کنیم و تراکنش ها را با امنیت قابل قبولی امضا کنیم، اما این اقدام نیازمند کار و زمان بیشتری است.

به هر حال، این معماری به ما امکان می‌دهد تا تمام نکات بلاک چین را مدیریت کنیم. در اینجا غیرمتمرکزسازی کاملی انجام نشده است، اما با توجه به نکات مثبت و منفی موجود، ارزش امتحان کردن را دارد.

غیرمتمرکزسازی سرور متمرکز

معمولا اطلاعات از دستگاه های معتبر و از طریق MQTT دریافت و در دیتابیس ذخیره می‌شود. نکته‌ای که باید مدنظر قرار دهیم، ارسال این اطلاعات به قرارداد هوشمند اتریوم است. برای انجام این کار، ابتدا با ایمپورت کردن ماژول های Python3 شروع می‌کنیم:

from web3 import Web3, HTTPProvider, IPCProvider, WebsocketProvider
from flask import Flask
from flask_mqtt import Mqtt
import time
import json as json

اضافه کردن پشتیبانی از MQTT کار آسانی نیست، بنابراین از Flask برای این مورد استفاده می‌کنیم. Web3 ماژولی است که تعامل با بلاک چین اتریوم را مدیریت می‌کند. با لیسنر (Listener) ساده ای شروع می‌کنیم که پیام های MQTT را پردازش می‌کند:

app = Flask(__name__)
app.config['MQTT_BROKER_URL'] = 'yourbroker.com' # your broker address goes here
app.config['MQTT_BROKER_PORT'] = 1883 # default port for non-tls connection
app.config['MQTT_USERNAME'] = '' # No username set for now
app.config['MQTT_PASSWORD'] = '' # no password set for now
app.config['MQTT_KEEPALIVE'] = 5 # keepalive every 5 seconds
app.config['MQTT_TLS_ENABLED'] = False # set TLS to disabled for testing purposes
mqtt = Mqtt()
mqtt.init_app(app)
running = True
@mqtt.on_connect()
def handle_connect(client, userdata, flags, rc):
    print("connected")
    mqtt.subscribe('topic') #your MQTT topic here
while running == True:
    @mqtt.on_message()
    def handle_mqtt_message(client, userdata, message):
        data = dict(
            topic=message.topic,
            payload=message.payload.decode()
        )
        barcode = (data["payload"])
        barcode = int(barcode)
        print (barcode)
        #our function to store the MQTT payload on Ethereum goes here as store_results(barcode)
        print ("OK")

این کار جوابگو است و پیام های ارسالی به آن را بازمی‌گرداند، اما در واقع به غیر از چاپ اطلاعات، کار دیگری با اطلاعات انجام نمی‌‌دهد.

قرارداد هوشمند ساده

قبل از ادامه کار، ما به یک قرارداد هوشمند ساده نیاز خواهیم داشت. در تصویر زیر یک قرارداد هوشمند ساده به زبان سالیدیتی نوشته شده است که یک عدد صحیح را در متغیری به اسم barcode ذخیره می‌کند:

pragma solidity >=0.4.0 <0.6.0;
// the pragma line above indicates which version of Solidity can be used to compile this contract. Solidity is updated OFTEN so this is very useful.
// The below names the contract, and the defines the variables it contains and their type
contract Barcode {
    address public owner = msg.sender;
    uint public creationTime = now;
    uint barcode;
// Only allow the contract owner to push barcode data to the contract.
    modifier onlyBy(address _account)
    {
        require(
            msg.sender == _account,
            "Sender not authorized."
        );
// Do not forget the "_;"! It will be replaced by the actual function body when the modifier is used.
        _;
    }
// This function is what we will call to set the variable x. It costs Ether to do so, and only stores one value (although historical values are preserved on the blockchain)
    
    function set(uint x) public onlyBy(owner) {
        barcode = x;
    }
// This function returns the value of x, it costs no Ether to do so.
    
    function get() public view returns (uint) {
        return barcode;
    }

پس از کامپایل کردن این قرارداد هوشمند در Remix، دکمه ای به صورت ABI مشخص می‌شود. این دکمه شامل توضیحات عملکردهای ارائه شده توسط قرارداد هوشمند است. Web3 برای تعامل با قرارداد هوشمند به این دکمه نیاز خواهد داشت. بر روی دکمه کلیک کنید تا کپی شود و سپس در یک فایل پیست کنید. در این مثال، ما از فایل barcode.json استفاده می‌کنیم.

سپس باید قرارداد هوشمند خود را به بلاک چین اضافه کنید. پس از ایجاد یک حساب در شبکه آزمایشی راپستن، می‌توانید با استفاده از کیف پول اتریوم، قرارداد هوشمند را به بلاک چین اضافه کنید.

بازگشت به برنامه

سپس به ماژول Web3 برای انتقال اطلاعات از MQTT به اتریوم نیاز داریم. ما از شبکه آزمایشی راپستن استفاده خواهیم کرد تا از ایجاد ازدحام در شبکه اصلی و انتشار کلیدهای خصوصی ارزشمند بدون هیچگونه مدیریت خودداری کنیم. هم چنین به یک حساب رایگان در infura.io نیاز داریم تا به عنوان ارتباط با شبکه اتریوم از آن استفاده کنیم. سپس یک URL ارائه می‌شود که در قسمت زیر می‌توانید پیست کنید. اطمینان حاصل کنید که از URL مناسب با شبکه آزمایشی راپستن استفاده کنید:

with open('full path to barcode.json') as f:
    abi = json.load(f)
    print("abi loaded")
w3 = Web3(HTTPProvider('URL provided by Infura'))
contract_address = 'contract address, including the 0x’
wallet_private_key = 'your test network private key here'
wallet_address = 'testnet wallet address, including the 0x'
contract = w3.eth.contract(address = contract_address, abi = abi)
def store_results(x):
    nonce = w3.eth.getTransactionCount(wallet_address)
#if something is failing, try print (nonce) to test connectivity to Infura here. Chain ID = 3 is Ropsten.
#Below, we craft a transaction to set variable x in the smart contract to the value provided to this function
    txn_dict = contract.functions.set(x).buildTransaction({
        'chainId': 3,
        'gas': 140000,
        'gasPrice': w3.toWei('40', 'gwei'),
        'nonce': nonce,
    })
#Then we sign the transaction with our private key
    signed_txn = w3.eth.account.signTransaction(txn_dict, private_key=wallet_private_key)
#The signed transaction is sent to the blockchain using Infura as an endpoint
    result = w3.eth.sendRawTransaction(signed_txn.rawTransaction)
# Then we wait for a receipt. It can take a short while.
    tx_receipt = w3.eth.getTransactionReceipt(result)
    count = 0
    while tx_receipt is None and (count < 30):
        time.sleep(10)
        tx_receipt = w3.eth.getTransactionReceipt(result)
    return(tx_receipt)
    if tx_receipt is None:
        tx_receipt = "Failed"
        return(tx_receipt)

ارتباط با اسکنر بارکد

در آخر، ما به سخت افزار IoT به عنوان منبع اطلاعات نیاز خواهیم داشت. می‌توان از یک اسکنر بارکد ساده استفاده و کد کوچکی اضافه کرد که بارکد اسکن شده را از MQTT خارج می‌کند:

-- Setup UART and print something so we know it's working
uart.setup(0, 9600, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)
print("Scanning")
-- Set up a couple of variables so they're not nil
data = ""
datac = ""
-- This function prints out the barcode data and clears all variables so the scanner can read a new barcode. If you wanted to send the data over MQTT, your code would replace the print statement here.
function finish()
    ClientID = 5446078
    m = mqtt.Client(ClientID, 120)
    datac = datac:gsub("%D+", "")
    print (datac)
    if datac ~= nil then
        m:connect("hardfork.asia", 1883, 0, function(client) print("connected") m:publish('5446078',datac,0,0) p = "Sent" print(p) m:close() scansoon() end)
    end
end
function scansoon()
    tmr.alarm(1, 1000, tmr.ALARM_SINGLE, function() scan() end)
    data = ""
    datac = ""
end
-- This function concatenates all data received over 150 milliseconds into the variable datac. The scanner sends the data in multiple parts to the ESP8266, which needs to be assembled into a single variable.
function scan()
    uart.on("data", 0, function(data)
        tmr.alarm(0,150,0,finish)
        datac = datac .. data
    end, 0)
end
tmr.alarm(1, 1000, tmr.ALARM_SINGLE, function() scan() end)

پس از آنکه به شبکه متصل شدیم و بارکد را اسکن کردیم، خروجی زیر را از برنامه مشاهده خواهیم کرد:

در آخر، اگر کیف پول اتریوم را اجرا کنیم و مقدار تابع Get در قرارداد هوشمند را بررسی کنیم یک بارکد مشاهده خواهیم کرد. سرانجام اینترنت بلاک چین اشیا ما کار می‌کند.


54321
امتیاز 5 از 1 رای

منبع hackaday
ممکن است شما دوست داشته باشید

ارسال نظر