يجب أن تكون التكنولوجيا في خدمة البشرية. يمكن لتكنولوجيا Blockchain، التي أحدثت ثورة في العديد من القطاعات، أن تحول أيضًا مجال الزراعة. ولجعل هذه التكنولوجيا اللامركزية اتجاهًا سائدًا للتبني، يجب علينا تبسيطها للوصول إلى عامة الناس حتى نتمكن من الوصول إلى المستخدمين الأوسع، مما يؤدي في النهاية إلى زيادة حالات الاستخدام. في هذا البرنامج التعليمي، سنقوم ببناء تطبيق لامركزي (dApp) يسمح للمستخدمين بشراء وبيع المنتجات الزراعية على شبكة بلوكتشين Rootstock (RSK). الهدف الرئيسي هو بناء تطبيق لامركزي يعمل على شبكة بلوكتشين. يمكن لأي نوع من المستخدمين إضافة المنتجات بسهولة لكسب المال عن طريق بيع منتجاتهم الزراعية دون تدخل بشري مفرط. في البداية، تم اختبار التطبيق على شبكة اختبار Rootstock، وهو الآن في حالة جاهزة للإنتاج تقريبًا (كان يحتاج فقط إلى تعديلات بسيطة للتبديل إلى الشبكة الرئيسية لـ Rootstock). تم تحميل المشروع بالفعل على GitHub، لذا يمكنك استنساخ المستودع لاختباره بنفسك. لهذا، أفضل على . ولكن في هذا البرنامج التعليمي، نحاول تقديم إرشادات متعمقة حتى يتمكن أي نوع من المستخدمين من بناء تطبيقهم اللامركزي بسهولة فهم البرنامج التعليمي خطوة بخطوة. قد نقترح عليك تنزيل كود الواجهة الأمامية من مستودع GitHub وإضافته إلى الدليل المناسب. سنغطي كل شيء من إعداد المشروع إلى نشر العقود الذكية وإنشاء واجهة أمامية تفاعلية بميزات في الوقت الفعلي. Readme.md GitHub قبل البدء، نهدف إلى بناء تطبيق لامركزي يسمى AgriMarket والذي من المتوقع أن يتمتع بالميزات التالية: يسمح للمستخدمين بالوصول إلى ميزات Web3 من خلال المحافظ المدعومة (MetaMask في حالتنا). يتيح للمستخدمين إضافة منتجاتهم الزراعية مع أسعارها عن طريق ربط محافظهم بالتطبيق اللامركزي. يؤكد التطبيق مكالمات العقد الذكي من خلال التفاعل مع MetaMask. يمكن للمستخدمين إضافة المنتجات إلى سلة التسوق ويكون التطبيق قادرًا على بدء المعاملات حتى في حالة وجود منتجات متعددة في سلة التسوق. يمكن للمستخدمين الحصول على إشعارات في الوقت الفعلي، وإيصالات المعاملات، وميزات إزالة المنتج من كلا العربتين وكذلك من صفحة قائمة المنتجات. 📥المتطلبات الأساسية - قبل أن نبدأ، تأكد من تثبيت ما يلي على جهازك: Node.js (v14 أو أعلى) npm أو الغزل Truffle أو Hardhat لتطوير العقود الذكية تم تكوين ملحق MetaMask لشبكة اختبار RSK Git للتحكم في الإصدار بيئة تطوير متكاملة مثل VSCode 📥إعداد المشروع 👉إنشاء دليل المشروع يرجى التأكد من تفضيلك لدليل المشروع الرئيسي هذا طوال عملية التطوير والاختبار بأكملها. 👉تهيئة دليل المشروع قم بإنشاء دليل جديد لمشروعك عن طريق تشغيل الأوامر التالية في المحطة الطرفية: mkdir rsk-agri-marketplace cd rsk-agri-marketplace 👉 قم بتهيئة مشروع npm جديد: npm init -y 👉بدء مشروع الكمأة نحن نستخدم Truffle لتجميع وتطوير العقد الذكي، لذا قم بتهيئته من خلال الدليل الجذر: truffle init يؤدي هذا إلى إنشاء البنية الأساسية: • - • - • - • - contracts/ تحتوي على عقود Solidity migrations/ نصوص النشر test/ اختبارات لعقودك truffle-config.js ملف تكوين Truffle 📥تكوين متغيرات البيئة يجب تخزين المعلومات الحساسة مثل المفاتيح الخاصة ومفتاح API الخاص بـ Pimata وما إلى ذلك في ملف .env. 👉 قم بتثبيت dotenv npm install dotenv 👉إنشاء ملف .env في الدليل الجذر، قم بإنشاء ملف .env بالهيكل التالي: REACT_APP_PINATA_API_KEY=Your API Key REACT_APP_PINATA_SECRET_API_KEY=Secret API Key MNEMONIC=12 words mnemonic key RSK_TESTNET_URL=https://public-node.testnet.rsk.co REACT_APP_CONTRACT_ADDRESS=Contract Address يرجى إنشاء ملف بدون مسافات إضافية أو عدم تطابق الأحرف وإلا ستواجه صعوبات لاحقًا. يرجى تذكر هذه لأنك تقوم بتحديث العقد الذكي لاحقًا. احصل على واجهة برمجة تطبيقات Pinata من . .env الخطوة هنا 📥الاتصال بشبكة اختبار RSK 👉تحديث truffle-config.js يمكنك رؤية ملف truffle-config.js الذي تم إنشاؤه بالفعل في دليل مشروعك. ما عليك سوى تحديث الكود حتى نتمكن من التفاعل مع شبكة اختبار RSK من خلاله. require('dotenv').config(); const HDWalletProvider = require('@truffle/hdwallet-provider'); module.exports = { networks: { development: { host: "127.0.0.1", port: 8545, network_id: "*", }, rskTestnet: { provider: () => new HDWalletProvider({ mnemonic: { phrase: process.env.MNEMONIC, }, providerOrUrl: `https://public-node.testnet.rsk.co`, chainId: 31, // RSK Testnet ID pollingInterval: 15000, }), network_id: 31, gas: 2500000, gasPrice: 60000000, confirmations: 2, timeoutBlocks: 60000, skipDryRun: true, }, }, compilers: { solc: { version: "0.8.20", }, }, db: { enabled: false, }, }; 👉قم بتثبيت HDWalletProvider npm install @truffle/hdwallet-provider 📥تطوير العقود الذكية سوف نقوم بإنشاء عقد السوق. 👉 قم بتثبيت عقود OpenZeppelin نحن نستخدم عقود OpenZeppelin لتحسين الأمان والتشغيل السلس لعقدنا الذكي، لذا قم بتثبيته عن طريق تشغيل الأمر التالي في المحطة الطرفية: npm install @openzeppelin/contracts 👉 قم بإنشاء في دليل : Marketplace.sol contracts/ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "@openzeppelin/contracts/utils/Pausable.sol"; contract Marketplace is ReentrancyGuard, Pausable { uint public productCount = 0; struct Product { uint id; address payable seller; string name; string description; string imageHash; // IPFS hash uint price; // Price in tRBTC bool active; } mapping(uint => Product) public products; event ProductCreated( uint id, address seller, string name, string description, string imageHash, uint price, bool active ); event ProductPurchased( uint id, address seller, address buyer, uint price ); event ProductRemoved(uint id, address seller); function createProduct( string memory _name, string memory _description, string memory _imageHash, uint _price ) public whenNotPaused { require(bytes(_name).length > 0, "Name is required"); require(_price > 0, "Price must be positive"); // Price is expected in tRBTC productCount++; products[productCount] = Product( productCount, payable(msg.sender), _name, _description, _imageHash, _price, true ); emit ProductCreated( productCount, msg.sender, _name, _description, _imageHash, _price, true ); } function purchaseProducts(uint[] memory _ids) public payable nonReentrant whenNotPaused { uint totalCost = 0; for (uint i = 0; i < _ids.length; i++) { Product storage _product = products[_ids[i]]; require(_product.id > 0 && _product.id <= productCount, "Invalid product ID"); require(_product.active, "Product is not active"); require(_product.seller != msg.sender, "Seller cannot buy their own product"); totalCost += _product.price; } require(msg.value >= totalCost, "Insufficient funds"); for (uint i = 0; i < _ids.length; i++) { Product storage _product = products[_ids[i]]; (bool success, ) = _product.seller.call{value: _product.price}(""); require(success, "Transfer failed to the seller"); // Emit purchase event (product can be bought again) emit ProductPurchased( _product.id, _product.seller, msg.sender, _product.price ); } } function removeProduct(uint _id) public { Product storage _product = products[_id]; require(_product.id > 0 && _product.id <= productCount, "Invalid product ID"); require(_product.seller == msg.sender, "Only the seller can remove the product"); _product.active = false; // Mark the product as inactive emit ProductRemoved(_id, msg.sender); } function getProduct(uint _id) public view returns (Product memory) { require(_id > 0 && _id <= productCount, "Invalid product ID"); Product memory product = products[_id]; require(product.active, "Product is not available"); return product; } function pause() public { _pause(); } function unpause() public { _unpause(); } } 👉اكتب نص الهجرة في migrations/2_deploy_contracts.js const Marketplace = artifacts.require("Marketplace"); module.exports = function (deployer) { deployer.deploy(Marketplace); }; 👉تجميع العقود ونشرها قم بتشغيل الكود التالي لتجميع العقد من خلال المحطة الطرفية: truffle compile إذا سارت الأمور على ما يرام، فيمكنك رؤية شيء مثل هذا في المحطة الطرفية: قم بتشغيل الأمر التالي في المحطة الطرفية لنشر على شبكة اختبار Rootstock. Marketplace.sol truffle migrate --network rskTestnet تحتاج إلى بعض المبالغ من tRBTC في المحفظة قبل نشر العقد الخاص بك. احصل عليه من صنبور RSK . هنا بعد نجاح العملية، ستظهر لك الرسالة التالية في المحطة الطرفية: ستجد ملف في تذكره، وسوف تقوم بنسخ هذا الملف إلى دليل آخر. Marketplace.json \build\contracts\Marketplace.json تطوير واجهة المستخدم لتطبيق Marketplace dApp الآن بعد أن قمنا بنشر العقود الذكية، سنبني واجهة أمامية جذابة للسوق تسمح للمستخدمين بالتفاعل معها. ستحتوي الواجهة الأمامية على ميزات مثل قوائم المنتجات، وإضافة المنتجات، والشراء، وإضافة/إزالة المنتجات من عربة التسوق، وتتبع المعاملات، وتوفير ملاحظات في الوقت الفعلي مثل الإشعارات وشريط التقدم. 📥تطوير الواجهة الأمامية 👉تهيئة تطبيق React سنستخدم React للواجهة الأمامية. قم بتشغيل تطبيق React جديد في دليل المشروع. npx create-react-app client انتقل إلى دليل العميل. cd client تثبيت Web3 وBootstrap لواجهة المستخدم npm install web3 bootstrap 👉هيكل المشروع ستحتاج إلى الهيكل الخاص بالواجهة الأمامية كما هو موضح في الشكل 1. 👉إعداد Web3 في src/utils/Marketplace.json للتفاعل مع العقد الذكي، سنقوم باستيراد ABI (واجهة التطبيق الثنائية). انسخ ABI من دليل Truffle إلى المجلد كما هو مذكور في . Marketplace.json build/contracts client/src/utils/ الخطوة يوجد إعداد Web3 في ملف قم بتنزيله من وضعه في الدليل المناسب كما هو موضح في الشكل 1. App.js GitHub 👉 إشعارات في الوقت الفعلي وأشرطة التقدم بالنسبة للإشعارات في الوقت الفعلي، سندمج مكتبة مثل . يمكنك أيضًا استخدام لأشرطة التقدم. react-toastify react-bootstrap تثبيت React Toastify في دليل client npm install react-toastify 👉قم بتثبيت Axios لطلبات HTTP (إلى واجهة برمجة تطبيقات Pinata): npm install axios حسنًا، يُرجى الآن تنزيل كافة مكونات الواجهة الأمامية من مجلد العميل (بما في ذلك المجلد والملفات) في . ووضعها في الدليل المناسب. مستودع GitHub 📥اللمسات النهائية والتفاعل مع تطبيقك 👉الآن، يمكنك التفاعل مع تطبيقك اللامركزي. يمكنك تشغيل تطبيق React الخاص بك باستخدام الأمر التالي في المحطة الطرفية: npm start سيتم فتح المتصفح الافتراضي تلقائيًا. يرجى التأكد من تثبيت ملحق متصفح MetMask وتكوين شبكة اختبار RSK بشكل صحيح (يمكنك اتباع دليل المشروع لاختيار الشبكة الصحيحة ). هنا الآن، يستدعي تطبيق React ملحق محفظة MetaMask، يرجى تأكيد المكالمة. ثم سيعرض المحفظة المتصلة في الواجهة الرئيسية كما هو موضح في الشكل التالي. توفر لك الواجهة الأمامية العديد من الميزات. يمكنك إضافة/إزالة المنتجات. في كل مرة، سيُطلب منك تأكيد المكالمة في ملحق محفظة MetaMask. تحقق من ملف GIF التالي: حسنًا، يمكنك الآن اختبار ما إذا كان التطبيق اللامركزي يعالج المعاملات المضافة إلى عربة التسوق بشكل صحيح أم لا. يمكنك الاطلاع على سجل المعاملات التفصيلي ضمن قسم "سجل المعاملات" مع جميع التفاصيل الفنية. بمجرد اكتمال عملية الشراء، يتم إرسال الأموال إلى المالك الذي أضاف المنتجات إلى التطبيق اللامركزي. دعونا نختبر التطبيق معًا: مبروك! لقد نجحنا في تطوير واختبار التطبيق اللامركزي في شبكة اختبار RSK. يمكنك تحويله إلى شبكة RSK الرئيسية عن طريق إضافة الميزات التي تريدها. ما عليك سوى تعديل التعليمات البرمجية أينما ورد ذكر شبكة الاختبار والتحقق أيضًا من هنا إذا كنت تتعجل في بناء التطبيق الجاهز للإنتاج. وثائق المشروع 📥التحديات المحتملة والمستقبلية: سيكون النهج الجديد لبدء السوق الزراعية هو الذي يتضمن العديد من العمليات مثل تسليم المنتج واستلامه وما إلى ذلك. وبدون معرفة المشترين والبائعين بالتفصيل، فقد يؤدي ذلك إلى خلق مشكلات تتعلق بالثقة. والتحدي الآخر هو أنه لا يزال في مرحلة تجريبية، ولا نعرف كيف يتصرف المستهلكون مع هذه التكنولوجيا المتطورة. لذا، فإن التعليم والتدريب ضروريان لتمكين المزارعين والمستهلكين على حد سواء من تبني التقنيات الجديدة. كما أن التعاون الكافي يشكل العامل الرئيسي في تطوير سوق لامركزية مستدامة للمنتجات الزراعية. خاتمة: لقد نجحنا في بناء سوق زراعي لامركزي على شبكة اختبار Rootstock (RSK). لقد تم اعتبار الأمان أولوية، ولهذا السبب تم اتخاذ العديد من التدابير لحماية كود العقد الذكي باستخدام عقود OpenZeppelin. يتكون التطبيق اللامركزي الذي تم اختباره من جميع الميزات الضرورية تقريبًا التي يجب أن يتمتع بها السوق اللامركزي البسيط، ولكن يمكنك تحسينه بمزيد من الميزات إذا كنت تخطط لإطلاق التطبيق على الشبكة الرئيسية لـ Rootstock. أيضًا، ضع الأمان في الاعتبار للتأكد من أن كل شيء يعمل كما هو مقصود وبسلاسة. لقد حاولنا الاستفادة من ميزات معالجة المعاملات السريعة التي تقدمها Rootstock مع رسوم المعاملات المنخفضة للمضي قدمًا في جميع المعاملات التي ستحل مشكلة الازدحام الشهيرة في Bitcoin. بالطبع، تواجه هذه الأنواع من الأسواق اللامركزية العديد من المشكلات، ولكن بما أننا نسعى بشكل طبيعي إلى الحرية، فيمكننا أن نأمل في العثور على سوق أكثر لامركزية في المستقبل.