Verwendung von Stealth-Adressen
Sie sind Bill. Aus Gründen, auf die wir hier nicht näher eingehen, möchten Sie für die Kampagne „Alice for Queen of the World“ spenden und Alice wissen lassen, dass Sie gespendet haben, damit sie Sie belohnt, falls sie gewinnt. Leider ist ihr Sieg nicht garantiert. Es gibt eine konkurrierende Kampagne: „Carol for Empress of the Solar System“. Wenn Carol gewinnt und herausfindet, dass Sie an Alice gespendet haben, stecken Sie in Schwierigkeiten. Sie können also nicht einfach 200 ETH von Ihrem Konto auf das von Alice überweisen.
ERC-5564 (opens in a new tab) bietet die Lösung. Dieser ERC erklärt, wie man Stealth-Adressen (opens in a new tab) für anonyme Übertragungen verwendet.
Warnung: Die Kryptografie hinter Stealth-Adressen ist, soweit wir wissen, solide. Es gibt jedoch potenzielle Seitenkanalangriffe. Unten werden Sie sehen, was Sie tun können, um dieses Risiko zu verringern.
Wie Stealth-Adressen funktionieren
Dieser Artikel wird versuchen, Stealth-Adressen auf zwei Arten zu erklären. Die erste ist, wie man sie verwendet. Dieser Teil reicht aus, um den Rest des Artikels zu verstehen. Danach folgt eine Erklärung der dahinterstehenden Mathematik. Wenn Sie sich für Kryptografie interessieren, lesen Sie auch diesen Teil.
Die einfache Version (wie man Stealth-Adressen verwendet)
Alice erstellt zwei Private-Keys und veröffentlicht die entsprechenden Public-Keys (die zu einer einzigen Meta-Adresse doppelter Länge kombiniert werden können). Bill erstellt ebenfalls einen Private-Key und veröffentlicht den entsprechenden Public-Key.
Unter Verwendung des Public-Keys der einen Partei und des Private-Keys der anderen kann man ein gemeinsames Geheimnis ableiten, das nur Alice und Bill bekannt ist (es kann nicht allein aus den Public-Keys abgeleitet werden). Mit diesem gemeinsamen Geheimnis erhält Bill die Stealth-Adresse und kann Vermögenswerte dorthin senden.
Alice erhält die Adresse ebenfalls aus dem gemeinsamen Geheimnis, aber da sie die Private-Keys zu den von ihr veröffentlichten Public-Keys kennt, kann sie auch den Private-Key erhalten, der es ihr ermöglicht, von dieser Adresse abzuheben.
Die Mathematik (warum Stealth-Adressen so funktionieren)
Standard-Stealth-Adressen verwenden Elliptische-Kurven-Kryptografie (ECC) (opens in a new tab), um eine bessere Leistung mit weniger Schlüsselbits zu erzielen und gleichzeitig das gleiche Sicherheitsniveau beizubehalten. Aber größtenteils können wir das ignorieren und so tun, als würden wir normale Arithmetik verwenden.
Es gibt eine Zahl, die jeder kennt, G. Man kann mit G multiplizieren. Aber aufgrund der Natur von ECC ist es praktisch unmöglich, durch G zu dividieren. Die Art und Weise, wie Public-Key-Kryptografie in Ethereum im Allgemeinen funktioniert, besteht darin, dass man einen Private-Key, Ppriv, verwenden kann, um Transaktionen zu signieren, die dann durch einen Public-Key, Ppub = GPpriv, verifiziert werden.
Alice erstellt zwei Private-Keys, Kpriv und Vpriv. Kpriv wird verwendet, um Geld von der Stealth-Adresse auszugeben, und Vpriv, um die Adressen einzusehen, die Alice gehören. Alice veröffentlicht dann die Public-Keys: Kpub = GKpriv und Vpub = GVpriv
Bill erstellt einen dritten Private-Key, Rpriv, und veröffentlicht Rpub = GRpriv in einer zentralen Registratur (Bill hätte ihn auch an Alice senden können, aber wir gehen davon aus, dass Carol mithört).
Bill berechnet RprivVpub = GRprivVpriv, wovon er ausgeht, dass Alice es ebenfalls kennt (wird unten erklärt). Dieser Wert wird S genannt, das gemeinsame Geheimnis. Dies gibt Bill einen Public-Key, Ppub = Kpub+G*hash(S). Aus diesem Public-Key kann er eine Adresse berechnen und beliebige Ressourcen dorthin senden. Wenn Alice in Zukunft gewinnt, kann Bill ihr Rpriv mitteilen, um zu beweisen, dass die Ressourcen von ihm stammen.
Alice berechnet RpubVpriv = GRprivVpriv. Dies gibt ihr dasselbe gemeinsame Geheimnis, S. Da sie den Private-Key, Kpriv, kennt, kann sie Ppriv = Kpriv+hash(S) berechnen. Dieser Schlüssel ermöglicht ihr den Zugriff auf Vermögenswerte in der Adresse, die sich aus Ppub = GPpriv = GKpriv+G*hash(S) = Kpub+G*hash(S) ergibt.
Wir haben einen separaten Ansichtsschlüssel (Viewing Key), um es Alice zu ermöglichen, Dave's World Domination Campaign Services als Subunternehmer zu beauftragen. Alice ist bereit, Dave die öffentlichen Adressen wissen zu lassen und sie zu informieren, wenn mehr Geld verfügbar ist, aber sie möchte nicht, dass er ihr Kampagnengeld ausgibt.
Da für das Einsehen und Ausgeben separate Schlüssel verwendet werden, kann Alice Dave Vpriv geben. Dann kann Dave S = RpubVpriv = GRprivVpriv berechnen und auf diese Weise die Public-Keys (Ppub = Kpub+G*hash(S)) erhalten. Aber ohne Kpriv kann Dave den Private-Key nicht erhalten.
Zusammenfassend sind dies die Werte, die den verschiedenen Teilnehmern bekannt sind.
| Alice | Veröffentlicht | Bill | Dave |
|---|---|---|---|
| G | G | G | G |
| Kpriv | - | - | - |
| Vpriv | - | - | Vpriv |
| Kpub = GKpriv | Kpub | Kpub | Kpub |
| Vpub = GVpriv | Vpub | Vpub | Vpub |
| - | - | Rpriv | - |
| Rpub | Rpub | Rpub = GRpriv | Rpub |
| S = RpubVpriv = GRprivVpriv | - | S = RprivVpub = GRprivVpriv | S = RpubVpriv = GRprivVpriv |
| Ppub = Kpub+G*hash(S) | - | Ppub = Kpub+G*hash(S) | Ppub = Kpub+G*hash(S) |
| Adresse=f(Ppub) | - | Adresse=f(Ppub) | Adresse=f(Ppub) |
| Ppriv = Kpriv+hash(S) | - | - | - |
Wenn Stealth-Adressen schiefgehen
Es gibt keine Geheimnisse auf der Blockchain. Während Stealth-Adressen Ihnen Privatsphäre bieten können, ist diese Privatsphäre anfällig für Verkehrsanalysen. Um ein triviales Beispiel zu wählen: Stellen Sie sich vor, Bill finanziert eine Adresse und sendet sofort eine Transaktion, um einen Rpub-Wert zu veröffentlichen. Ohne Alices Vpriv können wir nicht sicher sein, dass dies eine Stealth-Adresse ist, aber es ist sehr wahrscheinlich. Dann sehen wir eine weitere Transaktion, die alle ETH von dieser Adresse auf die Adresse von Alices Kampagnenfonds überträgt. Wir können es vielleicht nicht beweisen, aber es ist wahrscheinlich, dass Bill gerade für Alices Kampagne gespendet hat. Carol würde das sicherlich denken.
Es ist für Bill einfach, die Veröffentlichung von Rpub von der Finanzierung der Stealth-Adresse zu trennen (dies zu unterschiedlichen Zeiten und von unterschiedlichen Adressen aus zu tun). Das ist jedoch unzureichend. Das Muster, nach dem Carol sucht, ist, dass Bill eine Adresse finanziert und dann Alices Kampagnenfonds davon abhebt.
Eine Lösung besteht darin, dass Alices Kampagne das Geld nicht direkt abhebt, sondern es verwendet, um einen Dritten zu bezahlen. Wenn Alices Kampagne 10 ETH an Dave's World Domination Campaign Services sendet, weiß Carol nur, dass Bill an einen von Daves Kunden gespendet hat. Wenn Dave genug Kunden hat, könnte Carol nicht wissen, ob Bill an Alice gespendet hat, die mit ihr konkurriert, oder an Adam, Albert oder Abigail, die Carol egal sind. Alice kann der Zahlung einen gehashten Wert beifügen und Dave dann das Urbild (Preimage) zur Verfügung stellen, um zu beweisen, dass es ihre Spende war. Alternativ, wie oben angemerkt, weiß Dave bereits, von wem die Zahlung kam, wenn Alice ihm ihr Vpriv gibt.
Das Hauptproblem bei dieser Lösung ist, dass sie erfordert, dass Alice sich um Geheimhaltung kümmert, wenn diese Geheimhaltung Bill zugutekommt. Alice möchte vielleicht ihren Ruf wahren, damit Bills Freund Bob ebenfalls an sie spendet. Aber es ist auch möglich, dass es ihr nichts ausmachen würde, Bill bloßzustellen, weil er dann Angst davor hat, was passiert, wenn Carol gewinnt. Bill könnte am Ende Alice noch mehr Unterstützung zukommen lassen.
Verwendung mehrerer Stealth-Ebenen
Anstatt sich darauf zu verlassen, dass Alice Bills Privatsphäre wahrt, kann Bill dies selbst tun. Er kann mehrere Meta-Adressen für fiktive Personen, Bob und Bella, generieren. Bill sendet dann ETH an Bob, und „Bob“ (der eigentlich Bill ist) sendet sie an Bella. „Bella“ (ebenfalls Bill) sendet sie an Alice.
Carol kann immer noch eine Verkehrsanalyse durchführen und die Pipeline von Bill zu Bob zu Bella zu Alice sehen. Wenn „Bob“ und „Bella“ jedoch ETH auch für andere Zwecke verwenden, wird es nicht so aussehen, als hätte Bill etwas an Alice übertragen, selbst wenn Alice sofort von der Stealth-Adresse auf ihre bekannte Kampagnenadresse abhebt.
Schreiben einer Stealth-Adressen-Anwendung
Dieser Artikel erklärt eine Stealth-Adressen-Anwendung, die auf GitHub verfügbar ist (opens in a new tab).
Werkzeuge
Es gibt eine Typescript-Stealth-Adressen-Bibliothek (opens in a new tab), die wir verwenden könnten. Kryptografische Operationen können jedoch CPU-intensiv sein. Ich ziehe es vor, sie in einer kompilierten Sprache wie Rust (opens in a new tab) zu implementieren und WASM (opens in a new tab) zu verwenden, um den Code im Browser auszuführen.
Wir werden Vite (opens in a new tab) und React (opens in a new tab) verwenden. Dies sind branchenübliche Werkzeuge; wenn Sie nicht mit ihnen vertraut sind, können Sie dieses Tutorial verwenden. Um Vite zu verwenden, benötigen wir Node.
Stealth-Adressen in Aktion sehen
-
Installieren Sie die erforderlichen Werkzeuge: Rust (opens in a new tab) und Node (opens in a new tab).
-
Klonen Sie das GitHub-Repository.
1git clone https://github.com/qbzzt/251022-stealth-addresses.git2cd 251022-stealth-addresses
123. Installieren Sie die Voraussetzungen und kompilieren Sie den Rust-Code.34 ```sh5 cd src/rust-wasm6 rustup target add wasm32-unknown-unknown 7 cargo install wasm-pack 8 wasm-pack build --target web-
Starten Sie den Webserver.
1cd ../..2npm install3npm run dev
125. Navigieren Sie zu [der Anwendung](http://localhost:5173/). Diese Anwendungsseite hat zwei Frames: einen für Alices Benutzeroberfläche und den anderen für Bills. Die beiden Frames kommunizieren nicht miteinander; sie befinden sich nur der Einfachheit halber auf derselben Seite.346. Klicken Sie als Alice auf **Generate a Stealth Meta-Address**. Dadurch werden die neue Stealth-Adresse und die entsprechenden Private-Keys angezeigt. Kopieren Sie die Stealth-Meta-Adresse in die Zwischenablage.567. Fügen Sie als Bill die neue Stealth-Meta-Adresse ein und klicken Sie auf **Generate an address**. Dies gibt Ihnen die Adresse, die Sie für Alice finanzieren können. 788. Kopieren Sie die Adresse und Bills Public-Key und fügen Sie sie in den Bereich „Private key for address generated by Bill“ von Alices Benutzeroberfläche ein. Sobald diese Felder ausgefüllt sind, sehen Sie den Private-Key, um auf die Vermögenswerte an dieser Adresse zuzugreifen.9109. Sie können [einen Online-Rechner](https://iancoleman.net/ethereum-private-key-to-address/) verwenden, um sicherzustellen, dass der Private-Key der Adresse entspricht.1112### Wie das Programm funktioniert \{#how-the-program-works\}1314#### Die WASM-Komponente \{#wasm\}1516Der Quellcode, der in WASM kompiliert wird, ist in [Rust](https://rust-lang.org/) geschrieben. Sie können ihn in [`src/rust_wasm/src/lib.rs`](https://github.com/qbzzt/251022-stealth-addresses/blob/main/src/rust-wasm/src/lib.rs) sehen. Dieser Code ist in erster Linie eine Schnittstelle zwischen dem JavaScript-Code und [der `eth-stealth-addresses`-Bibliothek](https://github.com/kassandraoftroy/eth-stealth-addresses).1718**`Cargo.toml`**1920[`Cargo.toml`](https://doc.rust-lang.org/cargo/reference/manifest.html) in Rust ist analog zu [`package.json`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json) in JavaScript. Es enthält Paketinformationen, Abhängigkeitsdeklarationen usw.2122```toml23[package]24name = "rust-wasm"25version = "0.1.0"26edition = "2024"2728[dependencies]29eth-stealth-addresses = "0.1.0"30hex = "0.4.3"31wasm-bindgen = "0.2.104"32getrandom = { version = "0.2", features = ["js"] }Alle anzeigenDas Paket getrandom (opens in a new tab) muss Zufallswerte generieren. Das kann nicht durch rein algorithmische Mittel geschehen; es erfordert den Zugriff auf einen physikalischen Prozess als Entropiequelle. Diese Definition legt fest, dass wir diese Entropie erhalten, indem wir den Browser abfragen, in dem wir ausgeführt werden.
1console_error_panic_hook = "0.1.7"Diese Bibliothek (opens in a new tab) gibt uns aussagekräftigere Fehlermeldungen, wenn der WASM-Code in Panik gerät (panics) und nicht fortgesetzt werden kann.
1[lib]2crate-type = ["cdylib", "rlib"]Der Ausgabetyp, der erforderlich ist, um WASM-Code zu erzeugen.
lib.rs
Dies ist der eigentliche Rust-Code.
1use wasm_bindgen::prelude::*;Die Definitionen, um ein WASM-Paket aus Rust zu erstellen. Sie sind hier (opens in a new tab) dokumentiert.
1use eth_stealth_addresses::{2 generate_stealth_meta_address,3 generate_stealth_address,4 compute_stealth_key5};Die Funktionen, die wir aus der eth-stealth-addresses-Bibliothek (opens in a new tab) benötigen.
1use hex::{decode,encode};Rust verwendet typischerweise Byte-Arrays (opens in a new tab) ([u8; <size>]) für Werte. Aber in JavaScript verwenden wir typischerweise hexadezimale Zeichenfolgen. Die hex-Bibliothek (opens in a new tab) übersetzt für uns von einer Darstellung in die andere.
1#[wasm_bindgen]Generieren Sie WASM-Bindungen, um diese Funktion aus JavaScript aufrufen zu können.
1pub fn wasm_generate_stealth_meta_address() -> String {Der einfachste Weg, ein Objekt mit mehreren Feldern zurückzugeben, ist die Rückgabe eines JSON-Strings.
1 let (address, spend_private_key, view_private_key) = 2 generate_stealth_meta_address();Die Funktion generate_stealth_meta_address (opens in a new tab) gibt drei Felder zurück:
- Die Meta-Adresse (Kpub und Vpub)
- Den Ansichts-Private-Key (Vpriv)
- Den Ausgabe-Private-Key (Kpriv)
Die Tupel (opens in a new tab)-Syntax ermöglicht es uns, diese Werte wieder zu trennen.
1 format!("{{\"address\":\"{}\",\"view_private_key\":\"{}\",\"spend_private_key\":\"{}\"}}",2 encode(address),3 encode(view_private_key),4 encode(spend_private_key)5 )6}Verwenden Sie das Makro format! (opens in a new tab), um den JSON-codierten String zu generieren. Verwenden Sie hex::encode (opens in a new tab), um die Arrays in Hex-Strings umzuwandeln.
1fn str_to_array<const N: usize>(s: &str) -> Option<[u8; N]> {Diese Funktion wandelt einen Hex-String (bereitgestellt von JavaScript) in ein Byte-Array um. Wir verwenden sie, um Werte zu parsen, die vom JavaScript-Code bereitgestellt werden. Diese Funktion ist kompliziert, da Rust Arrays und Vektoren auf eine bestimmte Weise handhabt.
Der Ausdruck <const N: usize> wird als Generikum (Generic) (opens in a new tab) bezeichnet. N ist ein Parameter, der die Länge des zurückgegebenen Arrays steuert. Die Funktion heißt eigentlich str_to_array::<n>, wobei n die Array-Länge ist.
Der Rückgabewert ist Option<[u8; N]>, was bedeutet, dass das zurückgegebene Array optional (opens in a new tab) ist. Dies ist ein typisches Muster in Rust für Funktionen, die fehlschlagen können.
Wenn wir beispielsweise str_to_array::10("bad060a7") aufrufen, soll die Funktion ein Array mit zehn Werten zurückgeben, aber die Eingabe ist nur vier Bytes lang. Die Funktion muss fehlschlagen, und das tut sie, indem sie None zurückgibt. Der Rückgabewert für str_to_array::4("bad060a7") wäre Some<[0xba, 0xd0, 0x60, 0xa7]>.
1 // decode gibt Result<Vec<u8>, _> zurück2 let vec = decode(s).ok()?;Die Funktion hex::decode (opens in a new tab) gibt ein Result<Vec<u8>, FromHexError> zurück. Der Typ Result (opens in a new tab) kann entweder ein erfolgreiches Ergebnis (Ok(value)) oder einen Fehler (Err(error)) enthalten.
Die Methode .ok() wandelt das Result in eine Option um, deren Wert entweder der Ok()-Wert ist, wenn sie erfolgreich war, oder None, wenn nicht. Schließlich bricht der Fragezeichen-Operator (opens in a new tab) die aktuellen Funktionen ab und gibt ein None zurück, wenn die Option leer ist. Andernfalls entpackt er den Wert und gibt ihn zurück (in diesem Fall, um vec einen Wert zuzuweisen).
Dies sieht nach einer seltsam komplizierten Methode zur Fehlerbehandlung aus, aber Result und Option stellen sicher, dass alle Fehler auf die eine oder andere Weise behandelt werden.
1 if vec.len() != N { return None; }Wenn die Anzahl der Bytes falsch ist, ist das ein Fehler, und wir geben None zurück.
1 // try_into verbraucht vec und versucht, [u8; N] zu erstellen2 let array: [u8; N] = vec.try_into().ok()?;Rust hat zwei Array-Typen. Arrays (opens in a new tab) haben eine feste Größe. Vektoren (opens in a new tab) können wachsen und schrumpfen. hex::decode gibt einen Vektor zurück, aber die eth_stealth_addresses-Bibliothek möchte Arrays empfangen. .try_into() (opens in a new tab) konvertiert einen Wert in einen anderen Typ, zum Beispiel einen Vektor in ein Array.
1 Some(array)2}Rust verlangt nicht, dass Sie das Schlüsselwort return (opens in a new tab) verwenden, wenn Sie am Ende einer Funktion einen Wert zurückgeben.
1#[wasm_bindgen]2pub fn wasm_generate_stealth_address(stealth_address: &str) -> Option<String> {Diese Funktion empfängt eine öffentliche Meta-Adresse, die sowohl Vpub als auch Kpub enthält. Sie gibt die Stealth-Adresse, den zu veröffentlichenden Public-Key (Rpub) und einen Ein-Byte-Scanwert zurück, der die Identifizierung beschleunigt, welche veröffentlichten Adressen zu Alice gehören könnten.
Der Scanwert ist Teil des gemeinsamen Geheimnisses (S = GRprivVpriv). Dieser Wert steht Alice zur Verfügung, und seine Überprüfung ist viel schneller als die Überprüfung, ob f(Kpub+G*hash(S)) der veröffentlichten Adresse entspricht.
1 let (address, r_pub, scan) = 2 generate_stealth_address(&str_to_array::<66>(stealth_address)?);Wir verwenden die Funktion generate_stealth_address (opens in a new tab) der Bibliothek.
1 format!("{{\"address\":\"{}\",\"rPub\":\"{}\",\"scan\":\"{}\"}}",2 encode(address),3 encode(r_pub),4 encode(&[scan])5 ).into()6}Bereiten Sie den JSON-codierten Ausgabe-String vor.
1#[wasm_bindgen]2pub fn wasm_compute_stealth_key(3 address: &str, 4 bill_pub_key: &str, 5 view_private_key: &str,6 spend_private_key: &str 7) -> Option<String> {8 .9 .10 .11}Alle anzeigenDiese Funktion verwendet die Funktion compute_stealth_key (opens in a new tab) der Bibliothek, um den Private-Key zum Abheben von der Adresse (Rpriv) zu berechnen. Diese Berechnung erfordert diese Werte:
- Die Adresse (Adresse=f(Ppub))
- Den von Bill generierten Public-Key (Rpub)
- Den Ansichts-Private-Key (Vpriv)
- Den Ausgabe-Private-Key (Kpriv)
1#[wasm_bindgen(start)]#[wasm_bindgen(start)] (opens in a new tab) gibt an, dass die Funktion ausgeführt wird, wenn der WASM-Code initialisiert wird.
1pub fn main() {2 console_error_panic_hook::set_once();3}Dieser Code legt fest, dass die Panic-Ausgabe an die JavaScript-Konsole gesendet wird. Um dies in Aktion zu sehen, verwenden Sie die Anwendung und geben Sie Bill eine ungültige Meta-Adresse (ändern Sie einfach eine hexadezimale Ziffer). Sie werden diesen Fehler in der JavaScript-Konsole sehen:
1rust_wasm.js:236 panicked at /home/ori/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs:701:9:2assertion `left == right` failed3 left: 04 right: 1Gefolgt von einem Stacktrace. Geben Sie Bill dann die gültige Meta-Adresse und geben Sie Alice entweder eine ungültige Adresse oder einen ungültigen Public-Key. Sie werden diesen Fehler sehen:
1rust_wasm.js:236 panicked at /home/ori/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/eth-stealth-addresses-0.1.0/src/lib.rs:78:9:2keys do not generate stealth addressWieder gefolgt von einem Stacktrace.
Die Benutzeroberfläche
Die Benutzeroberfläche ist mit React (opens in a new tab) geschrieben und wird von Vite (opens in a new tab) bereitgestellt. Sie können mehr darüber in diesem Tutorial erfahren. Hier besteht kein Bedarf an WAGMI (opens in a new tab), da wir nicht direkt mit einer Blockchain oder einem Wallet interagieren.
Der einzige nicht offensichtliche Teil der Benutzeroberfläche ist die WASM-Konnektivität. Hier ist, wie sie funktioniert.
vite.config.js
Diese Datei enthält die Vite-Konfiguration (opens in a new tab).
1import { defineConfig } from 'vite'2import react from '@vitejs/plugin-react'3import wasm from "vite-plugin-wasm";45// https://vite.dev/config/6export default defineConfig({7 plugins: [react(), wasm()],8})Wir benötigen zwei Vite-Plugins: react (opens in a new tab) und wasm (opens in a new tab).
App.jsx
Diese Datei ist die Hauptkomponente der Anwendung. Sie ist ein Container, der zwei Komponenten enthält: Alice und Bill, die Benutzeroberflächen für diese Benutzer. Der relevante Teil für WASM ist der Initialisierungscode.
1import init from './rust-wasm/pkg/rust_wasm.js'Wenn wir wasm-pack (opens in a new tab) verwenden, erstellt es zwei Dateien, die wir hier verwenden: eine wasm-Datei mit dem eigentlichen Code (hier src/rust-wasm/pkg/rust_wasm_bg.wasm) und eine JavaScript-Datei mit den Definitionen zu deren Verwendung (hier src/rust_wasm/pkg/rust_wasm.js). Der Standardexport dieser JavaScript-Datei ist Code, der ausgeführt werden muss, um WASM zu initiieren.
1function App() {2 .3 .4 .5 useEffect(() => {6 const loadWasm = async () => {7 try {8 await init();9 setWasmReady(true)10 } catch (err) {11 console.error('Error loading wasm:', err)12 alert("Wasm error: " + err)13 }14 }1516 loadWasm()17 }, []18 )Alle anzeigenDer useEffect-Hook (opens in a new tab) ermöglicht es Ihnen, eine Funktion anzugeben, die ausgeführt wird, wenn sich Zustandsvariablen ändern. Hier ist die Liste der Zustandsvariablen leer ([]), sodass diese Funktion nur einmal beim Laden der Seite ausgeführt wird.
Die Effektfunktion muss sofort zurückkehren. Um asynchronen Code zu verwenden, wie z. B. das WASM-init (das die .wasm-Datei laden muss und daher Zeit in Anspruch nimmt), definieren wir eine interne async (opens in a new tab)-Funktion und führen sie ohne ein await aus.
Bill.jsx
Dies ist die Benutzeroberfläche für Bill. Sie hat eine einzige Aktion: das Erstellen einer Adresse basierend auf der von Alice bereitgestellten Stealth-Meta-Adresse.
1import { wasm_generate_stealth_address } from './rust-wasm/pkg/rust_wasm.js'Zusätzlich zum Standardexport exportiert der von wasm-pack generierte JavaScript-Code eine Funktion für jede Funktion im WASM-Code.
1 <button onClick={() => {2 setPublicAddress(JSON.parse(wasm_generate_stealth_address(stealthMetaAddress)))3 }}>Um WASM-Funktionen aufzurufen, rufen wir einfach die Funktion auf, die von der durch wasm-pack erstellten JavaScript-Datei exportiert wird.
Alice.jsx
Der Code in Alice.jsx ist analog, außer dass Alice zwei Aktionen hat:
- Eine Meta-Adresse generieren
- Den Private-Key für eine von Bill veröffentlichte Adresse abrufen
Fazit
Stealth-Adressen sind kein Allheilmittel; sie müssen korrekt verwendet werden. Aber wenn sie richtig eingesetzt werden, können sie Privatsphäre auf einer öffentlichen Blockchain ermöglichen.
Sehen Sie hier für weitere meiner Arbeiten (opens in a new tab).
Letzte Aktualisierung der Seite: 14. November 2025