paint-brush
Δημιουργήστε μια γεννήτρια αποδείξεων μόνο με τη μέθοδο Rootstock API και RPCμε@ileolami
184 αναγνώσεις

Δημιουργήστε μια γεννήτρια αποδείξεων μόνο με τη μέθοδο Rootstock API και RPC

με Ileolami19m2024/12/01
Read on Terminal Reader

Πολύ μακρύ; Να διαβασω

Οι αποδείξεις είναι σημαντικές για την επικύρωση των συναλλαγών και την παροχή απόδειξης αγοράς. Αυτό το άρθρο θα σας δείξει πώς να δημιουργήσετε μια απλή αλλά αποτελεσματική γεννήτρια αποδείξεων χρησιμοποιώντας το Rootstock API και μια μεμονωμένη μέθοδο RPC (Remote Procedure Call).
featured image - Δημιουργήστε μια γεννήτρια αποδείξεων μόνο με τη μέθοδο Rootstock API και RPC
Ileolami HackerNoon profile picture
0-item
1-item

Στον σημερινό κόσμο, οι αποδείξεις είναι ζωτικής σημασίας για την επικύρωση των συναλλαγών και την τήρηση αποδείξεων αγορών. Είτε πρόκειται για μια μεγάλη τράπεζα είτε για ένα μικρό κατάστημα στην άκρη του δρόμου, οι αποδείξεις βοηθούν τις επιχειρήσεις και τα άτομα να παραμείνουν οργανωμένες και να παρακολουθούν τις δαπάνες τους.


Αλλά εδώ είναι το θέμα: τα περισσότερα dApps δεν παρέχουν αποδείξεις και βασίζονται σε εξερευνητές για την επαλήθευση των λεπτομερειών συναλλαγής. Τι θα γινόταν αν δεν έπρεπε να βασιστείτε σε αυτό; Φανταστείτε πόσο πιο βολικό θα ήταν για τους χρήστες σας να δημιουργούν αποδείξεις απευθείας, χωρίς να χρειάζεται να ελέγξουν τα πορτοφόλια τους.


Εάν δημιουργείτε ένα dApp που βασίζεται σε πληρωμές στο Rootstock, αυτό το άρθρο θα σας δείξει πώς να δημιουργήσετε μια απλή αλλά αποτελεσματική γεννήτρια αποδείξεων χρησιμοποιώντας το Rootstock API και μία μόνο μέθοδο RPC (Remote Procedure Call). Αυτή η προσέγγιση διευκολύνει τη διαδικασία και διασφαλίζει ότι τα αρχεία συναλλαγών σας είναι ακριβή και εύκολη στην πρόσβαση.


Ας μάθουμε τα βήματα και τα εργαλεία που χρειάζονται για να δημιουργήσουμε μια ομαλή εμπειρία δημιουργίας αποδείξεων.


Προαπαιτούμενα

  1. Πρέπει να έχετε εγκατεστημένο τον κόμβο στη συσκευή σας
  2. γνώση Javascript
  3. Εγκατεστημένο πλαίσιο Js της επιλογής σας
  4. Επεξεργαστής κώδικα π.χ., VScode

Θα χρησιμοποιήσω το React Typescript και το TailwindCSS για το στυλ

Εργαλείο και Τεχνολογίες

  1. Κλειδί API Rootstock
  2. Web3js : για αλληλεπίδραση με το RPC
  3. QRCode React : για να δημιουργήσετε έναν κωδικό QR για να σαρώσουν οι χρήστες και να λάβουν την απόδειξή τους
  4. Jspdf : για τη δημιουργία της απόδειξης σε PDF

Εγκαταστήστε, εισαγάγετε τα πακέτα και δημιουργήστε το λειτουργικό στοιχείο

  1. Εγκαταστήστε όλες τις εξαρτήσεις χρησιμοποιώντας αυτήν την εντολή:

     npm i web3js jspdf qrcode.react
  2. Δημιουργήστε ένα νέο αρχείο ή χρησιμοποιήστε το App.jsx

  3. Εισαγάγετε τα πακέτα στο αρχείο με τα εξής:

     import { useState } from "react"; import Web3 from "web3"; import { jsPDF } from "jspdf"; import { QRCodeSVG } from "qrcode.react";
  4. Αρχικοποιήστε το λειτουργικό στοιχείο

     const TransactionReceipt = () => { /......./ } export default TransactionReceipt;


State Management και 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}` );
  1. Κρατική διαχείριση :

    • const [transactionId, setTransactionId] = useState(""); : Αυτή η γραμμή προετοιμάζει μια μεταβλητή transactionId . Αυτή η μεταβλητή κατάστασης θα είναι υπεύθυνη για τον κατακερματισμό συναλλαγής που έχει εισαχθεί, τον οποίο άλλες μεταβλητές και συναρτήσεις θα αξιοποιήσουν για να δημιουργήσουν την απόδειξη.
    • const [transactionDetails, setTransactionDetails] = useState<TransactionDetails | null>(null); : Αυτή η γραμμή προετοιμάζει μια μεταβλητή transactionDetails με null τιμή και παρέχει μια συνάρτηση setTransactionDetails για την ενημέρωση της τιμής της. Η κατάσταση μπορεί να κρατήσει είτε ένα αντικείμενο TransactionDetails είτε null .
    • const [error, setError] = useState(""); : Αυτή η γραμμή προετοιμάζει ένα error μεταβλητής κατάστασης με μια κενή συμβολοσειρά και παρέχει μια συνάρτηση setError για την ενημέρωση της τιμής της.
  2. Διεπαφή TypeScript :

    • interface TransactionDetails : Αυτό ορίζει μια διεπαφή TypeScript για τη δομή του αντικειμένου λεπτομερειών συναλλαγής. Περιλαμβάνει ιδιότητες όπως transactionHash , from , to , cumulativeGasUsed , blockNumber και μια προαιρετική contractAddress .
  3. Εκκίνηση Web3 :

    • const web3 = new Web3(https://rpc.testnet.rootstock.io/${import.meta.env.VITE_API_KEY}); : Αυτή η γραμμή αρχικοποιεί το Web3js, συνδέοντας το τελικό σημείο RPC στο δίκτυο δοκιμής Rootstock. Η διεύθυνση URL τελικού σημείου περιλαμβάνει ένα κλειδί API που ανακτάται από μεταβλητές περιβάλλοντος χρησιμοποιώντας 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"); } } };
  1. Ρύθμιση χειρισμού σφαλμάτων :
    • try { ... } catch (err) { ... } : Αυτή η δομή χρησιμοποιείται για τον χειρισμό τυχόν σφαλμάτων που ενδέχεται να προκύψουν κατά την εκτέλεση της συνάρτησης.
  2. Επαναφορά κατάστασης :
    • setError("");: Διαγράφει τυχόν προηγούμενα μηνύματα σφάλματος ορίζοντας την κατάσταση error σε μια κενή συμβολοσειρά.
    • setTransactionDetails(null);: Διαγράφει τυχόν στοιχεία προηγούμενης συναλλαγής ορίζοντας την κατάσταση transactionDetails σε null .
  3. Λήψη απόδειξης συναλλαγής :
    • const receipt = await web3.eth.getTransactionReceipt(transactionId) ;: Αυτή η γραμμή χρησιμοποιεί τη μέθοδο web3js για την ανάκτηση της απόδειξης συναλλαγής για το αναγνωριστικό συναλλαγής που έχει εισαχθεί.
  4. Ελέγξτε για παραλαβή :
    • if (!receipt) { throw new Error("Transaction not found!"); } : Εάν η απόδειξη δεν βρεθεί (δηλαδή, η απόδειξη είναι null ή undefined ), εμφανίζεται ένα σφάλμα με το μήνυμα "Η συναλλαγή δεν βρέθηκε!".
  5. Ορισμός λεπτομερειών συναλλαγής :
    • setTransactionDetails(receipt) : Εάν βρεθεί η απόδειξη, ενημερώνει την κατάσταση transactionDetails με την απόδειξη που έχει ληφθεί.
  6. Χειρισμός σφαλμάτων :
    • 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"); };
  1. Ελέγξτε για λεπτομέρειες συναλλαγής :
    • if (!transactionDetails) return; : Αυτό ελέγχει εάν transactionDetails είναι null ή undefined . Εάν είναι, η συνάρτηση επιστρέφει νωρίς και δεν κάνει τίποτα.


  2. Στοιχεία συναλλαγής Destructure :
    • const { transactionHash, from, to, cumulativeGasUsed, blockNumber, contractAddress } = transactionDetails; : Αυτό καταστρέφει το αντικείμενο transactionDetails για εξαγωγή μεμονωμένων ιδιοτήτων για ευκολότερη πρόσβαση.


  3. Δημιουργία εγγράφου PDF :
    • const pdf = new jsPDF() : Αυτό δημιουργεί μια νέα παρουσία της κλάσης jsPDF, η οποία αντιπροσωπεύει ένα έγγραφο PDF.


  4. Ορισμός μεγέθους γραμματοσειράς και προσθήκη τίτλου :
    • pdf.setFontSize(16) : Αυτό ορίζει το μέγεθος γραμματοσειράς της επικεφαλίδας σε 16.

    • pdf.text("Transaction Receipt", 10, 10); : Αυτό προσθέτει τον τίτλο "Απόδειξη συναλλαγής" στις συντεταγμένες (10, 10) στο έγγραφο PDF.


  5. Προσθήκη στοιχείων συναλλαγής σε 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(Cumulative Gas Used: ${cumulativeGasUsed} , 10, 60); : Αυτό προσθέτει το αθροιστικό αέριο που χρησιμοποιείται στις συντεταγμένες (10, 60).

    • pdf.text(Block Number: ${blockNumber}, 10, 70); : Αυτό προσθέτει τον αριθμό μπλοκ στις συντεταγμένες (10, 70).


  6. Αποθήκευση εγγράφου PDF :
    • pdf.save("Transaction_Receipt.pdf");: Αυτό θα αποθηκεύσει το έγγραφο PDF με το όνομα αρχείου "Transaction_Receipt.pdf" .

Η διεπαφή χρήστη

Εδώ θα αποδώσετε αυτά τα λειτουργικά στοιχεία ως διεπαφή χρήστη στους χρήστες.

Αυτός ο κώδικας έχει ήδη συμπεριλάβει το στυλ χρησιμοποιώντας το 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

Διαδήλωση

Σύναψη

Σε αυτό το άρθρο, μπορέσατε να δημιουργήσετε μια γεννήτρια αποδείξεων σε κώδικα PDF ή QR χρησιμοποιώντας τη μέθοδο Rootstock API Key and RPC. Έτσι, στο επόμενο έργο σας dApp, ελπίζω να δω αυτό το χαρακτηριστικό σε αυτό.