Menggunakan Alamat Siluman
Anda adalah Bill. Untuk alasan yang tidak akan kita bahas, Anda ingin berdonasi ke kampanye "Alice untuk Ratu Dunia" dan ingin Alice tahu bahwa Anda berdonasi sehingga dia akan memberi Anda hadiah jika dia menang. Sayangnya, kemenangannya tidak dijamin. Ada kampanye pesaing, "Carol untuk Permaisuri Tata Surya". Jika Carol menang, dan dia tahu Anda berdonasi kepada Alice, Anda akan mendapat masalah. Jadi Anda tidak bisa begitu saja mentransfer 200 ETH dari akun Anda ke akun Alice.
ERC-5564 (opens in a new tab) memiliki solusinya. ERC ini menjelaskan cara menggunakan alamat siluman (opens in a new tab) untuk transfer anonim.
Peringatan: Kriptografi di balik alamat siluman, sejauh yang kami tahu, aman. Namun, ada potensi serangan saluran sampingan (side-channel attacks). Di bawah ini, Anda akan melihat apa yang dapat Anda lakukan untuk mengurangi risiko ini.
Cara kerja alamat siluman
Artikel ini akan mencoba menjelaskan alamat siluman dengan dua cara. Yang pertama adalah cara menggunakannya. Bagian ini cukup untuk memahami sisa artikel. Kemudian, ada penjelasan tentang matematika di baliknya. Jika Anda tertarik dengan kriptografi, bacalah bagian ini juga.
Versi sederhana (cara menggunakan alamat siluman)
Alice membuat dua kunci pribadi dan mempublikasikan kunci publik yang sesuai (yang dapat digabungkan menjadi satu alamat meta dengan panjang ganda). Bill juga membuat kunci pribadi dan mempublikasikan kunci publik yang sesuai.
Dengan menggunakan kunci publik satu pihak dan kunci pribadi pihak lain, Anda dapat memperoleh rahasia bersama yang hanya diketahui oleh Alice dan Bill (ini tidak dapat diperoleh dari kunci publik saja). Dengan menggunakan rahasia bersama ini, Bill mendapatkan alamat siluman dan dapat mengirimkan aset ke alamat tersebut.
Alice juga mendapatkan alamat dari rahasia bersama tersebut, tetapi karena dia mengetahui kunci pribadi dari kunci publik yang dia publikasikan, dia juga bisa mendapatkan kunci pribadi yang memungkinkannya menarik dana dari alamat tersebut.
Matematika (mengapa alamat siluman bekerja seperti ini)
Alamat siluman standar menggunakan kriptografi kurva eliptik (ECC) (opens in a new tab) untuk mendapatkan kinerja yang lebih baik dengan bit kunci yang lebih sedikit, sambil tetap menjaga tingkat keamanan yang sama. Namun sebagian besar kita dapat mengabaikannya dan berpura-pura menggunakan aritmatika biasa.
Ada angka yang diketahui semua orang, G. Anda dapat mengalikannya dengan G. Tetapi karena sifat ECC, hampir tidak mungkin untuk membaginya dengan G. Cara kerja kriptografi kunci publik secara umum di Ethereum adalah Anda dapat menggunakan kunci pribadi, Ppriv, untuk menandatangani transaksi yang kemudian diverifikasi oleh kunci publik, Ppub = GPpriv.
Alice membuat dua kunci pribadi, Kpriv dan Vpriv. Kpriv akan digunakan untuk membelanjakan uang dari alamat siluman, dan Vpriv untuk melihat alamat yang dimiliki oleh Alice. Alice kemudian mempublikasikan kunci publik: Kpub = GKpriv dan Vpub = GVpriv
Bill membuat kunci pribadi ketiga, Rpriv, dan mempublikasikan Rpub = GRpriv ke registri pusat (Bill juga bisa mengirimkannya ke Alice, tetapi kita asumsikan Carol sedang mendengarkan).
Bill menghitung RprivVpub = GRprivVpriv, yang dia harapkan Alice juga mengetahuinya (dijelaskan di bawah). Nilai ini disebut S, rahasia bersama. Ini memberi Bill sebuah kunci publik, Ppub = Kpub+G*hash(S). Dari kunci publik ini, dia dapat menghitung sebuah alamat dan mengirimkan sumber daya apa pun yang dia inginkan ke alamat tersebut. Di masa depan, jika Alice menang, Bill dapat memberitahunya Rpriv untuk membuktikan bahwa sumber daya tersebut berasal darinya.
Alice menghitung RpubVpriv = GRprivVpriv. Ini memberinya rahasia bersama yang sama, S. Karena dia mengetahui kunci pribadi, Kpriv, dia dapat menghitung Ppriv = Kpriv+hash(S). Kunci ini memungkinkannya mengakses aset di alamat yang dihasilkan dari Ppub = GPpriv = GKpriv+G*hash(S) = Kpub+G*hash(S).
Kita memiliki kunci tampilan (viewing key) terpisah untuk memungkinkan Alice melakukan subkontrak ke Layanan Kampanye Dominasi Dunia Dave. Alice bersedia memberi tahu Dave alamat publik dan menginformasikannya ketika ada lebih banyak uang yang tersedia, tetapi dia tidak ingin Dave menghabiskan uang kampanyenya.
Karena melihat dan membelanjakan menggunakan kunci yang terpisah, Alice dapat memberikan Vpriv kepada Dave. Kemudian Dave dapat menghitung S = RpubVpriv = GRprivVpriv dan dengan cara itu mendapatkan kunci publik (Ppub = Kpub+G*hash(S)). Tetapi tanpa Kpriv Dave tidak bisa mendapatkan kunci pribadi.
Singkatnya, ini adalah nilai-nilai yang diketahui oleh berbagai peserta.
| Alice | Dipublikasikan | 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) |
| Alamat=f(Ppub) | - | Alamat=f(Ppub) | Alamat=f(Ppub) |
| Ppriv = Kpriv+hash(S) | - | - | - |
Ketika alamat siluman bermasalah
Tidak ada rahasia di blockchain. Meskipun alamat siluman dapat memberi Anda privasi, privasi tersebut rentan terhadap analisis lalu lintas. Sebagai contoh sederhana, bayangkan Bill mendanai sebuah alamat dan segera mengirimkan transaksi untuk mempublikasikan nilai Rpub. Tanpa Vpriv milik Alice, kita tidak bisa yakin bahwa ini adalah alamat siluman, tetapi kemungkinan besar memang begitu. Kemudian, kita melihat transaksi lain yang mentransfer semua ETH dari alamat tersebut ke alamat dana kampanye Alice. Kita mungkin tidak dapat membuktikannya, tetapi kemungkinan besar Bill baru saja berdonasi ke kampanye Alice. Carol pasti akan berpikir begitu.
Sangat mudah bagi Bill untuk memisahkan publikasi Rpub dari pendanaan alamat siluman (lakukan pada waktu yang berbeda, dari alamat yang berbeda). Namun, itu tidak cukup. Pola yang dicari Carol adalah Bill mendanai sebuah alamat, dan kemudian dana kampanye Alice menarik dana darinya.
Salah satu solusinya adalah kampanye Alice tidak menarik uang secara langsung, melainkan menggunakannya untuk membayar pihak ketiga. Jika kampanye Alice mengirimkan 10 ETH ke Layanan Kampanye Dominasi Dunia Dave, Carol hanya tahu bahwa Bill berdonasi ke salah satu pelanggan Dave. Jika Dave memiliki cukup banyak pelanggan, Carol tidak akan dapat mengetahui apakah Bill berdonasi kepada Alice yang bersaing dengannya, atau kepada Adam, Albert, atau Abigail yang tidak dipedulikan Carol. Alice dapat menyertakan nilai yang di-hash dengan pembayaran, dan kemudian memberikan preimage kepada Dave, untuk membuktikan bahwa itu adalah donasinya. Sebagai alternatif, seperti yang dicatat di atas, jika Alice memberikan Vpriv miliknya kepada Dave, dia sudah tahu dari mana pembayaran itu berasal.
Masalah utama dengan solusi ini adalah bahwa hal itu mengharuskan Alice untuk peduli tentang kerahasiaan ketika kerahasiaan itu menguntungkan Bill. Alice mungkin ingin mempertahankan reputasinya sehingga teman Bill, Bob, juga akan berdonasi kepadanya. Tetapi mungkin juga dia tidak keberatan mengekspos Bill, karena dengan begitu Bill akan takut dengan apa yang akan terjadi jika Carol menang. Bill mungkin akhirnya memberikan lebih banyak dukungan kepada Alice.
Menggunakan beberapa lapisan siluman
Daripada mengandalkan Alice untuk menjaga privasi Bill, Bill dapat melakukannya sendiri. Dia dapat menghasilkan beberapa alamat meta untuk orang fiktif, Bob dan Bella. Bill kemudian mengirimkan ETH ke Bob, dan "Bob" (yang sebenarnya adalah Bill) mengirimkannya ke Bella. "Bella" (juga Bill) mengirimkannya ke Alice.
Carol masih dapat melakukan analisis lalu lintas dan melihat jalur Bill-ke-Bob-ke-Bella-ke-Alice. Namun, jika "Bob" dan "Bella" juga menggunakan ETH untuk tujuan lain, tidak akan terlihat bahwa Bill mentransfer apa pun ke Alice, bahkan jika Alice segera menarik dana dari alamat siluman ke alamat kampanyenya yang diketahui.
Menulis aplikasi alamat siluman
Artikel ini menjelaskan aplikasi alamat siluman yang tersedia di GitHub (opens in a new tab).
Alat
Ada pustaka alamat siluman typescript (opens in a new tab) yang bisa kita gunakan. Namun, operasi kriptografi dapat memakan banyak CPU. Saya lebih suka mengimplementasikannya dalam bahasa yang dikompilasi, seperti Rust (opens in a new tab), dan menggunakan WASM (opens in a new tab) untuk menjalankan kode di browser.
Kita akan menggunakan Vite (opens in a new tab) dan React (opens in a new tab). Ini adalah alat standar industri; jika Anda tidak terbiasa dengannya, Anda dapat menggunakan tutorial ini. Untuk menggunakan Vite, kita membutuhkan Node.
Melihat alamat siluman beraksi
-
Instal alat yang diperlukan: Rust (opens in a new tab) dan Node (opens in a new tab).
-
Klon repositori GitHub.
1git clone https://github.com/qbzzt/251022-stealth-addresses.git2cd 251022-stealth-addresses
123. Instal prasyarat dan kompilasi kode Rust.34 ```sh5 cd src/rust-wasm6 rustup target add wasm32-unknown-unknown 7 cargo install wasm-pack 8 wasm-pack build --target web-
Mulai server web.
1cd ../..2npm install3npm run dev
125. Telusuri ke [aplikasi](http://localhost:5173/). Halaman aplikasi ini memiliki dua bingkai: satu untuk antarmuka pengguna Alice dan yang lainnya untuk Bill. Kedua bingkai tidak berkomunikasi; mereka hanya berada di halaman yang sama untuk kenyamanan.346. Sebagai Alice, klik **Generate a Stealth Meta-Address**. Ini akan menampilkan alamat siluman baru dan kunci pribadi yang sesuai. Salin alamat meta siluman ke papan klip.567. Sebagai Bill, tempel alamat meta siluman baru dan klik **Generate an address**. Ini memberi Anda alamat untuk didanai bagi Alice. 788. Salin alamat dan kunci publik Bill dan tempelkan di area "Private key for address generated by Bill" pada antarmuka pengguna Alice. Setelah bidang tersebut diisi, Anda akan melihat kunci pribadi untuk mengakses aset di alamat tersebut.9109. Anda dapat menggunakan [kalkulator online](https://iancoleman.net/ethereum-private-key-to-address/) untuk memastikan kunci pribadi sesuai dengan alamat.1112### Cara kerja program \{#how-the-program-works\}1314#### Komponen WASM \{#wasm\}1516Kode sumber yang dikompilasi menjadi WASM ditulis dalam [Rust](https://rust-lang.org/). Anda dapat melihatnya di [`src/rust_wasm/src/lib.rs`](https://github.com/qbzzt/251022-stealth-addresses/blob/main/src/rust-wasm/src/lib.rs). Kode ini pada dasarnya adalah antarmuka antara kode JavaScript dan [pustaka `eth-stealth-addresses`](https://github.com/kassandraoftroy/eth-stealth-addresses).1718**`Cargo.toml`**1920[`Cargo.toml`](https://doc.rust-lang.org/cargo/reference/manifest.html) di Rust analog dengan [`package.json`](https://docs.npmjs.com/cli/v9/configuring-npm/package-json) di JavaScript. Ini berisi informasi paket, deklarasi dependensi, dll.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"] }Tampilkan semuaPaket getrandom (opens in a new tab) perlu menghasilkan nilai acak. Hal itu tidak dapat dilakukan dengan cara algoritmik murni; ini membutuhkan akses ke proses fisik sebagai sumber entropi. Definisi ini menentukan bahwa kita akan mendapatkan entropi tersebut dengan meminta browser tempat kita menjalankannya.
1console_error_panic_hook = "0.1.7"Pustaka ini (opens in a new tab) memberi kita pesan kesalahan yang lebih bermakna ketika kode WASM panik dan tidak dapat dilanjutkan.
1[lib]2crate-type = ["cdylib", "rlib"]Jenis keluaran yang diperlukan untuk menghasilkan kode WASM.
lib.rs
Ini adalah kode Rust yang sebenarnya.
1use wasm_bindgen::prelude::*;Definisi untuk membuat paket WASM dari Rust. Mereka didokumentasikan di sini (opens in a new tab).
1use eth_stealth_addresses::{2 generate_stealth_meta_address,3 generate_stealth_address,4 compute_stealth_key5};Fungsi yang kita butuhkan dari pustaka eth-stealth-addresses (opens in a new tab).
1use hex::{decode,encode};Rust biasanya menggunakan array (opens in a new tab) byte ([u8; <size>]) untuk nilai. Tetapi di JavaScript, kita biasanya menggunakan string heksadesimal. Pustaka hex (opens in a new tab) menerjemahkan untuk kita dari satu representasi ke representasi lainnya.
1#[wasm_bindgen]Hasilkan binding WASM agar dapat memanggil fungsi ini dari JavaScript.
1pub fn wasm_generate_stealth_meta_address() -> String {Cara termudah untuk mengembalikan objek dengan beberapa bidang adalah dengan mengembalikan string JSON.
1 let (address, spend_private_key, view_private_key) = 2 generate_stealth_meta_address();generate_stealth_meta_address (opens in a new tab) mengembalikan tiga bidang:
- Alamat meta (Kpub dan Vpub)
- Kunci pribadi tampilan (Vpriv)
- Kunci pribadi pembelanjaan (Kpriv)
Sintaks tuple (opens in a new tab) memungkinkan kita memisahkan nilai-nilai tersebut lagi.
1 format!("{{\"address\":\"{}\",\"view_private_key\":\"{}\",\"spend_private_key\":\"{}\"}}",2 encode(address),3 encode(view_private_key),4 encode(spend_private_key)5 )6}Gunakan makro format! (opens in a new tab) untuk menghasilkan string yang dienkode JSON. Gunakan hex::encode (opens in a new tab) untuk mengubah array menjadi string hex.
1fn str_to_array<const N: usize>(s: &str) -> Option<[u8; N]> {Fungsi ini mengubah string hex (disediakan oleh JavaScript) menjadi array byte. Kita menggunakannya untuk mengurai nilai yang disediakan oleh kode JavaScript. Fungsi ini rumit karena cara Rust menangani array dan vektor.
Ekspresi <const N: usize> disebut generik (opens in a new tab). N adalah parameter yang mengontrol panjang array yang dikembalikan. Fungsi ini sebenarnya disebut str_to_array::<n>, di mana n adalah panjang array.
Nilai kembaliannya adalah Option<[u8; N]>, yang berarti array yang dikembalikan bersifat opsional (opens in a new tab). Ini adalah pola khas di Rust untuk fungsi yang mungkin gagal.
Misalnya, jika kita memanggil str_to_array::10("bad060a7"), fungsi tersebut seharusnya mengembalikan array sepuluh nilai, tetapi inputnya hanya empat byte. Fungsi tersebut harus gagal, dan ia melakukannya dengan mengembalikan None. Nilai kembalian untuk str_to_array::4("bad060a7") akan menjadi Some<[0xba, 0xd0, 0x60, 0xa7]>.
1 // decode returns Result<Vec<u8>, _> // decode mengembalikan Result<Vec<u8>, _>2 let vec = decode(s).ok()?;Fungsi hex::decode (opens in a new tab) mengembalikan Result<Vec<u8>, FromHexError>. Tipe Result (opens in a new tab) dapat berisi hasil yang berhasil (Ok(value)) atau kesalahan (Err(error)).
Metode .ok() mengubah Result menjadi Option, yang nilainya adalah nilai Ok() jika berhasil atau None jika tidak. Terakhir, operator tanda tanya (opens in a new tab) membatalkan fungsi saat ini dan mengembalikan None jika Option kosong. Jika tidak, ia membuka nilai dan mengembalikannya (dalam hal ini, untuk menetapkan nilai ke vec).
Ini terlihat seperti metode yang sangat berbelit-belit untuk menangani kesalahan, tetapi Result dan Option memastikan bahwa semua kesalahan ditangani, dengan satu atau lain cara.
1 if vec.len() != N { return None; }Jika jumlah byte salah, itu adalah kegagalan, dan kita mengembalikan None.
1 // try_into consumes vec and attempts to make [u8; N] // try_into mengonsumsi vec dan mencoba membuat [u8; N]2 let array: [u8; N] = vec.try_into().ok()?;Rust memiliki dua tipe array. Array (opens in a new tab) memiliki ukuran tetap. Vektor (opens in a new tab) dapat bertambah dan menyusut. hex::decode mengembalikan vektor, tetapi pustaka eth_stealth_addresses ingin menerima array. .try_into() (opens in a new tab) mengonversi nilai ke tipe lain, misalnya, vektor menjadi array.
1 Some(array)2}Rust tidak mengharuskan Anda menggunakan kata kunci return (opens in a new tab) saat mengembalikan nilai di akhir fungsi.
1#[wasm_bindgen]2pub fn wasm_generate_stealth_address(stealth_address: &str) -> Option<String> {Fungsi ini menerima alamat meta publik, yang mencakup Vpub dan Kpub. Ini mengembalikan alamat siluman, kunci publik untuk dipublikasikan (Rpub), dan nilai pemindaian satu byte yang mempercepat identifikasi alamat mana yang dipublikasikan yang mungkin milik Alice.
Nilai pemindaian adalah bagian dari rahasia bersama (S = GRprivVpriv). Nilai ini tersedia untuk Alice, dan memeriksanya jauh lebih cepat daripada memeriksa apakah f(Kpub+G*hash(S)) sama dengan alamat yang dipublikasikan.
1 let (address, r_pub, scan) = 2 generate_stealth_address(&str_to_array::<66>(stealth_address)?);Kita menggunakan generate_stealth_address (opens in a new tab) dari pustaka.
1 format!("{{\"address\":\"{}\",\"rPub\":\"{}\",\"scan\":\"{}\"}}",2 encode(address),3 encode(r_pub),4 encode(&[scan])5 ).into()6}Siapkan string keluaran yang dienkode JSON.
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}Tampilkan semuaFungsi ini menggunakan compute_stealth_key (opens in a new tab) dari pustaka untuk menghitung kunci pribadi guna menarik dana dari alamat (Rpriv). Perhitungan ini membutuhkan nilai-nilai berikut:
- Alamat (Address=f(Ppub))
- Kunci publik yang dihasilkan oleh Bill (Rpub)
- Kunci pribadi tampilan (Vpriv)
- Kunci pribadi pembelanjaan (Kpriv)
1#[wasm_bindgen(start)]#[wasm_bindgen(start)] (opens in a new tab) menentukan bahwa fungsi dieksekusi saat kode WASM diinisialisasi.
1pub fn main() {2 console_error_panic_hook::set_once();3}Kode ini menentukan bahwa keluaran panik dikirim ke konsol JavaScript. Untuk melihatnya beraksi, gunakan aplikasi dan berikan Bill alamat meta yang tidak valid (cukup ubah satu digit heksadesimal). Anda akan melihat kesalahan ini di konsol JavaScript:
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: 1Diikuti oleh jejak tumpukan (stack trace). Kemudian berikan Bill alamat meta yang valid, dan berikan Alice alamat yang tidak valid atau kunci publik yang tidak valid. Anda akan melihat kesalahan ini:
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 addressSekali lagi, diikuti oleh jejak tumpukan.
Antarmuka Pengguna
Antarmuka pengguna ditulis menggunakan React (opens in a new tab) dan disajikan oleh Vite (opens in a new tab). Anda dapat mempelajarinya menggunakan tutorial ini. Tidak perlu WAGMI (opens in a new tab) di sini karena kita tidak berinteraksi langsung dengan blockchain atau dompet.
Satu-satunya bagian yang tidak jelas dari antarmuka pengguna adalah konektivitas WASM. Begini cara kerjanya.
vite.config.js
File ini berisi konfigurasi Vite (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/ // https://vite.dev/config/6export default defineConfig({7 plugins: [react(), wasm()],8})Kita membutuhkan dua plugin Vite: react (opens in a new tab) dan wasm (opens in a new tab).
App.jsx
File ini adalah komponen utama aplikasi. Ini adalah wadah yang mencakup dua komponen: Alice dan Bill, antarmuka pengguna untuk pengguna tersebut. Bagian yang relevan untuk WASM adalah kode inisialisasi.
1import init from './rust-wasm/pkg/rust_wasm.js'Saat kita menggunakan wasm-pack (opens in a new tab), ia membuat dua file yang kita gunakan di sini: file wasm dengan kode sebenarnya (di sini, src/rust-wasm/pkg/rust_wasm_bg.wasm) dan file JavaScript dengan definisi untuk menggunakannya (di sini, src/rust_wasm/pkg/rust_wasm.js). Ekspor default dari file JavaScript tersebut adalah kode yang perlu dijalankan untuk memulai WASM.
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 )Tampilkan semuaHook useEffect (opens in a new tab) memungkinkan Anda menentukan fungsi yang dieksekusi saat variabel status berubah. Di sini, daftar variabel status kosong ([]), jadi fungsi ini hanya dieksekusi sekali saat halaman dimuat.
Fungsi efek harus segera kembali. Untuk menggunakan kode asinkron, seperti init WASM (yang harus memuat file .wasm dan karenanya membutuhkan waktu) kita mendefinisikan fungsi async (opens in a new tab) internal dan menjalankannya tanpa await.
Bill.jsx
Ini adalah antarmuka pengguna untuk Bill. Ini memiliki satu tindakan, membuat alamat berdasarkan alamat meta siluman yang disediakan oleh Alice.
1import { wasm_generate_stealth_address } from './rust-wasm/pkg/rust_wasm.js'Selain ekspor default, kode JavaScript yang dihasilkan oleh wasm-pack mengekspor fungsi untuk setiap fungsi dalam kode WASM.
1 <button onClick={() => {2 setPublicAddress(JSON.parse(wasm_generate_stealth_address(stealthMetaAddress)))3 }}>Untuk memanggil fungsi WASM, kita cukup memanggil fungsi yang diekspor oleh file JavaScript yang dibuat oleh wasm-pack.
Alice.jsx
Kode di Alice.jsx serupa, kecuali bahwa Alice memiliki dua tindakan:
- Menghasilkan alamat meta
- Mendapatkan kunci pribadi untuk alamat yang dipublikasikan oleh Bill
Kesimpulan
Alamat siluman bukanlah obat mujarab; mereka harus digunakan dengan benar. Tetapi jika digunakan dengan benar, mereka dapat mengaktifkan privasi di blockchain publik.
Lihat di sini untuk karya saya yang lain (opens in a new tab).
Pembaruan terakhir halaman: 14 November 2025