Technologijos turi tarnauti žmonijai. Blockchain technologija, kuri jau padarė revoliuciją daugelyje sektorių, taip pat gali pakeisti žemės ūkio sritį. Kad ši decentralizuota technologija taptų plačiai paplitusi, turėtume ją supaprastinti, kad pasiektume plačiąją visuomenę, kad galėtume pasiekti platesnius vartotojus ir galiausiai padidinti naudojimo atvejų skaičių.
Šioje pamokoje mes sukursime decentralizuotą programą (dApp), kuri leidžia vartotojams pirkti ir parduoti žemės ūkio produktus Rootstock (RSK) blokų grandinės tinkle. Pagrindinis tikslas yra sukurti „dApp“, kuri veiktų „blockchain“ tinkle. Bet kokie vartotojai gali lengvai pridėti produktų, kad užsidirbtų parduodami savo žemės ūkio produktus be pernelyg didelio žmogaus įsikišimo.
Iš pradžių programa buvo išbandyta „Rootstock“ testavimo tinkle ir ji yra beveik paruošta gamybai (tereikia nedidelių pakeitimų, kad perjungtumėte į „Rootstock“ pagrindinį tinklą). Projektas jau įkeltas į „GitHub“, todėl galite tiesiog klonuoti saugyklą ir patys jį išbandyti.
Dėl to man labiau patinka Readme.md
„GitHub“ . Tačiau šioje mokymo programoje mes stengiamės nuodugniai vadovautis, kad bet kuris vartotojas galėtų sukurti savo dApp, kad būtų lengviau suprasti mokymo programą. Galime pasiūlyti atsisiųsti „Frontend“ kodą iš „GitHub“ saugyklos ir įtraukti jį į atitinkamą katalogą. Mes apimsime viską nuo projekto nustatymo iki išmaniųjų sutarčių diegimo ir interaktyvios sąsajos su realiuoju laiku funkcijomis sukūrimo.
Prieš pradėdami, mes siekiame sukurti dApp, pavadintą AgriMarket, kuri turėtų turėti šias funkcijas:
👉Sukurkite projekto katalogą
Įsitikinkite, kad per visą mūsų kūrimo ir testavimo procesą teikiate pirmenybę šio pagrindinio projekto katalogui.
👉Inicijuokite projekto katalogą
Sukurkite naują savo projekto katalogą terminale vykdydami šias komandas:
mkdir rsk-agri-marketplace cd rsk-agri-marketplace
👉Inicijuoti naują npm projektą:
npm init -y
👉Inicijuokite triufelių projektą
Mes naudojame Truffle, kad sudarytume ir plėtotume išmaniąją sutartį, todėl inicijuokite ją naudodami šakninį katalogą:
truffle init
Taip sukuriama pagrindinė struktūra: • contracts/
– yra solidumo sutartys • migrations/
– diegimo scenarijai • test/
– sutarčių testai • truffle-config.js
– triufelių konfigūracijos failas
Skelbtina informacija, pvz., privatūs raktai, Pimata API raktas ir kt., turėtų būti saugoma .env faile.
👉Įdiekite dotenv
npm install dotenv
👉Sukurkite .env failą
Šakniniame kataloge sukurkite .env failą su tokia struktūra:
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
Sukurkite .env
failą be papildomų tarpų ar simbolių neatitikimų, kitaip vėliau susidursite su sunkumais. Prisiminkite šį veiksmą , nes vėliau atnaujinsite išmaniąją sutartį. Gaukite Pinata API iš čia .
👉Atnaujinkite truffle-config.js
Jau sukurtą truffle-config.js galite pamatyti savo projekto kataloge. Tiesiog atnaujinkite kodą, kad galėtume per jį bendrauti su RSK testnetu.
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, }, };
👉Įdiekite HDWalletProvider
npm install @truffle/hdwallet-provider
Mes sudarysime prekyvietės sutartį.
👉Įdiekite OpenZeppelin sutartis
Mes naudojame OpenZeppelin sutartis, kad padidintume savo išmaniosios sutarties saugumą ir sklandų veikimą, todėl įdiekite ją terminale paleisdami šią komandą:
npm install @openzeppelin/contracts
👉Sukurkite Marketplace.sol
contracts/
kataloge:
// 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(); } }
👉Parašykite perkėlimo scenarijų migrations/2_deploy_contracts.js
const Marketplace = artifacts.require("Marketplace"); module.exports = function (deployer) { deployer.deploy(Marketplace); };
👉Sudarykite ir įdiekite sutartis
Norėdami sudaryti sutartį per terminalą, paleiskite šį kodą:
truffle compile
Jei viskas vyksta teisingai, terminale galite pamatyti kažką panašaus į tai:
Vykdykite šią komandą terminale, kad įdiegtumėte Marketplace.sol
į šaknų tinklo testą.
truffle migrate --network rskTestnet
Prieš įgyvendindami sutartį, piniginėje turite turėti tam tikrą tRBTC kiekį. Gaukite jį iš RSK maišytuvo čia .
Po sėkmingo proceso pamatysite pranešimą šiame terminale:
Rinkmeną Marketplace.json
rasite aplanke \build\contracts\Marketplace.json
Atsiminkite, nukopijuosite šį failą į kitą katalogą.
Frontend kūrimas, skirtas Marketplace dApp
Dabar, kai įdiegėme išmaniąsias sutartis, ketiname sukurti patrauklią rinkos sąsają, kuri leistų vartotojams su ja bendrauti. Frontend turės tokias funkcijas kaip produktų sąrašai, produktų pridėjimas, pirkimas, produktų įtraukimas / pašalinimas iš krepšelio, operacijų stebėjimas ir atsiliepimų realiuoju laiku teikimas, pvz., pranešimai ir eigos juosta.
👉Inicijuoti React programą
Priekinei sistemai naudosime „React“.
Projekto kataloge inicijuokite naują „React“ programą.
npx create-react-app client
Eikite į kliento katalogą.
cd client
Įdiekite „Web3“ ir „Bootstrap“, skirtą vartotojo sąsajai
npm install web3 bootstrap
👉Projekto struktūra
Jums reikės priekinės dalies struktūros, kaip parodyta 1 paveiksle.
👉Web3 sąranka src/utils/Marketplace.json
Norėdami sąveikauti su išmaniąja sutartimi, importuosime ABI (Application Binary Interface).
Marketplace.json
ABI iš savo Truffle build/contracts
katalogo į aplanką client/src/utils/
kaip nurodyta veiksme .
App.js
faile. Atsisiųskite jį iš „GitHub“ ir įdėkite jį į atitinkamą katalogą, kaip parodyta 1 paveiksle.
👉 Realaus laiko pranešimai ir eigos juostos
Norėdami gauti pranešimus realiuoju laiku, integruosime į biblioteką panašią react-toastify
. Taip pat eigos juostoms galite naudoti react-bootstrap
.
Įdiekite „React Toastify“ client
kataloge
npm install react-toastify
👉Įdiekite HTTP užklausų „Axios“ (į „Pinata“ API):
npm install axios
Gerai, dabar atsisiųskite visus „Frontend“ komponentus iš „GitHub“ saugyklos kliento aplanko (įskaitant aplanką + failus). Ir įdėkite juos į atitinkamą katalogą.
👉Dabar galite bendrauti su savo dApp. Galite paleisti savo react programą naudodami šią komandą terminale:
npm start
Jis automatiškai atidarys numatytąją naršyklę. Įsitikinkite, kad įdiegėte MetMask naršyklės plėtinį ir tinkamai sukonfigūravote RSK testnet (galite vadovautis projekto vadovu, norėdami pasirinkti tinkamą tinklą čia ).
Dabar „React“ programa iškviečia „MetaMask“ piniginės plėtinį, patvirtinkite skambutį. Tada pagrindinėje sąsajoje bus rodoma prijungta piniginė, kaip parodyta toliau pateiktame paveikslėlyje.
Frontend siūlo daugybę funkcijų. Galite pridėti/pašalinti produktus. Kiekvieną kartą jūsų bus paprašyta patvirtinti skambutį „MetaMask“ piniginės plėtinyje. Patikrinkite šį gif failą:
Na, dabar galite patikrinti, ar „dApp“ tinkamai apdoroja į krepšelį įtrauktas operacijas, ar ne. Išsamią operacijų istoriją galite pamatyti skiltyje „Operacijų istorija“ su visa technine informacija. Kai pirkimas bus baigtas, fondas siunčiamas savininkui, kuris pridėjo produktus prie dApp.
Išbandykime programą kartu:
Sveikiname! Mes sėkmingai sukūrėme ir išbandėme dApp RSK testų tinkle. Galite perjungti jį į RSK pagrindinį tinklą pridėdami norimas funkcijas. Tiesiog pakoreguokite kodus visur, kur minimas „testnet“, taip pat patikrinkite projekto dokumentaciją čia, jei skubate kurti gamybai paruoštos programos.
Tai bus naujas būdas inicijuoti žemės ūkio rinką, apimančią kelis procesus, pvz., produktų pristatymą, atsiėmimą ir tt Nežinant išsamiai pirkėjų ir pardavėjų, gali kilti pasitikėjimo problemų. Kitas iššūkis yra tai, kad ji vis dar yra eksperimentinėje fazėje, ir mes nežinome, kaip vartotojai elgiasi su šia besivystančia technologija.
Taigi švietimas ir mokymas yra būtini ir ūkininkams, ir vartotojams, kad galėtų pritaikyti naujas technologijas. Be to, pakankamas bendradarbiavimas yra pagrindiniai veiksniai kuriant tvarią decentralizuotą žemės ūkio produktų rinką.
Sėkmingai sukūrėme decentralizuotą žemės ūkio rinką „Rootstock“ (RSK) testavimo tinkle. Saugumas buvo laikomas prioritetu, todėl imamasi kelių priemonių, siekiant apsaugoti išmaniųjų sutarčių kodą naudojant OpenZeppelin sutartis. Išbandytą „dApp“ sudaro beveik visos būtinos funkcijos, kurias turėtų turėti paprasta decentralizuota rinka, tačiau galite ją patobulinti naudodami daugiau funkcijų, jei planuojate paleisti programą „Rootstock“ pagrindiniame tinkle. Be to, nepamirškite saugumo, kad įsitikintumėte, jog viskas veikia taip, kaip numatyta ir sklandžiai.
Mes bandėme panaudoti „Rootstock“ greito operacijų apdorojimo ypatybes su mažais operacijų mokesčiais, kad galėtume tęsti visas operacijas, kurios išspręstų „Bitcoin“ perkrovos problemą. Žinoma, tokios decentralizuotos prekyvietės turi susidurti su daugybe problemų, tačiau natūraliai siekdami laisvės galime tikėtis, kad ateityje rasime labiau decentralizuotą prekyvietę.