Қазіргі әлемде чектер транзакцияларды тексеру және сатып алуды растау үшін өте маңызды. Үлкен банк немесе жол бойындағы шағын дүкен болсын, түбіртектер кәсіпорындар мен жеке тұлғаларға ұйымшыл болып, олардың шығындарын қадағалауға көмектеседі.
Бірақ мұнда бір нәрсе бар: көптеген dApps түбіртектерді ұсынбайды және транзакция мәліметтерін тексеру үшін зерттеушілерге сенеді. Бұған сенудің қажеті болмаса ше? Пайдаланушыларыңызға әмияндарын тексеруді қажет етпей-ақ түбіртектерді тікелей жасау қаншалықты ыңғайлы болатынын елестетіп көріңіз.
Rootstock жүйесінде төлемге негізделген dApp құрып жатсаңыз, бұл мақала сізге Rootstock API және бір ғана RPC (Қашықтан процедура шақыру) әдісін пайдаланып қарапайым, бірақ тиімді түбіртек генераторын қалай жасау керектігін көрсетеді. Бұл тәсіл процесті жеңілдетеді және транзакция жазбаларының дәлдігін және қол жеткізуге оңай болуын қамтамасыз етеді.
Бірқалыпты түбіртек жасау тәжірибесін жасау үшін қажетті қадамдар мен құралдарды үйренейік.
Алғы шарттар
- Құрылғыда түйін орнатылған болуы керек
- Javascript бойынша білім
- Сіздің таңдауыңыз бойынша орнатылған Js фреймворк
- Код редакторы, мысалы, VScode
Мен сәндеу үшін React Typescript және TailwindCSS қолданамын
Құрал және технологиялар
- Rootstock API кілті
- Web3js : RPC-мен әрекеттесу
- QRCode React : пайдаланушыларға сканерлеу және түбіртек алу үшін QR кодын жасау
- Jspdf : PDF файлдарына түбіртек жасау үшін
Орнату, бумаларды импорттау және функционалды құрамдас бөлікті жасау
Осы пәрменді пайдаланып барлық тәуелділіктерді орнатыңыз:
npm i web3js jspdf qrcode.react
Жаңа файл жасаңыз немесе
App.jsx
пайдаланыңызПакеттерді келесі файлға импорттаңыз:
import { useState } from "react"; import Web3 from "web3"; import { jsPDF } from "jspdf"; import { QRCodeSVG } from "qrcode.react";
Функционалдық компонентті инициализациялаңыз
const TransactionReceipt = () => { /......./ } export default TransactionReceipt;
Мемлекетті басқару және Web3 Intilaiztion
Мұндағы код үзіндісі useState hook, Web3js, Rootstock RPC және API көмегімен транзакция мәліметтерін алу және көрсету күйі мен функционалдығын басқарады.
const [transactionId, setTransactionId] = useState(""); interface TransactionDetails { transactionHash: string; from: string; to: string; cumulativeGasUsed: number; blockNumber: number; contractAddress?: string; } const [transactionDetails, setTransactionDetails] = useState<TransactionDetails | null>(null); const [error, setError] = useState(""); const web3 = new Web3( `https://rpc.testnet.rootstock.io/${import.meta.env.VITE_API_KEY}` );
Мемлекеттік басқару :
-
const [transactionId, setTransactionId] = useState("");
: Бұл жолtransactionId
күй айнымалысын инициализациялайды. Бұл күй айнымалысы басқа айнымалылар мен функциялар түбіртек жасау үшін пайдаланатын енгізілген транзакция хэшіне жауапты болады. -
const [transactionDetails, setTransactionDetails] = useState<TransactionDetails | null>(null);
: Бұл жолnull
мәні барtransactionDetails
күй айнымалысын инициализациялайды және оның мәнін жаңарту үшінsetTransactionDetails
функциясын береді. КүйTransactionDetails
нысанын немесеnull
ұстай алады. -
const [error, setError] = useState("");
: Бұл жол күй айнымалыerror
бос жолмен инициализациялайды және оның мәнін жаңарту үшінsetError
функциясын береді.
-
TypeScript интерфейсі :
-
interface TransactionDetails
: Бұл транзакция мәліметтері нысанының құрылымы үшін TypeScript интерфейсін анықтайды. ОлtransactionHash
сияқты қасиеттерді,from
,to
,cumulativeGasUsed
,blockNumber
және қосымшаcontractAddress
қамтиды.
-
Web3 инициализациясы :
-
const web3 = new Web3(https://rpc.testnet.rootstock.io/${import.meta.env.VITE_API_KEY});
: Бұл жол RPC соңғы нүктесіне Rootstock сынақ желісіне қосылатын Web3js инициализациясын жасайды. Соңғы нүкте URL мекенжайыimport.meta.env.VITE_API_KEY
арқылы орта айнымалы мәндерінен шығарылатын API кілтін қамтиды.
-
Транзакция мәліметтерін алу функциясы
Мұндағы код web3.js әдісімен Rootstock жүйесінен асинхронды функцияны пайдаланып транзакция мәліметтерін алады.
const fetchTransactionDetails = async () => { try { setError(""); setTransactionDetails(null); const receipt = await web3.eth.getTransactionReceipt(transactionId); if (!receipt) { throw new Error("Transaction not found!"); } setTransactionDetails(receipt); } catch (err) { if (err instanceof Error) { setError(err.message); } else { setError("An unknown error occurred"); } } };
- Қате өңдеуді орнату :
-
try { ... } catch (err) { ... }
: Бұл құрылым функцияны орындау кезінде орын алуы мүмкін қателерді өңдеу үшін пайдаланылады.
-
- Қалпына келтіру күйі :
- setError("");: Бұл
error
күйін бос жолға орнату арқылы кез келген алдыңғы қате туралы хабарларды жояды. - setTransactionDetails(null);: Бұл
transactionDetails
күйінnull
мәніне орнату арқылы кез келген алдыңғы транзакция мәліметтерін тазартады.
- setError("");: Бұл
- Транзакция түбіртегін алу :
-
const receipt = await web3.eth.getTransactionReceipt(transactionId)
;: Бұл жол енгізілген транзакция идентификаторы үшін транзакция түбіртегін алу үшін web3js әдісін пайдаланады.
-
- Түбіртекті тексеру :
-
if (!receipt) { throw new Error("Transaction not found!"); }
: Егер түбіртек табылмаса (яғни, түбіртекnull
немесеundefined
), «Транзакция табылмады!» хабарымен қате жіберіледі.
-
- Транзакция мәліметтерін орнату :
-
setTransactionDetails(receipt)
: Егер түбіртек табылса, ол алынған түбіртекпенtransactionDetails
күйін жаңартады.
-
- Қатені өңдеу :
-
catch (err) { ... }
: Бұл блокtry
блогын орындау кезінде пайда болатын кез келген қателерді ұстайды. -
if (err instanceof Error) { setError(err.message); } else { setError("An unknown error occurred"); }
: Егер ұсталған қате Қате сыныбының данасы болса, ол қате туралы хабарғаerror
күйін орнатады. Әйтпесе, олerror
күйін «Белгісіз қате орын алды» жалпы қате туралы хабарға орнатады.
-
PDF түбіртегін жасау функциялары
Мұнда Jspdf бумасы транзакция мәліметтерін қамтитын PDF жасау үшін пайдаланылады.
const generatePDF = () => { if (!transactionDetails) return; const { transactionHash, from, to, cumulativeGasUsed, blockNumber, contractAddress, } = transactionDetails; const pdf = new jsPDF(); pdf.setFontSize(16); pdf.text("Transaction Receipt", 10, 10); pdf.setFontSize(12); pdf.text(`Transaction Hash: ${transactionHash}`, 10, 20); pdf.text(`From: ${from}`, 10, 30); pdf.text(`Contract Address: ${contractAddress}`, 10, 40); pdf.text(`To: ${to}`, 10, 40); pdf.text(`Cumulative Gas Used: ${cumulativeGasUsed}`, 10, 50); pdf.text(`Block Number: ${blockNumber}`, 10, 60); pdf.save("Transaction_Receipt.pdf"); };
- Транзакция мәліметтерін тексеріңіз :
if (!transactionDetails) return;
: БұлtransactionDetails
null
немесеundefined
тексереді. Егер солай болса, функция ертерек қайтарылады және ештеңе жасамайды.
- Құрылымдық транзакция мәліметтері :
const { transactionHash, from, to, cumulativeGasUsed, blockNumber, contractAddress } = transactionDetails;
: Бұл оңай қол жеткізу үшін жеке сипаттарды шығару үшінtransactionDetails
нысанын бұзады.
- PDF құжатын жасау :
const pdf = new jsPDF()
: Бұл PDF құжатын көрсететін jsPDF сыныбының жаңа данасын жасайды.
- Қаріп өлшемін орнатыңыз және тақырып қосыңыз :
pdf.setFontSize(16)
: Бұл тақырыптың қаріп өлшемін 16-ға орнатады.pdf.text("Transaction Receipt", 10, 10);
: Бұл PDF құжатындағы координаттарда (10, 10) «Транзакция түбіртегі» тақырыбын қосады.
- PDF файлына транзакция мәліметтерін қосу :
pdf.setFontSize(12);
: Бұл мәтіннің қалған бөлігі үшін қаріп өлшемін 12 етіп орнатады.pdf.text(Transaction Hash
: ${transactionHash}, 10, 20);
: Бұл координаттардағы транзакция хэшін қосады (10, 20).pdf.text(From: ${from}, 10, 30);
: Бұл координаттарға жіберуші мекенжайын қосады (10, 30).pdf.text(Contract Address: ${contractAddress}, 10, 40);
: Бұл координаттарға (10, 40) келісім-шарт мекенжайын қосады. Ескертпе: мәтіннің қабаттасуына жол бермеу үшін бұл жолды түзету керек.pdf.text(To: ${to}, 10, 50);
: Бұл координаттарға (10, 50) алушы мекенжайын қосады.pdf.text(Пайдаланылған жинақталған газ: ${кумулятивті газ пайдаланылған}
, 10, 60);
: Бұл координаттарда (10, 60) пайдаланылатын жинақталған газды қосады.pdf.text(Block Number: ${blockNumber}, 10, 70);
: Бұл координаттардағы блок нөмірін қосады (10, 70).
- PDF құжатын сақтау :
- pdf.save("Transaction_Receipt.pdf");: Бұл PDF құжатын "Transaction_Receipt.pdf" файл атымен сақтайды.
Пайдаланушы интерфейсі
Мұнда сіз сол функционалды компоненттерді пайдаланушыларға UI ретінде көрсетесіз.
Бұл код Tailwindcss көмегімен сәндеуді қамтыған
return ( <div className="p-8 font-sans bg-gray-100 min-h-screen"> <div className="max-w-3xl m-auto bg-white p-6 rounded-lg shadow-lg"> <h1 className="text-3xl font-bold mb-6 text-center text-blue-600"> Transaction Receipt Generator </h1> <div className="mb-6"> <div className="flex"> <input type="text" id="transactionId" value={transactionId} onChange={(e) => setTransactionId(e.target.value)} placeholder="Enter transaction hash" className="border p-2 w-full rounded-l-lg" /> <button onClick={fetchTransactionDetails} className="p-2 bg-blue-500 text-white rounded-r-lg" > Fetch Details </button> </div> </div> {error && ( <p className="text-red-500 mt-4 text-center">Error: {error}</p> )} {transactionDetails && ( <div className="mt-6 flex flex-row gap-8"> <div className="w-2/3"> <h2 className="text-2xl font-semibold mb-4 text-center"> Transaction Details </h2> <div className="bg-gray-50 p-4 rounded-lg shadow-inner w-[460px]"> <p> <strong>Transaction Hash:</strong>{" "} {`${transactionDetails.transactionHash.slice( 0, 6 )}...${transactionDetails.transactionHash.slice(-6)}`} </p> <p> <strong>From:</strong> {transactionDetails.from} </p> <p> <strong>Contract Address:</strong>{" "} {transactionDetails.contractAddress} </p> <p> <strong>To:</strong> {transactionDetails.to} </p> <p> <strong>Cumulative Gas Used:</strong>{" "} {transactionDetails.cumulativeGasUsed.toString()} </p> <p> <strong>Block Number:</strong>{" "} {transactionDetails.blockNumber.toString()} </p> </div> <button onClick={generatePDF} className="mt-6 w-full p-3 bg-green-500 text-white rounded-lg" > Download PDF Receipt </button> </div> <div className="w-1/2 text-center"> <h3 className="text-xl font-semibold mb-4">QR Code</h3> <QRCodeSVG value={`Transaction Hash: ${ transactionDetails.transactionHash }, From: ${transactionDetails.from}, To: ${transactionDetails.to}, Contract Address: ${transactionDetails.contractAddress}, Cumulative Gas Used: ${transactionDetails.cumulativeGasUsed.toString()}, Block Number: ${transactionDetails.blockNumber.toString()}`} size={200} className="mx-auto" /> </div> </div> )} </div> </div>
QR коды генераторы үшін qrcode.react кітапханасы пайдаланылды және транзакция мәліметтері оған QR коды SVG шифрланған.
Қорытынды код базасы және шығыс
Қадамды орындасаңыз, кодтық базаңыз келесідей болуы керек:
import { useState } from "react"; import Web3 from "web3"; import { jsPDF } from "jspdf"; import { QRCodeSVG } from "qrcode.react"; const TransactionReceipt = () => { const [transactionId, setTransactionId] = useState(""); interface TransactionDetails { transactionHash: string; from: string; to: string; cumulativeGasUsed: number; blockNumber: number; contractAddress?: string; } const [transactionDetails, setTransactionDetails] = useState<TransactionDetails | null>(null); const [error, setError] = useState(""); const web3 = new Web3( `https://rpc.testnet.rootstock.io/${import.meta.env.VITE_API_KEY}` ); const fetchTransactionDetails = async () => { try { setError(""); setTransactionDetails(null); const receipt = await web3.eth.getTransactionReceipt(transactionId); if (!receipt) { throw new Error("Transaction not found!"); } setTransactionDetails(receipt); } catch (err) { if (err instanceof Error) { setError(err.message); } else { setError("An unknown error occurred"); } } }; const generatePDF = () => { if (!transactionDetails) return; const { transactionHash, from, to, cumulativeGasUsed, blockNumber, contractAddress, } = transactionDetails; const pdf = new jsPDF(); pdf.setFontSize(16); pdf.text("Transaction Receipt", 10, 10); pdf.setFontSize(12); pdf.text(`Transaction Hash: ${transactionHash}`, 10, 20); pdf.text(`From: ${from}`, 10, 30); pdf.text(`Contract Address: ${contractAddress}`, 10, 40); pdf.text(`To: ${to}`, 10, 40); pdf.text(`Cumulative Gas Used: ${cumulativeGasUsed}`, 10, 50); pdf.text(`Block Number: ${blockNumber}`, 10, 60); pdf.save("Transaction_Receipt.pdf"); }; return ( <div className="p-8 font-sans bg-gray-100 min-h-screen"> <div className="max-w-3xl m-auto bg-white p-6 rounded-lg shadow-lg"> <h1 className="text-3xl font-bold mb-6 text-center text-blue-600"> Transaction Receipt Generator </h1> <div className="mb-6"> <div className="flex"> <input type="text" id="transactionId" value={transactionId} onChange={(e) => setTransactionId(e.target.value)} placeholder="Enter transaction hash" className="border p-2 w-full rounded-l-lg" /> <button onClick={fetchTransactionDetails} className="p-2 bg-blue-500 text-white rounded-r-lg" > Fetch Details </button> </div> </div> {error && ( <p className="text-red-500 mt-4 text-center">Error: {error}</p> )} {transactionDetails && ( <div className="mt-6 flex flex-row gap-8"> <div className="w-2/3"> <h2 className="text-2xl font-semibold mb-4 text-center"> Transaction Details </h2> <div className="bg-gray-50 p-4 rounded-lg shadow-inner w-[460px]"> <p> <strong>Transaction Hash:</strong>{" "} {`${transactionDetails.transactionHash.slice( 0, 6 )}...${transactionDetails.transactionHash.slice(-6)}`} </p> <p> <strong>From:</strong> {transactionDetails.from} </p> <p> <strong>Contract Address:</strong>{" "} {transactionDetails.contractAddress} </p> <p> <strong>To:</strong> {transactionDetails.to} </p> <p> <strong>Cumulative Gas Used:</strong>{" "} {transactionDetails.cumulativeGasUsed.toString()} </p> <p> <strong>Block Number:</strong>{" "} {transactionDetails.blockNumber.toString()} </p> </div> <button onClick={generatePDF} className="mt-6 w-full p-3 bg-green-500 text-white rounded-lg" > Download PDF Receipt </button> </div> <div className="w-1/2 text-center"> <h3 className="text-xl font-semibold mb-4">QR Code</h3> <QRCodeSVG value={`Transaction Hash: ${ transactionDetails.transactionHash }, From: ${transactionDetails.from}, To: ${transactionDetails.to}, Contract Address: ${transactionDetails.contractAddress}, Cumulative Gas Used: ${transactionDetails.cumulativeGasUsed.toString()}, Block Number: ${transactionDetails.blockNumber.toString()}`} size={200} className="mx-auto" /> </div> </div> )} </div> </div> ); }; export default TransactionReceipt;
Содан кейін TransactionReceipt
файлын импорттап, оны App.tsx
файлында көрсетіңіз
Демо
Қорытынды
Бұл мақалада Rootstock API кілті және RPC әдісі арқылы түбіртек генераторын PDF немесе QR кодына құра алдыңыз. Сондықтан келесі dApp жобаңызда бұл мүмкіндікті көремін деп үміттенемін.