Teknologiak gizakiaren zerbitzura egon behar du. Blockchain teknologiak, dagoeneko sektore asko irauli dituenak, nekazaritza arloa ere eraldatu dezake. Teknologia deszentralizatu hau hartzeko joera nagusira eramateko, sinplifikatu egin beharko genuke publiko orokorrarengana iristeko, erabiltzaile zabalagoetan sartu ahal izateko, azken finean, erabilera kasuak areagotuz.
Tutorial honetan, erabiltzaileek Rootstock (RSK) blockchain sarean nekazaritza produktuak erosi eta saltzeko aukera ematen duen aplikazio deszentralizatua (dApp) eraikiko dugu. Helburu nagusia blockchain sarean exekutatzen den dApp bat eraikitzea da. Edozein erabiltzailek produktuak erraz gehi ditzakete nekazaritza produktuak salduz gizakiaren gehiegizko esku-hartzerik gabe.
Hasieran, aplikazioa Rootstock-en testnet-ean probatu zen, eta ia ekoizpenerako prest dago (doikuntza txikiak behar ziren Rootstock-en sare nagusira aldatzeko). Proiektua GitHub-en kargatuta dago, beraz, biltegia klonatu dezakezu zuk zeuk probatzeko.
Horretarako, nahiago dut Readme.md
GitHub -en. Baina, tutorial honetan, sakontzen saiatzen gara edozein erabiltzailek bere dApp-a eraiki dezan tutoriala urratsez urrats ulertzeko erraztasunarekin. Frontend kodea GitHub biltegitik deskargatu eta dagokion direktorioan gehitzea proposatzen dizugu. Proiektua konfiguratu, kontratu adimendunak zabaldu eta denbora errealeko funtzioekin frontend interaktibo bat sortu arte landuko dugu.
Hasi baino lehen, AgriMarket izeneko dApp bat eraiki nahi dugu, honako ezaugarri hauek izango dituena:
👉Sortu Proiektuen Direktorioa
Mesedez, ziurtatu proiektu nagusi honen direktorioa nahiago duzula gure garapen eta proba prozesu osoan zehar.
👉Abiaraztu Proiektuen Direktorioa
Sortu direktorio berri bat zure proiekturako komando hauek exekutatuta terminalean:
mkdir rsk-agri-marketplace cd rsk-agri-marketplace
👉Hasi npm proiektu berri bat:
npm init -y
👉Boilurra Proiektua hasieratu
Truffle erabiltzen ari gara kontratu adimenduna konpilatzeko eta garatzeko, beraz, hasieratu erroko direktorioaren bidez:
truffle init
Honek oinarrizko egitura sortzen du: • contracts/
- Solidity kontratuak ditu • migrations/
- Inplementazio scriptak • test/
- Zure kontratuen probak • truffle-config.js
- Truffle konfigurazio fitxategia
Informazio sentikorra bezalako gako pribatuak, Pimata API gakoa eta abar .env fitxategi batean gorde behar dira.
👉Instalatu dotenv
npm install dotenv
👉Sortu .env fitxategi bat
Erroko direktorioan, sortu .env fitxategi bat egitura honekin:
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
Mesedez, sortu .env
fitxategia espazio gehigarririk edo karaktere desegokirik gabe, bestela zailtasunak izango dituzu geroago. Mesedez, gogoratu Urrats hau geroago kontratu adimenduna eguneratzen ari zarelako. Lortu Pinata APIa hemendik .
👉Eguneratu truffle-config.js
Dagoeneko sortutako truffle-config.js ikus dezakezu zure proiektuaren direktorioa. Kodea eguneratu besterik ez dago RSK testnet-arekin elkarreragin ahal izateko.
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, }, };
👉Instalatu HDWalletProvider
npm install @truffle/hdwallet-provider
Marketplace kontratua sortuko dugu.
👉Instalatu OpenZeppelin Kontratuak
OpenZeppelin kontratuak erabiltzen ari gara gure kontratu adimendunaren segurtasuna eta funtzionamendu ona hobetzeko, beraz, instalatu komando hau terminalean exekutatuz:
npm install @openzeppelin/contracts
👉Sortu Marketplace.sol
contracts/
direktorioan:
// 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(); } }
👉Idatzi Migration Scripta migrations/2_deploy_contracts.js
const Marketplace = artifacts.require("Marketplace"); module.exports = function (deployer) { deployer.deploy(Marketplace); };
👉Kontratuak osatu eta zabaldu
Exekutatu honako kodea terminalaren bidez kontratua osatzeko:
truffle compile
Dena ondo badoa, honelako zerbait ikus dezakezu terminalean:
Exekutatu komando hau terminalean Marketplace.sol
Rootstock-en testnet-ean zabaltzeko.
truffle migrate --network rskTestnet
tRBTC kopuru batzuk behar dituzu zorroan zure kontratua zabaldu aurretik. Eskuratu hemen RSK txorrotatik.
Prozesu arrakastatsuaren ondoren, mezua ikusiko duzu terminal honetan:
Marketplace.json
fitxategia aurkituko duzu \build\contracts\Marketplace.json
gogoratu, fitxategi hau beste direktorio batean kopiatuko duzu.
Marketplace dApp-rako frontend garapena
Kontratu adimendunak zabaldu ditugunez, merkaturako frontend erakargarri bat eraikiko dugu, erabiltzaileek harekin elkarreragin dezaten. Frontendak produktuen zerrendak, produktuak gehitzea, erostea, produktuak gehitzea/kentzea saskian, transakzioen jarraipena egitea eta denbora errealeko iritzia ematea bezalako ezaugarriak izango ditu, hala nola jakinarazpenak eta aurrerapen-barra.
👉Hasi React aplikazioa
Frontenderako React erabiliko dugu.
Hasieratu React aplikazio berri bat proiektuaren direktorioan.
npx create-react-app client
Nabigatu bezeroen direktoriora.
cd client
Instalatu Web3 eta Bootstrap UI-rako
npm install web3 bootstrap
👉Proiektuaren Egitura
Frontendaren egitura beharko duzu 1. Irudian erakusten den moduan.
👉Web3 konfigurazioa src/utils/Marketplace.json
en
Kontratu adimendunarekin elkarreragiteko, ABI (Application Binary Interface) inportatuko dugu.
Marketplace.json
ABI zure Truffle build/contracts
direktoriotik client/src/utils/
karpetara Urratsean aipatu bezala.
App.js
fitxategian dago. Deskargatu GitHub- etik eta jarri direktorio egokian 1. Irudian erakusten den moduan.
👉 Denbora errealeko jakinarazpenak eta aurrerapen-barrak
Denbora errealeko jakinarazpenetarako, liburutegi moduko react-toastify
bat integratuko dugu. Era berean, react-bootstrap
erabil dezakezu aurrerapen-barretarako.
Instalatu React Toastify client
direktorioan
npm install react-toastify
👉Instalatu Axios HTTP eskaeretarako (Pinata-ren APIrako):
npm install axios
Ongi da, orain deskargatu Frontend osagai guztiak GitHub biltegiko bezero karpetatik (karpeta+fitxategiak barne). Eta jarri itzazu dagokion direktorioan.
👉Orain, zure dApp-arekin elkarreragin dezakezu. Zure erreakzio aplikazioa exekutatu dezakezu komando hau terminalean erabiliz:
npm start
Nabigatzaile lehenetsia automatikoki irekiko du. Mesedez, ziurtatu MetMask arakatzailearen luzapena instalatuta eta RSK testnet-a behar bezala konfiguratuta duzula (proiektuaren gida jarraitu dezakezu sare egokia hautatzeko hemen ).
Orain, erreakzionatzeko aplikazioak MetaMask zorroaren luzapena deitzen du, berretsi deia. Ondoren, konektatutako zorroa erakutsiko du interfaze nagusian hurrengo irudian erakusten den moduan.
Frontend-ak funtzio ugari eskaintzen dizkizu. Produktuak gehitu/kendu ditzakezu. Aldi bakoitzean, deia berresteko eskatuko zaizu MetaMask zorroaren luzapenean. Egiaztatu gif hau:
Beno, orain dApp-ek saskian gehitutako transakzioak behar bezala prozesatzen dituen edo ez probatu dezakezu. Transakzioen historia zehatza ikus dezakezu "Transakzioen historia" atalean xehetasun tekniko guztiekin. Erosketa amaitutakoan, funtsa dApp-era produktuak gehitu dituen jabeari bidaltzen zaio.
Probatu dezagun aplikazioa elkarrekin:
Zorionak! DApp-a arrakastaz garatu eta probatu dugu RSK testnet-en. RSK sare nagusira alda dezakezu nahi dituzun funtzioak gehituz. Egokitu kodeak testnet aipatzen den lekuan eta egiaztatu proiektuaren dokumentazioa hemen produkziorako prest dagoen aplikazioa eraikitzera presaka joaten bazara.
Nekazaritza-merkatua abiarazteko ikuspegi berria izango da, hainbat prozesu barne hartzen dituena, besteak beste, produktuen entrega, bilketa, etab. Erosleak eta saltzaileak zehatz-mehatz ezagutu gabe, konfiantza arazoak sor ditzake. Beste erronka bat da oraindik fase esperimentalean dagoela, eta ez dakigu kontsumitzaileek nola jokatzen duten eboluzionatzen ari den teknologia honen aurrean.
Beraz, hezkuntza eta prestakuntza ezinbestekoak dira bai nekazariak bai kontsumitzaileak teknologia berriak hartzeko. Era berean, kolaborazio nahikoak dira nekazaritzako produktuen merkatu deszentralizatu iraunkor bat garatzeko funtsezko faktoreak.
Arrakastaz eraiki genuen nekazaritza-merkatu deszentralizatua Rootstock (RSK) testnet-ean. Segurtasuna lehentasun gisa hartu da, horregatik hainbat neurri hartzen dira OpenZeppelin kontratuak erabiliz smartcontract kodea babesteko. Probatu dApp-ek merkatu deszentralizatu sinple batek izan beharko lituzkeen ia beharrezko eginbide guztiak ditu, baina funtzio gehiagorekin hobetu dezakezu aplikazioa Rootstock-en sare nagusian abiarazteko asmoa baduzu. Gainera, kontuan izan segurtasuna dena nahi bezala eta ondo funtzionatzen duela ziurtatzeko.
Rootstock-en transakzio bizkorrak prozesatzeko funtzioak erabiltzen saiatu gara transakzio kuota baxuekin Bitcoin-en pilaketa arazo ezaguna konponduko duen transakzio guztiarekin aurrera egiteko. Jakina, merkatu deszentralizatu mota hauek arazo askori aurre egin behar diete, baina askatasuna naturalki bilatzen dugunez, etorkizunean merkatu deszentralizatuago bat aurkitzea espero dezakegu.