Қазіргі әлемде чектер транзакцияларды тексеру және сатып алуды растау үшін өте маңызды. Үлкен банк немесе жол бойындағы шағын дүкен болсын, түбіртектер кәсіпорындар мен жеке тұлғаларға ұйымшыл болып, олардың шығындарын қадағалауға көмектеседі. Бірақ мұнда бір нәрсе бар: көптеген түбіртектерді ұсынбайды және транзакция мәліметтерін тексеру үшін зерттеушілерге сенеді. Бұған сенудің қажеті болмаса ше? Пайдаланушыларыңызға әмияндарын тексеруді қажет етпей-ақ түбіртектерді тікелей жасау қаншалықты ыңғайлы болатынын елестетіп көріңіз. dApps Rootstock жүйесінде төлемге негізделген dApp құрып жатсаңыз, бұл мақала сізге Rootstock API және бір ғана RPC (Қашықтан процедура шақыру) әдісін пайдаланып қарапайым, бірақ тиімді түбіртек генераторын қалай жасау керектігін көрсетеді. Бұл тәсіл процесті жеңілдетеді және транзакция жазбаларының дәлдігін және қол жеткізуге оңай болуын қамтамасыз етеді. Бірқалыпты түбіртек жасау тәжірибесін жасау үшін қажетті қадамдар мен құралдарды үйренейік. Алғы шарттар Құрылғыда түйін орнатылған болуы керек Javascript бойынша білім Сіздің таңдауыңыз бойынша орнатылған Js фреймворк Код редакторы, мысалы, VScode Мен сәндеу үшін React Typescript және TailwindCSS қолданамын Құрал және технологиялар Rootstock API кілті : RPC-мен әрекеттесу Web3js : пайдаланушыларға сканерлеу және түбіртек алу үшін QR кодын жасау QRCode React : PDF файлдарына түбіртек жасау үшін Jspdf Орнату, бумаларды импорттау және функционалды құрамдас бөлікті жасау Осы пәрменді пайдаланып барлық тәуелділіктерді орнатыңыз: 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 интерфейсі : Бұл транзакция мәліметтері нысанының құрылымы үшін TypeScript интерфейсін анықтайды. Ол сияқты қасиеттерді, , , , және қосымша қамтиды. interface TransactionDetails transactionHash from to cumulativeGasUsed blockNumber contractAddress : Web3 инициализациясы : Бұл жол RPC соңғы нүктесіне Rootstock сынақ желісіне қосылатын Web3js инициализациясын жасайды. Соңғы нүкте URL мекенжайы арқылы орта айнымалы мәндерінен шығарылатын API кілтін қамтиды. const web3 = new Web3(https://rpc.testnet.rootstock.io/${import.meta.env.VITE_API_KEY}); import.meta.env.VITE_API_KEY Транзакция мәліметтерін алу функциясы Мұндағы код 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 : Транзакция түбіртегін алу ;: Бұл жол енгізілген транзакция идентификаторы үшін транзакция түбіртегін алу үшін web3js әдісін пайдаланады. const receipt = await web3.eth.getTransactionReceipt(transactionId) : Түбіртекті тексеру : Егер түбіртек табылмаса (яғни, түбіртек немесе ), «Транзакция табылмады!» хабарымен қате жіберіледі. 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 құжатын жасау : Бұл PDF құжатын көрсететін jsPDF сыныбының жаңа данасын жасайды. const pdf = new jsPDF() : Қаріп өлшемін орнатыңыз және тақырып қосыңыз : Бұл тақырыптың қаріп өлшемін 16-ға орнатады. pdf.setFontSize(16) : Бұл PDF құжатындағы координаттарда (10, 10) «Транзакция түбіртегі» тақырыбын қосады. pdf.text("Transaction Receipt", 10, 10); : PDF файлына транзакция мәліметтерін қосу : Бұл мәтіннің қалған бөлігі үшін қаріп өлшемін 12 етіп орнатады. pdf.setFontSize(12); : ${transactionHash} : Бұл координаттардағы транзакция хэшін қосады (10, 20). pdf.text(Transaction Hash , 10, 20); : Бұл координаттарға жіберуші мекенжайын қосады (10, 30). pdf.text(From: ${from}, 10, 30); : Бұл координаттарға (10, 40) келісім-шарт мекенжайын қосады. Ескертпе: мәтіннің қабаттасуына жол бермеу үшін бұл жолды түзету керек. pdf.text(Contract Address: ${contractAddress}, 10, 40); : Бұл координаттарға (10, 50) алушы мекенжайын қосады. pdf.text(To: ${to}, 10, 50); pdf.text(Пайдаланылған жинақталған газ: ${кумулятивті газ пайдаланылған} : Бұл координаттарда (10, 60) пайдаланылатын жинақталған газды қосады. , 10, 60); : Бұл координаттардағы блок нөмірін қосады (10, 70). pdf.text(Block Number: ${blockNumber}, 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 Демо https://youtu.be/Xwkl9pu8UiM?embedable=true Қорытынды Бұл мақалада Rootstock API кілті және RPC әдісі арқылы түбіртек генераторын PDF немесе QR кодына құра алдыңыз. Сондықтан келесі dApp жобаңызда бұл мүмкіндікті көремін деп үміттенемін.