Blokcheyn smart-kontraktlari uchun frontend hodisa tinglovchisini yaratish bo'yicha to'liq qo'llanma. Kontrakt holati o'zgarishlarini real vaqt rejimida kuzatish, Web3.js yoki ethers.js'ni integratsiya qilish, hodisa ma'lumotlarini dekodlash va ilova interfeysini yangilashni o'rganing.
Frontend Blokcheyn Smart-kontrakt Hodisa Tinglovchisi: Kontrakt Holatini Kuzatish
Markazlashtirilmagan ilovalar (DApps) ko'pincha asosiy smart-kontrakt holatidagi o'zgarishlarni aks ettirish uchun real vaqt rejimida yangilanishlarni talab qiladi. Aynan shu yerda hodisa tinglovchilari (event listeners) ishga tushadi. Smart-kontraktlar tomonidan chiqarilgan hodisalarni kuzatib borish orqali frontend ilovalari holat o'zgarishlariga munosabat bildirishi va foydalanuvchilarga eng so'nggi ma'lumotlarni taqdim etishi mumkin. Ushbu qo'llanma amaliyot va eng yaxshi amaliyotlarga e'tibor qaratgan holda, blokcheyn smart-kontraktlari uchun frontend hodisa tinglovchisini yaratish bo'yicha to'liq ma'lumot beradi.
Smart-kontrakt Hodisalari Nima?
Solidity kabi tillarda yozilgan smart-kontraktlar, kontrakt ichida ma'lum harakatlar sodir bo'lganda hodisalarni chiqarishi (emit) mumkin. Ushbu hodisalar tashqi ilovalarga holat o'zgarishi sodir bo'lganligi haqida signal beruvchi bildirishnoma mexanizmi bo'lib xizmat qiladi. Ularni blokcheynda doimiy ravishda yozib olinadigan jurnal yozuvlari (log entries) deb o'ylang. Hodisalar o'zgarish haqida ma'lumotni o'z ichiga oladi, bu esa ilovalarga mos ravishda munosabat bildirish imkonini beradi.
Masalan, oddiy token kontraktini ko'rib chiqaylik. U hisoblar o'rtasida tokenlar o'tkazilganda hodisa chiqarishi mumkin. Ushbu hodisa odatda jo'natuvchining manzili, qabul qiluvchining manzili va o'tkazilgan miqdorni o'z ichiga oladi. Frontend ilovasi ushbu hodisani tinglab, foydalanuvchi balansini real vaqt rejimida yangilashi mumkin.
Nima uchun Hodisa Tinglovchilaridan Foydalanish Kerak?
Blokcheyndan holat o'zgarishlarini so'rab turish (polling) samarasiz va ko'p resurs talab qiladi. Hodisa tinglovchilari ilovalarga passiv ravishda bildirishnomalarni kutish imkonini berib, ancha qulay va samarali yechimni taqdim etadi. Bu blokcheyndagi yuklamani kamaytiradi va DApp'ning javob berish tezligini yaxshilaydi.
Hodisa tinglovchilaridan foydalanishning asosiy afzalliklari:
- Real vaqtdagi yangilanishlar: Foydalanuvchilarga kontrakt holati o'zgarishlari haqida darhol ma'lumot berish.
- Samaradorlikni oshirish: Blokcheyndan doimiy so'rov yuborish zaruratini kamaytirish.
- Yaxshilangan foydalanuvchi tajribasi: Ancha dinamik va sezgir ilova yaratish.
- Gaz xarajatlarini kamaytirish: Blokcheynda keraksiz o'qish operatsiyalaridan qochish.
Asboblar va Texnologiyalar
Frontend hodisa tinglovchilarini yaratish uchun bir nechta asboblar va kutubxonalardan foydalanish mumkin. Eng mashhur variantlar quyidagilardir:
- Web3.js: Ethereum nodlari va smart-kontraktlar bilan ishlash imkonini beruvchi JavaScript kutubxonasi. U blokcheyn ma'lumotlariga kirish, tranzaksiyalarni yuborish va hodisalarni tinglash uchun keng qamrovli API taqdim etadi.
- Ethers.js: Ethereum bilan ishlash uchun yana bir mashhur JavaScript kutubxonasi. U o'zining soddaligi, xavfsizligi va ishlash samaradorligi bilan tanilgan.
- Infura/Alchemy: Ethereum tarmog'iga ishonchli kirishni taklif qiluvchi infratuzilma provayderlari. Ular blokcheyn ma'lumotlarini o'qish va tranzaksiyalarni yuborish uchun API'lar taqdim etib, o'z Ethereum nodingizni ishga tushirish zaruratini yo'q qiladi.
- WebSockets: Mijoz va server o'rtasida real vaqt rejimida ikki tomonlama aloqani ta'minlaydigan aloqa protokoli. WebSockets ko'pincha hodisa bildirishnomalarini frontend'ga yetkazish uchun ishlatiladi.
Frontend Hodisa Tinglovchisini Yaratish: Qadamma-qadam Qo'llanma
Ushbu bo'limda Web3.js yoki ethers.js yordamida frontend hodisa tinglovchisini yaratish bosqichlari ko'rsatilgan.
1-qadam: Ishlanma Muhitini Sozlash
Boshlashdan oldin, quyidagilar o'rnatilganligiga ishonch hosil qiling:
- Node.js: JavaScript ishga tushirish muhiti.
- npm (Node Package Manager) yoki yarn: Bog'liqliklarni (dependencies) o'rnatish uchun paket menejeri.
- Kod muharriri: Visual Studio Code, Sublime Text yoki siz afzal ko'rgan boshqa har qanday muharrir.
Yangi loyiha katalogini yarating va uni npm yoki yarn bilan ishga tushiring:
mkdir my-dapp
cd my-dapp
npm init -y
Yoki yarn yordamida:
mkdir my-dapp
cd my-dapp
yarn init -y
2-qadam: Bog'liqliklarni O'rnatish
Web3.js yoki ethers.js'ni, shuningdek, boshqa kerakli bog'liqliklarni o'rnating. Masalan, muhit o'zgaruvchilarini (environment variables) boshqarish uchun kutubxona kerak bo'lishi mumkin.
npm yordamida:
npm install web3 dotenv
yarn yordamida:
yarn add web3 dotenv
Yoki ethers.js uchun:
npm yordamida:
npm install ethers dotenv
yarn yordamida:
yarn add ethers dotenv
3-qadam: Web3 Provayderingizni Sozlash
Ethereum tarmog'iga ulanish uchun Web3 provayderini sozlashingiz kerak. Buni Infura, Alchemy yoki mahalliy Ethereum nodi (masalan, Ganache) yordamida amalga oshirish mumkin.
Loyiha katalogingizda `.env` faylini yarating va Infura yoki Alchemy API kalitingizni qo'shing:
INFURA_API_KEY=YOUR_INFURA_API_KEY
Keyin, JavaScript faylingizda Web3 provayderini sozlang:
Web3.js yordamida:
require('dotenv').config();
const Web3 = require('web3');
const infuraApiKey = process.env.INFURA_API_KEY;
const web3 = new Web3(new Web3.providers.WebsocketProvider(`wss://mainnet.infura.io/ws/v3/${infuraApiKey}`));
Ethers.js yordamida:
require('dotenv').config();
const { ethers } = require('ethers');
const infuraApiKey = process.env.INFURA_API_KEY;
const provider = new ethers.providers.WebSocketProvider(`wss://mainnet.infura.io/ws/v3/${infuraApiKey}`);
Eslatma: Agar test tarmog'idan foydalanayotgan bo'lsangiz, `mainnet`'ni mos tarmoq bilan almashtiring (masalan, `ropsten`, `rinkeby`, `goerli`).
4-qadam: Kontrakt ABI va Manzilini Olish
Smart-kontraktingiz bilan ishlash uchun sizga uning Dasturiy Ikkilik Interfeysi (Application Binary Interface - ABI) va manzili kerak bo'ladi. ABI - bu kontraktning funksiyalari va hodisalarini tavsiflovchi JSON fayli. Manzil - bu kontraktning blokcheyndagi joylashuvi.
ABI'ni Solidity kompilyatori chiqishidan olishingiz mumkin. Manzil kontraktni joylashtirganingizdan so'ng ko'rsatiladi.
ABI'ni JSON faylida (masalan, `MyContract.json`) va manzilni `.env` faylingizda saqlang:
CONTRACT_ADDRESS=0xYourContractAddress...
5-qadam: Kontrakt Nusxasini Yaratish
ABI va manzildan foydalanib, JavaScript faylingizda kontrakt nusxasini (instance) yarating:
Web3.js yordamida:
const contractAddress = process.env.CONTRACT_ADDRESS;
const contractABI = require('./MyContract.json').abi;
const myContract = new web3.eth.Contract(contractABI, contractAddress);
Ethers.js yordamida:
const contractAddress = process.env.CONTRACT_ADDRESS;
const contractABI = require('./MyContract.json').abi;
const myContract = new ethers.Contract(contractAddress, contractABI, provider);
6-qadam: Hodisalarni Tinglash
Endi siz smart-kontraktingiz tomonidan chiqarilgan hodisalarni tinglashni boshlashingiz mumkin. Hodisalarga obuna bo'lish uchun kontrakt nusxangizning `events` xususiyatidan foydalaning.
Web3.js yordamida:
myContract.events.MyEvent({
filter: {myIndexedParam: [20,23]}, // Indekslangan parametrlar yordamida ixtiyoriy filtr.
fromBlock: 'latest' // Eng so'nggi blokdan tinglashni boshlash.
}, function(error, event){
if(!error)
{console.log(event);}
else
{console.log(error);}
})
.on('data', function(event){
console.log(event);
})
.on('changed', function(event){
// hodisani mahalliy ma'lumotlar bazasidan o'chirish
})
.on('error', console.error);
Yoki async/await yordamida:
myContract.events.MyEvent({
filter: {myIndexedParam: [20,23]}, // Indekslangan parametrlar yordamida ixtiyoriy filtr.
fromBlock: 'latest' // Eng so'nggi blokdan tinglashni boshlash.
})
.on('data', async function(event){
console.log(event);
// Hodisa ma'lumotlarini shu yerda qayta ishlang, masalan, interfeysni yangilang
try {
// Misol: DApp'ingizning boshqa qismi bilan o'zaro aloqada bo'ling.
// await someOtherFunction(event.returnValues);
} catch (error) {
console.error("Hodisa qayta ishlanishida xatolik:", error);
}
})
.on('changed', function(event){
// hodisani mahalliy ma'lumotlar bazasidan o'chirish
})
.on('error', console.error);
Ethers.js yordamida:
myContract.on("MyEvent", (param1, param2, event) => {
console.log("MyEvent hodisasi chiqarildi!");
console.log("Param1:", param1);
console.log("Param2:", param2);
console.log("Hodisa Ma'lumotlari:", event);
// Hodisa ma'lumotlarini shu yerda qayta ishlang, masalan, interfeysni yangilang
});
Ikkala misolda ham `MyEvent`'ni tinglamoqchi bo'lgan hodisa nomi bilan almashtiring. Hodisa chiqarilganda qayta chaqiruv funksiyasi (callback function) ishga tushadi. Hodisa ma'lumotlariga `event` ob'ekti orqali kirishingiz mumkin.
7-qadam: Hodisa Ma'lumotlarini Qayta Ishlash
`event` ob'ekti hodisa haqidagi ma'lumotlarni, jumladan, unga uzatilgan argumentlar, blok raqami va tranzaksiya xeshini o'z ichiga oladi. Siz ushbu ma'lumotlardan ilovangiz interfeysini yangilash yoki boshqa amallarni bajarish uchun foydalanishingiz mumkin.
Masalan, agar hodisangiz foydalanuvchi balansini o'z ichiga olsa, siz frontend'da balans ko'rinishini yangilashingiz mumkin:
// Hodisani qayta ishlovchi ichida
const balance = event.returnValues.balance; // Web3.js
// Yoki
// const balance = param1; // ethers.js, param1 balans deb faraz qilsak
document.getElementById('balance').textContent = balance;
Hodisa Tinglovchisining Ilg'or Texnikalari
Ushbu bo'limda murakkabroq hodisa tinglovchilarini yaratish uchun ba'zi ilg'or texnikalar ko'rib chiqiladi.
Hodisalarni Filtrlash
Siz hodisalarni ma'lum mezonlarga, masalan, indekslangan parametrning qiymatiga qarab filtrlashingiz mumkin. Bu sizni qiziqtirgan hodisalar doirasini toraytirishga va qayta ishlashingiz kerak bo'lgan ma'lumotlar hajmini kamaytirishga yordam beradi.
Web3.js'da siz hodisalarga obuna bo'lishda `filter` opsiyasidan foydalanishingiz mumkin:
myContract.events.MyEvent({
filter: {myIndexedParam: [20, 23]}, // Faqat myIndexedParam 20 yoki 23 bo'lgan hodisalarni tinglash.
fromBlock: 'latest'
}, function(error, event){
console.log(event);
})
Ethers.js'da siz kontrakt nusxasini yaratishda yoki hodisa tinglovchisini biriktirishda filtrlarni belgilashingiz mumkin:
// Hodisa nomi va indekslangan argumentlar bo'yicha filtrlash
const filter = myContract.filters.MyEvent(arg1, arg2);
myContract.on(filter, (arg1, arg2, event) => {
console.log("MyEvent hodisasi maxsus argumentlar bilan chiqarildi!");
console.log("Arg1:", arg1);
console.log("Arg2:", arg2);
console.log("Hodisa Ma'lumotlari:", event);
});
O'tgan Hodisalarni Tinglash
Siz hodisa tinglovchingiz faol bo'lishidan oldin sodir bo'lgan o'tgan hodisalarni olishingiz mumkin. Bu ilovangizning boshlang'ich holatini o'rnatish yoki audit maqsadlari uchun foydali bo'lishi mumkin.
Web3.js'da siz `getPastEvents` metodidan foydalanishingiz mumkin:
myContract.getPastEvents('MyEvent', {
fromBlock: 0,
toBlock: 'latest'
}, function(error, events){
console.log(events);
});
Ethers.js'da siz provayderning `getLogs` metodi yordamida hodisa jurnallarini (event logs) so'rashingiz mumkin:
const blockNumber = await provider.getBlockNumber();
const filter = myContract.filters.MyEvent(arg1, arg2);
const logs = await provider.getLogs({
address: myContract.address,
fromBlock: blockNumber - 1000, // oxirgi 1000 blok
toBlock: blockNumber,
topics: filter.topics // mavzularni filtrlash
});
for (const log of logs) {
const parsedLog = myContract.interface.parseLog(log);
console.log(parsedLog);
}
Bekor Qilingan Tranzaksiyalarni Boshqarish
Tranzaksiyalar ba'zan xatolar yoki yetarli gaz bo'lmaganligi sababli bekor qilinishi (revert) mumkin. Tranzaksiya bekor qilinganda, u bilan bog'liq hodisalar chiqarilmaydi. Ilovangizda kutilmagan xatti-harakatlarning oldini olish uchun bekor qilingan tranzaksiyalarni to'g'ri boshqarish muhimdir.
Bekor qilingan tranzaksiyalarni boshqarishning bir usuli - tranzaksiya kvitansiyasini (receipt) kuzatish. Kvitansiya tranzaksiya haqida ma'lumotni, jumladan, uning holatini (muvaffaqiyatli yoki muvaffaqiyatsiz) o'z ichiga oladi. Agar holat `0x0` bo'lsa, tranzaksiya bekor qilingan.
Tranzaksiya kvitansiyasini olish uchun `web3.eth.getTransactionReceipt` (Web3.js) yoki `provider.getTransactionReceipt` (ethers.js) metodidan foydalanishingiz mumkin.
Real Vaqtdagi Yangilanishlar uchun WebSockets'dan Foydalanish
WebSockets mijoz va server o'rtasida doimiy aloqani ta'minlab, real vaqt rejimida ikki tomonlama aloqa o'rnatish imkonini beradi. Bu hodisa bildirishnomalarini frontend'ga yetkazish uchun idealdir.
Web3.js va ethers.js ikkalasi ham WebSockets'ni qo'llab-quvvatlaydi. WebSockets'dan foydalanish uchun Web3 provayderingizni WebSocket endpoint bilan sozlang (yuqoridagi sozlash misollarida ko'rsatilganidek).
Xavfsizlik Masalalari
Frontend hodisa tinglovchilarini yaratishda quyidagi xavfsizlik jihatlarini hisobga olish muhim:
- Ma'lumotlarni tekshirish: Hodisa ma'lumotlarini ilovangizda ishlatishdan oldin har doim tekshiring. Blokcheyndan olingan ma'lumotlarga ko'r-ko'rona ishonmang.
- Xatoliklarni boshqarish: Kutilmagan xatti-harakatlar va potentsial xavfsizlik zaifliklarining oldini olish uchun mustahkam xatoliklarni boshqarish tizimini joriy qiling.
- So'rovlarni cheklash (Rate Limiting): Suiiste'mollikning oldini olish va ilovangizni xizmat ko'rsatishni rad etish (denial-of-service) hujumlaridan himoya qilish uchun so'rovlarni cheklashni joriy qiling.
- Bog'liqliklarni boshqarish: Xavfsizlik zaifliklarini tuzatish uchun bog'liqliklaringizni doimo yangilab turing.
- Foydalanuvchi kiritgan ma'lumotlarni tozalash (Sanitization): Agar foydalanuvchilarga hodisa ma'lumotlarini ko'rsatayotgan bo'lsangiz, saytlararo skripting (XSS) hujumlarining oldini olish uchun ma'lumotlarni tozalang.
Eng Yaxshi Amaliyotlar
Mustahkam va qo'llab-quvvatlanishi oson frontend hodisa tinglovchilarini yaratish uchun ushbu eng yaxshi amaliyotlarga rioya qiling:
- Modulli arxitekturadan foydalaning: Ilovangizni kichikroq, qayta ishlatiladigan qismlarga ajrating.
- Birlik testlarini (unit tests) yozing: Hodisa tinglovchilaringiz to'g'ri ishlayotganiga ishonch hosil qilish uchun ularni sinchkovlik bilan sinovdan o'tkazing.
- Jurnal yozish (logging) tizimidan foydalaning: Ilovangizni tuzatishga yordam berish uchun muhim hodisalar va xatoliklarni jurnalga yozing.
- Kodingizni hujjatlashtiring: Tushunish va qo'llab-quvvatlashni osonlashtirish uchun kodingizni aniq hujjatlashtiring.
- Kodlash qoidalariga rioya qiling: O'qishni osonlashtirish va qo'llab-quvvatlashni yaxshilash uchun izchil kodlash qoidalariga rioya qiling.
- Ilovangizni kuzatib boring: Potentsial muammolarni aniqlash uchun ilovangizning ishlashi va resurslardan foydalanishini kuzatib boring.
Misol Stsenariysi: Token O'tkazmasini Kuzatish
Keling, amaliy misolni ko'rib chiqaylik: oddiy ERC-20 token kontraktida token o'tkazmalarini kuzatish.
ERC-20 standarti hisoblar o'rtasida tokenlar o'tkazilganda chiqariladigan `Transfer` hodisasini o'z ichiga oladi. Ushbu hodisa jo'natuvchining manzili, qabul qiluvchining manzili va o'tkazilgan miqdorni o'z ichiga oladi.
Frontend ilovangizda `Transfer` hodisalarini qanday tinglashingiz mumkinligi quyida ko'rsatilgan:
Web3.js yordamida:
myContract.events.Transfer({
fromBlock: 'latest'
}, function(error, event){
if(!error)
{
console.log("Transfer Hodisasi:", event);
const from = event.returnValues.from;
const to = event.returnValues.to;
const value = event.returnValues.value;
// Interfeysni yangilang yoki boshqa amallarni bajaring
console.log(`Tokenlar ${from} dan ${to} ga o'tkazildi: ${value}`);
}
else
{console.error(error);}
});
Ethers.js yordamida:
myContract.on("Transfer", (from, to, value, event) => {
console.log("Transfer hodisasi chiqarildi!");
console.log("Kimdan:", from);
console.log("Kimga:", to);
console.log("Miqdor:", value.toString()); // Qiymat ethers.js'da BigNumber turida bo'ladi
console.log("Hodisa Ma'lumotlari:", event);
// Interfeysni yangilang yoki boshqa amallarni bajaring
console.log(`Tokenlar ${from} dan ${to} ga o'tkazildi: ${value.toString()}`);
});
Ushbu kod parchasi `Transfer` hodisalarini tinglaydi va jo'natuvchining manzili, qabul qiluvchining manzili va o'tkazilgan miqdorni konsolga chiqaradi. Keyin siz ushbu ma'lumotlardan ilovangiz interfeysini yangilash, tranzaksiyalar tarixini ko'rsatish yoki boshqa amallarni bajarish uchun foydalanishingiz mumkin.
Xulosa
Frontend blokcheyn smart-kontrakt hodisa tinglovchilari real vaqt rejimida ishlaydigan, sezgir DApp'lar yaratish uchun kuchli vositadir. Smart-kontraktlar tomonidan chiqarilgan hodisalarni kuzatib borish orqali siz foydalanuvchilarga eng so'nggi ma'lumotlarni taqdim etishingiz va umumiy foydalanuvchi tajribasini yaxshilashingiz mumkin. Ushbu qo'llanmada hodisa tinglovchilarini yaratish uchun asosiy tushunchalar, vositalar va usullar, shuningdek, hodisalarni filtrlash, bekor qilingan tranzaksiyalarni boshqarish va real vaqtdagi yangilanishlar uchun WebSockets'dan foydalanish kabi ilg'or mavzular yoritildi. Ushbu qo'llanmada keltirilgan eng yaxshi amaliyotlarga rioya qilish orqali siz DApp'laringizning funksionalligi va foydalanuvchi tajribasini oshiradigan mustahkam va xavfsiz hodisa tinglovchilarini yarata olasiz.