Kattava opas frontend-tapahtumankuuntelijan rakentamiseen lohkoketjun älysopimuksille, mahdollistaen sopimuksen tilan reaaliaikaisen seurannan.
Frontend-lohkoketjun älysopimuksen tapahtumankuuntelija: Sopimuksen tilan seuranta
Hajautetut sovellukset (DApps) vaativat usein reaaliaikaisia päivityksiä heijastamaan muutoksia taustalla olevan älysopimuksen tilassa. Tässä tapahtumankuuntelijat astuvat kuvaan. Seuraamalla älysopimusten lähettämiä tapahtumia frontend-sovellukset voivat reagoida tilasiirtymiin ja tarjota käyttäjille ajantasaista tietoa. Tämä opas tarjoaa kattavan yleiskatsauksen frontend-tapahtumankuuntelijan rakentamisesta lohkoketjun älysopimuksille, keskittyen käytännön toteutukseen ja parhaisiin käytäntöihin.
Mitä ovat älysopimusten tapahtumat?
Älysopimukset, jotka on kirjoitettu esimerkiksi Solidity-kielellä, voivat lähettää tapahtumia, kun tietyt toiminnot tapahtuvat sopimuksessa. Nämä tapahtumat toimivat ilmoitusmekanismina, joka viestii ulkoisille sovelluksille, että tilamuutos on tapahtunut. Ajattele niitä lokimerkintöinä, jotka tallennetaan pysyvästi lohkoketjuun. Tapahtumat sisältävät tietoa muutoksesta, mikä mahdollistaa sovellusten reagoimisen sen mukaisesti.
Esimerkiksi, harkitse yksinkertaista token-sopimusta. Se saattaa lähettää tapahtuman, kun tokeneita siirretään tilien välillä. Tämä tapahtuma sisältäisi tyypillisesti lähettäjän osoitteen, vastaanottajan osoitteen ja siirretyn määrän. Frontend-sovellus voisi kuunnella tätä tapahtumaa ja päivittää käyttäjän saldon reaaliajassa.
Miksi käyttää tapahtumankuuntelijoita?
Lohkoketjun jatkuva kysely tilamuutosten varalta on tehotonta ja resurssi-intensiivistä. Tapahtumankuuntelijat tarjoavat elegantimman ja tehokkaamman ratkaisun antamalla sovellusten odottaa passiivisesti ilmoituksia. Tämä vähentää lohkoketjun kuormitusta ja parantaa DApp-sovelluksen responsiivisuutta.
Tapahtumankuuntelijoiden tärkeimpiä etuja ovat:
- Reaaliaikaiset päivitykset: Tarjoa käyttäjille välitöntä palautetta sopimuksen tilamuutoksista.
- Parempi tehokkuus: Vähennä tarvetta jatkuvasti kysellä lohkoketjulta tietoja.
- Parannettu käyttökokemus: Luo dynaamisempi ja reagoivampi sovellus.
- Pienemmät kaasukulut: Vältä tarpeettomia lukutoimenpiteitä lohkoketjusta.
Työkalut ja teknologiat
Frontend-tapahtumankuuntelijoiden rakentamiseen voidaan käyttää useita työkaluja ja kirjastoja. Suosituimpia vaihtoehtoja ovat:
- Web3.js: JavaScript-kirjasto, joka mahdollistaa vuorovaikutuksen Ethereum-solmujen ja älysopimusten kanssa. Se tarjoaa kattavan API:n lohkoketjudatan käyttöön, transaktioiden lähettämiseen ja tapahtumien kuunteluun.
- Ethers.js: Toinen suosittu JavaScript-kirjasto Ethereumin kanssa vuorovaikutukseen. Se on tunnettu yksinkertaisuudestaan, turvallisuudestaan ja suorituskyvystään.
- Infura/Alchemy: Infrastruktuurin tarjoajat, jotka tarjoavat luotettavan pääsyn Ethereum-verkkoon. Ne tarjoavat API:t lohkoketjudatan lukemiseen ja transaktioiden lähettämiseen, poistaen tarpeen ylläpitää omaa Ethereum-solmua.
- WebSockets: Viestintäprotokolla, joka mahdollistaa reaaliaikaisen, kaksisuuntaisen viestinnän asiakkaan ja palvelimen välillä. WebSocketeja käytetään usein tapahtumailmoitusten toimittamiseen frontendiin.
Frontend-tapahtumankuuntelijan rakentaminen: Vaiheittainen opas
Tässä osiossa kuvataan vaiheet, jotka liittyvät frontend-tapahtumankuuntelijan rakentamiseen käyttäen Web3.js:ää tai ethers.js:ää.
Vaihe 1: Kehitysympäristön pystyttäminen
Ennen aloittamista varmista, että sinulla on seuraavat asennettuna:
- Node.js: JavaScript-ajoympäristö.
- npm (Node Package Manager) tai yarn: Paketinhallintaohjelma riippuvuuksien asentamiseen.
- Koodieditori: Visual Studio Code, Sublime Text tai mikä tahansa muu haluamasi editori.
Luo uusi projektihakemisto ja alusta se npm:llä tai yarnilla:
mkdir my-dapp
cd my-dapp
npm init -y
Tai käyttäen yarnia:
mkdir my-dapp
cd my-dapp
yarn init -y
Vaihe 2: Riippuvuuksien asentaminen
Asenna Web3.js tai ethers.js sekä muut tarvittavat riippuvuudet. Saatat esimerkiksi tarvita kirjaston ympäristömuuttujien käsittelyyn.
Käyttäen npm:ää:
npm install web3 dotenv
Käyttäen yarnia:
yarn add web3 dotenv
Tai ethers.js:lle:
Käyttäen npm:ää:
npm install ethers dotenv
Käyttäen yarnia:
yarn add ethers dotenv
Vaihe 3: Web3-tarjoajan määrittäminen
Sinun on määritettävä Web3-tarjoaja yhdistääksesi Ethereum-verkkoon. Tämä voidaan tehdä käyttämällä Infuraa, Alchemya tai paikallista Ethereum-solmua (kuten Ganache).
Luo `.env`-tiedosto projektihakemistoosi ja lisää Infura- tai Alchemy-API-avaimesi:
INFURA_API_KEY=OMA_INFURA_API_AVAIN
Sitten, JavaScript-tiedostossasi, määritä Web3-tarjoaja:
Käyttäen Web3.js:ää:
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}`));
Käyttäen ethers.js:ää:
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}`);
Huom: Korvaa `mainnet` sopivalla verkolla (esim. `ropsten`, `rinkeby`, `goerli`), jos käytät testiverkkoa.
Vaihe 4: Sopimuksen ABI:n ja osoitteen hankkiminen
Vuorovaikutukseen älysopimuksesi kanssa tarvitset sen Application Binary Interfacen (ABI) ja osoitteen. ABI on JSON-tiedosto, joka kuvaa sopimuksen funktiot ja tapahtumat. Osoite on sopimuksen sijainti lohkoketjussa.
Voit saada ABI:n Solidity-kääntäjäsi tulosteesta. Osoite näytetään, kun olet julkaissut sopimuksen.
Tallenna ABI JSON-tiedostoon (esim. `MyContract.json`) ja osoite `.env`-tiedostoosi:
CONTRACT_ADDRESS=0xOmanSopimuksenOsoite...
Vaihe 5: Sopimusinstanssin luominen
Käyttämällä ABI:ta ja osoitetta, luo sopimusinstanssi JavaScript-tiedostossasi:
Käyttäen Web3.js:ää:
const contractAddress = process.env.CONTRACT_ADDRESS;
const contractABI = require('./MyContract.json').abi;
const myContract = new web3.eth.Contract(contractABI, contractAddress);
Käyttäen ethers.js:ää:
const contractAddress = process.env.CONTRACT_ADDRESS;
const contractABI = require('./MyContract.json').abi;
const myContract = new ethers.Contract(contractAddress, contractABI, provider);
Vaihe 6: Tapahtumien kuunteleminen
Nyt voit aloittaa älysopimuksesi lähettämien tapahtumien kuuntelun. Käytä sopimusinstanssisi `events`-ominaisuutta tilataksesi tapahtumia.
Käyttäen Web3.js:ää:
myContract.events.MyEvent({
filter: {myIndexedParam: [20,23]}, // Valinnainen suodatus käyttäen indeksoituja parametreja.
fromBlock: 'latest' // Aloita kuuntelu viimeisimmästä lohkosta.
}, function(error, event){
if(!error)
{console.log(event);}
else
{console.log(error);}
})
.on('data', function(event){
console.log(event);
})
.on('changed', function(event){
// poista tapahtuma paikallisesta tietokannasta
})
.on('error', console.error);
Tai käyttäen async/await:
myContract.events.MyEvent({
filter: {myIndexedParam: [20,23]}, // Valinnainen suodatus käyttäen indeksoituja parametreja.
fromBlock: 'latest' // Aloita kuuntelu viimeisimmästä lohkosta.
})
.on('data', async function(event){
console.log(event);
// Käsittele tapahtumadata täällä, esim. päivitä käyttöliittymä
try {
// Esimerkki: Vuorovaikuta toisen DAppisi osan kanssa.
// await someOtherFunction(event.returnValues);
} catch (error) {
console.error("Virhe tapahtuman käsittelyssä:", error);
}
})
.on('changed', function(event){
// poista tapahtuma paikallisesta tietokannasta
})
.on('error', console.error);
Käyttäen ethers.js:ää:
myContract.on("MyEvent", (param1, param2, event) => {
console.log("Tapahtuma MyEvent lähetetty!");
console.log("Param1:", param1);
console.log("Param2:", param2);
console.log("Tapahtumadata:", event);
// Käsittele tapahtumadata täällä, esim. päivitä käyttöliittymä
});
Korvaa molemmissa esimerkeissä `MyEvent` sen tapahtuman nimellä, jota haluat kuunnella. Takaisinkutsufunktio suoritetaan aina, kun tapahtuma lähetetään. Voit käyttää tapahtumadataa `event`-objektin kautta.
Vaihe 7: Tapahtumadatan käsittely
`event`-objekti sisältää tietoa tapahtumasta, mukaan lukien sille välitetyt argumentit, lohkon numeron ja transaktion tiivisteen (hash). Voit käyttää tätä dataa päivittääksesi sovelluksesi käyttöliittymää tai suorittaaksesi muita toimintoja.
Esimerkiksi, jos tapahtumasi sisältää käyttäjän saldon, voit päivittää saldonäytön frontendissä:
// Tapahtumankäsittelijän sisällä
const balance = event.returnValues.balance; // Web3.js
// Tai
// const balance = param1; // ethers.js, olettaen että param1 on saldo
document.getElementById('balance').textContent = balance;
Edistyneet tapahtumankuuntelijatekniikat
Tässä osiossa tutkitaan joitakin edistyneitä tekniikoita kehittyneempien tapahtumankuuntelijoiden rakentamiseen.
Tapahtumien suodattaminen
Voit suodattaa tapahtumia tiettyjen kriteerien perusteella, kuten indeksoidun parametrin arvon perusteella. Tämä voi auttaa sinua rajaamaan sinua kiinnostavat tapahtumat ja vähentämään käsiteltävän datan määrää.
Web3.js:ssä voit käyttää `filter`-vaihtoehtoa tilatessasi tapahtumia:
myContract.events.MyEvent({
filter: {myIndexedParam: [20, 23]}, // Kuuntele vain tapahtumia, joissa myIndexedParam on 20 tai 23.
fromBlock: 'latest'
}, function(error, event){
console.log(event);
})
Ethers.js:ssä voit määrittää suodattimia luodessasi sopimusinstanssia tai liittäessäsi tapahtumankuuntelijaa:
// Suodata tapahtuman nimen ja indeksoitujen argumenttien perusteella
const filter = myContract.filters.MyEvent(arg1, arg2);
myContract.on(filter, (arg1, arg2, event) => {
console.log("Tapahtuma MyEvent lähetetty tietyillä argumenteilla!");
console.log("Arg1:", arg1);
console.log("Arg2:", arg2);
console.log("Tapahtumadata:", event);
});
Menneiden tapahtumien kuunteleminen
Voit hakea menneitä tapahtumia, jotka tapahtuivat ennen kuin tapahtumankuuntelijasi oli aktiivinen. Tämä voi olla hyödyllistä sovelluksesi tilan alustamisessa tai tarkastustarkoituksissa.
Web3.js:ssä voit käyttää `getPastEvents`-metodia:
myContract.getPastEvents('MyEvent', {
fromBlock: 0,
toBlock: 'latest'
}, function(error, events){
console.log(events);
});
Ethers.js:ssä voit kysellä tapahtumalokeja käyttämällä tarjoajan `getLogs`-metodia:
const blockNumber = await provider.getBlockNumber();
const filter = myContract.filters.MyEvent(arg1, arg2);
const logs = await provider.getLogs({
address: myContract.address,
fromBlock: blockNumber - 1000, // viimeiset 1000 lohkoa
toBlock: blockNumber,
topics: filter.topics // suodata topicit
});
for (const log of logs) {
const parsedLog = myContract.interface.parseLog(log);
console.log(parsedLog);
}
Palautettujen transaktioiden käsittely
Transaktiot voivat joskus palautua virheiden tai riittämättömän kaasun vuoksi. Kun transaktio palautuu, siihen liittyviä tapahtumia ei lähetetä. On tärkeää käsitellä palautetut transaktiot siististi odottamattoman käyttäytymisen välttämiseksi sovelluksessasi.
Yksi tapa käsitellä palautettuja transaktioita on seurata transaktion kuittia. Kuitti sisältää tietoa transaktiosta, mukaan lukien sen tilan (onnistunut tai epäonnistunut). Jos tila on `0x0`, transaktio palautui.
Voit käyttää `web3.eth.getTransactionReceipt` (Web3.js) tai `provider.getTransactionReceipt` (ethers.js) -metodia transaktion kuitin hakemiseen.
WebSocketsien käyttö reaaliaikaisiin päivityksiin
WebSockets tarjoaa pysyvän yhteyden asiakkaan ja palvelimen välillä, mahdollistaen reaaliaikaisen, kaksisuuntaisen viestinnän. Tämä on ihanteellista tapahtumailmoitusten toimittamiseen frontendiin.
Sekä Web3.js että ethers.js tukevat WebSocketeja. Käyttääksesi WebSocketeja, määritä Web3-tarjoajasi WebSocket-päätepisteellä (kuten asennusesimerkeissä yllä on näytetty).
Turvallisuusnäkökohdat
Kun rakennat frontend-tapahtumankuuntelijoita, on tärkeää ottaa huomioon seuraavat turvallisuusnäkökohdat:
- Datan validointi: Vahvista aina tapahtumadata ennen sen käyttöä sovelluksessasi. Älä luota sokeasti lohkoketjusta saatuun dataan.
- Virheidenkäsittely: Toteuta vankka virheidenkäsittely estääksesi odottamattoman käyttäytymisen ja mahdolliset turvallisuushaavoittuvuudet.
- Käyttörajoitukset (Rate Limiting): Toteuta käyttörajoitukset väärinkäytön estämiseksi ja sovelluksesi suojaamiseksi palvelunestohyökkäyksiltä.
- Riippuvuuksien hallinta: Pidä riippuvuutesi ajan tasalla turvallisuushaavoittuvuuksien korjaamiseksi.
- Käyttäjäsyötteen puhdistaminen: Jos näytät tapahtumadataa käyttäjille, puhdista data estääksesi sivustojen väliset komentosarjahyökkäykset (XSS).
Parhaat käytännöt
Noudata näitä parhaita käytäntöjä rakentaaksesi vakaita ja ylläpidettäviä frontend-tapahtumankuuntelijoita:
- Käytä modulaarista arkkitehtuuria: Jaa sovelluksesi pienempiin, uudelleenkäytettäviin komponentteihin.
- Kirjoita yksikkötestejä: Testaa tapahtumankuuntelijasi perusteellisesti varmistaaksesi, että ne toimivat oikein.
- Käytä lokituskehystä: Kirjaa tärkeät tapahtumat ja virheet ylös auttaaksesi sinua sovelluksesi vianmäärityksessä.
- Dokumentoi koodisi: Dokumentoi koodisi selkeästi, jotta sitä on helpompi ymmärtää ja ylläpitää.
- Noudata koodauskäytäntöjä: Noudata johdonmukaisia koodauskäytäntöjä parantaaksesi luettavuutta ja ylläpidettävyyttä.
- Seuraa sovellustasi: Seuraa sovelluksesi suorituskykyä ja resurssien käyttöä tunnistaaksesi mahdolliset pullonkaulat.
Esimerkkiskenaario: Token-siirron seuranta
Tarkastellaan käytännön esimerkkiä: token-siirtojen seuranta yksinkertaisessa ERC-20-token-sopimuksessa.
ERC-20-standardi sisältää `Transfer`-tapahtuman, joka lähetetään aina, kun tokeneita siirretään tilien välillä. Tämä tapahtuma sisältää lähettäjän osoitteen, vastaanottajan osoitteen ja siirretyn määrän.
Näin voit kuunnella `Transfer`-tapahtumia frontend-sovelluksessasi:
Käyttäen Web3.js:ää:
myContract.events.Transfer({
fromBlock: 'latest'
}, function(error, event){
if(!error)
{
console.log("Siirtotapahtuma:", event);
const from = event.returnValues.from;
const to = event.returnValues.to;
const value = event.returnValues.value;
// Päivitä käyttöliittymä tai suorita muita toimintoja
console.log(`Tokeneita siirretty osoitteesta ${from} osoitteeseen ${to}: ${value}`);
}
else
{console.error(error);}
});
Käyttäen ethers.js:ää:
myContract.on("Transfer", (from, to, value, event) => {
console.log("Siirtotapahtuma lähetetty!");
console.log("Lähettäjä:", from);
console.log("Vastaanottaja:", to);
console.log("Määrä:", value.toString()); // ethers.js:ssä arvo on BigNumber
console.log("Tapahtumadata:", event);
// Päivitä käyttöliittymä tai suorita muita toimintoja
console.log(`Tokeneita siirretty osoitteesta ${from} osoitteeseen ${to}: ${value.toString()}`);
});
Tämä koodinpätkä kuuntelee `Transfer`-tapahtumia ja kirjaa konsoliin lähettäjän osoitteen, vastaanottajan osoitteen ja siirretyn määrän. Voit sitten käyttää tätä tietoa päivittääksesi sovelluksesi käyttöliittymää, näyttääksesi transaktiohistorian tai suorittaaksesi muita toimintoja.
Yhteenveto
Frontend-lohkoketjun älysopimusten tapahtumankuuntelijat ovat tehokas työkalu reaaliaikaisten, reagoivien DApp-sovellusten rakentamiseen. Seuraamalla älysopimusten lähettämiä tapahtumia voit tarjota käyttäjille ajantasaista tietoa ja parantaa yleistä käyttökokemusta. Tämä opas on kattanut peruskäsitteet, työkalut ja tekniikat tapahtumankuuntelijoiden rakentamiseen sekä edistyneitä aiheita, kuten tapahtumien suodattamisen, palautettujen transaktioiden käsittelyn ja WebSocketsien käytön reaaliaikaisiin päivityksiin. Noudattamalla tässä oppaassa esitettyjä parhaita käytäntöjä voit rakentaa vakaita ja turvallisia tapahtumankuuntelijoita, jotka parantavat DApp-sovellustesi toiminnallisuutta ja käyttökokemusta.