Дар ҷаҳони имрӯза квитансияҳо барои тасдиқи транзаксияҳо ва нигоҳ доштани далели харидҳо муҳиманд. Новобаста аз он ки ин бонки калон ё дӯкони хурди канори роҳ аст, квитансияҳо ба корхонаҳо ва шахсони алоҳида кӯмак мекунанд, ки муташаккил бошанд ва хароҷоти онҳоро пайгирӣ кунанд. Аммо ин аст, ки аксари квитансия намедиҳанд ва барои тафтиши тафсилоти транзаксия ба муҳаққиқон такя мекунанд. Чӣ мешавад, агар шумо набояд ба он такя кунед? Тасаввур кунед, ки барои корбарони шумо бидуни тафтиши ҳамёнҳои худ мустақиман квитансия тавлид кардан то чӣ андоза қулайтар хоҳад буд. dApps Агар шумо дар асоси пардохт dApp дар Rootstock сохта истода бошед, ин мақола ба шумо нишон медиҳад, ки чӣ гуна як генератори содда ва самараноки квитансияро бо истифода аз Rootstock API ва танҳо як усули RPC (Занги дурдаст) эҷод кунед. Ин равиш равандро осонтар мекунад ва кафолат медиҳад, ки сабтҳои транзаксияҳои шумо дақиқ ва дастрас бошанд. Биёед қадамҳо ва асбобҳоеро омӯзем, ки барои эҷоди таҷрибаи ҳамвор тавлид кардани квитансия лозиманд. Шартҳои пешакӣ Шумо бояд гиреҳро дар дастгоҳи худ насб карда бошед дониш дар Javascript Чаҳорчӯбаи Js-и интихобкардаи шумо насб карда шудааст Муҳаррири код, масалан, VScode Ман барои ороиши React Typescript ва TailwindCSS истифода хоҳам кард Асбоб ва технологияҳо Калиди API Rootstock : барои ҳамкорӣ бо 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 Парчами рамз дар ин ҷо ҳолат ва функсияҳоро барои гирифтан ва намоиш додани тафсилоти транзаксия бо истифодаи 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); transactionDetails null setTransactionDetails TransactionDetails null : Ин сатр тағирёбандаи ҳолатиро бо сатри холӣ оғоз мекунад ва функсияи ро барои навсозии арзиши он таъмин мекунад. const [error, setError] = useState(""); error setError : Интерфейси TypeScript : Ин интерфейси TypeScript-ро барои сохтори объекти тафсилоти транзаксия муайян мекунад. Он дорои хосиятҳо ба монанди , , , , ва ихтиёрӣ мебошад. interface TransactionDetails transactionHash from to cumulativeGasUsed blockNumber contractAddress : Оғозсозии Web3 : Ин сатр Web3js-ро оғоз мекунад, ки ба нуқтаи ниҳоии RPC ба testnet Rootstock пайваст мешавад. URL-и ниҳоӣ калиди API-ро дар бар мегирад, ки аз тағирёбандаҳои муҳити зист бо истифода аз гирифта мешавад. const web3 = new Web3(https://rpc.testnet.rootstock.io/${import.meta.env.VITE_API_KEY}); import.meta.env.VITE_API_KEY Функсия барои гирифтани тафсилоти транзаксия Рамзи ин ҷо тафсилоти транзаксияро бо истифода аз функсияи асинхронӣ аз Rootstock бо усули web3.js мегирад. 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 : Агар хатои дастгиршуда намунаи синфи Error бошад, он ҳолати ба паёми хато муқаррар мекунад. Дар акси ҳол, он ҳолати ба паёми хатогии умумӣ муқаррар мекунад "Хатогии номаълум рух дод". 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 : Ин як мисоли нави синфи jsPDF-ро эҷод мекунад, ки ҳуҷҷати PDF-ро муаррифӣ мекунад. const pdf = new jsPDF() : Андозаи шрифтро танзим кунед ва унвон илова кунед : Ин андозаи ҳуруфи сарлавҳаро ба 16 муқаррар мекунад. pdf.setFontSize(16) : Ин дар координатҳо (10, 10) дар ҳуҷҷати PDF унвони "Квитансияи транзаксия" -ро илова мекунад. 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 Хулоса Дар ин мақола, шумо тавонистед як генератори квитансияро дар PDF ё QR бо истифода аз усули Rootstock API ва усули RPC созед. Ҳамин тавр, дар лоиҳаи навбатии dApp, ман умедворам, ки ин хусусиятро дар он бубинам.