Gizli Adresleri Kullanmak
Siz Bill'siniz. Girmeyeceğimiz nedenlerden dolayı, "Dünya Kraliçesi Alice" kampanyasına bağış yapmak ve Alice'in bağış yaptığınızı bilmesini istiyorsunuz, böylece kazanırsa sizi ödüllendirebilir. Ne yazık ki, zaferi garanti değil. Rakip bir kampanya var: "Güneş Sistemi İmparatoriçesi Carol". Eğer Carol kazanırsa ve Alice'e bağış yaptığınızı öğrenirse, başınız belaya girer. Bu yüzden hesabınızdan Alice'in hesabına öylece 200 ETH transfer edemezsiniz.
ERC-5564 (opens in a new tab) bu sorunun çözümüne sahip. Bu ERC, anonim transfer için gizli adreslerin (opens in a new tab) nasıl kullanılacağını açıklar.
Uyarı: Gizli adreslerin arkasındaki kriptografi, bildiğimiz kadarıyla sağlamdır. Ancak, potansiyel yan kanal saldırıları (side-channel attacks) vardır. Aşağıda, bu riski azaltmak için neler yapabileceğinizi göreceksiniz.
Gizli adresler nasıl çalışır
Bu makale gizli adresleri iki şekilde açıklamaya çalışacaktır. İlki bunların nasıl kullanılacağıdır. Bu kısım, makalenin geri kalanını anlamak için yeterlidir. Ardından, arkasındaki matematiğin bir açıklaması yer almaktadır. Kriptografi ile ilgileniyorsanız, bu kısmı da okuyun.
Basit versiyon (gizli adresler nasıl kullanılır)
Alice iki özel anahtar oluşturur ve bunlara karşılık gelen açık anahtarları (tek bir çift uzunluklu meta-adres halinde birleştirilebilir) yayınlar. Bill de bir özel anahtar oluşturur ve buna karşılık gelen açık anahtarı yayınlar.
Bir tarafın açık anahtarını ve diğerinin özel anahtarını kullanarak, yalnızca Alice ve Bill tarafından bilinen paylaşılan bir sır (shared secret) türetebilirsiniz (yalnızca açık anahtarlardan türetilemez). Bu paylaşılan sırrı kullanarak Bill, gizli adresi elde eder ve ona varlık gönderebilir.
Alice de adresi paylaşılan sırdan alır, ancak yayınladığı açık anahtarların özel anahtarlarını bildiği için, o adresten para çekmesini sağlayan özel anahtarı da elde edebilir.
Matematik (gizli adresler neden böyle çalışır)
Standart gizli adresler, aynı güvenlik seviyesini korurken daha az anahtar bitiyle daha iyi performans elde etmek için eliptik eğri kriptografisi (ECC) (opens in a new tab) kullanır. Ancak çoğunlukla bunu görmezden gelebilir ve normal aritmetik kullanıyormuşuz gibi davranabiliriz.
Herkesin bildiği bir sayı vardır, G. G ile çarpabilirsiniz. Ancak ECC'nin doğası gereği, G'ye bölmek pratik olarak imkansızdır. Ethereum'da açık anahtar kriptografisinin genel çalışma şekli şöyledir: İşlemleri imzalamak için bir özel anahtar, Ppriv, kullanabilirsiniz ve bu işlemler daha sonra bir açık anahtar, Ppub = GPpriv, tarafından doğrulanır.
Alice iki özel anahtar oluşturur, Kpriv ve Vpriv. Kpriv, gizli adresten para harcamak için, Vpriv ise Alice'e ait adresleri görüntülemek için kullanılacaktır. Alice daha sonra açık anahtarları yayınlar: Kpub = GKpriv ve Vpub = GVpriv
Bill üçüncü bir özel anahtar, Rpriv, oluşturur ve Rpub = GRpriv değerini merkezi bir kayıt defterinde yayınlar (Bill bunu Alice'e de gönderebilirdi, ancak Carol'ın dinlediğini varsayıyoruz).
Bill, Alice'in de bilmesini beklediği (aşağıda açıklanmıştır) RprivVpub = GRprivVpriv değerini hesaplar. Bu değere paylaşılan sır olan S denir. Bu, Bill'e bir açık anahtar verir, Ppub = Kpub+G*hash(S). Bu açık anahtardan bir adres hesaplayabilir ve ona istediği kaynakları gönderebilir. Gelecekte, Alice kazanırsa, Bill kaynakların kendisinden geldiğini kanıtlamak için ona Rpriv değerini söyleyebilir.
Alice RpubVpriv = GRprivVpriv değerini hesaplar. Bu ona aynı paylaşılan sırrı, S'yi verir. Özel anahtarı, Kpriv'i bildiği için Ppriv = Kpriv+hash(S) değerini hesaplayabilir. Bu anahtar, Ppub = GPpriv = GKpriv+G*hash(S) = Kpub+G*hash(S) sonucunda ortaya çıkan adresteki varlıklara erişmesini sağlar.
Alice'in Dave'in Dünya Hakimiyeti Kampanya Hizmetleri'ne taşeronluk yapmasına izin vermek için ayrı bir görüntüleme anahtarımız var. Alice, Dave'in açık adresleri bilmesine ve daha fazla para olduğunda onu bilgilendirmesine izin vermeye isteklidir, ancak kampanya parasını harcamasını istemez.
Görüntüleme ve harcama ayrı anahtarlar kullandığından, Alice Dave'e Vpriv verebilir. Ardından Dave S = RpubVpriv = GRprivVpriv hesaplayabilir ve bu şekilde açık anahtarları (Ppub = Kpub+G*hash(S)) elde edebilir. Ancak Kpriv olmadan Dave özel anahtarı alamaz.
Özetlemek gerekirse, farklı katılımcılar tarafından bilinen değerler şunlardır.
| Alice | Yayınlanan | 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) |
| Adres=f(Ppub) | - | Adres=f(Ppub) | Adres=f(Ppub) |
| Ppriv = Kpriv+hash(S) | - | - | - |
Gizli adresler ters gittiğinde
Blokzincir üzerinde sır yoktur. Gizli adresler size gizlilik sağlayabilse de, bu gizlilik trafik analizine karşı hassastır. Basit bir örnek vermek gerekirse, Bill'in bir adresi fonladığını ve hemen ardından bir Rpub değeri yayınlamak için bir işlem gönderdiğini hayal edin. Alice'in Vpriv değeri olmadan, bunun gizli bir adres olduğundan emin olamayız, ancak büyük ihtimalle öyledir. Ardından, o adresteki tüm ETH'yi Alice'in kampanya fonu adresine transfer eden başka bir işlem görürüz. Bunu kanıtlayamayabiliriz, ancak Bill'in Alice'in kampanyasına bağış yapmış olması muhtemeldir. Carol kesinlikle böyle düşünecektir.
Bill'in Rpub yayınını gizli adresi fonlamaktan ayırması kolaydır (bunları farklı zamanlarda, farklı adreslerden yapabilir). Ancak bu yetersizdir. Carol'ın aradığı model, Bill'in bir adresi fonlaması ve ardından Alice'in kampanya fonunun bu adresten para çekmesidir.
Bir çözüm, Alice'in kampanyasının parayı doğrudan çekmemesi, bunun yerine üçüncü bir tarafa ödeme yapmak için kullanmasıdır. Alice'in kampanyası Dave'in Dünya Hakimiyeti Kampanya Hizmetleri'ne 10 ETH gönderirse, Carol yalnızca Bill'in Dave'in müşterilerinden birine bağış yaptığını bilir. Dave'in yeterince müşterisi varsa, Carol Bill'in kendisiyle rekabet eden Alice'e mi yoksa Carol'ın umursamadığı Adam, Albert veya Abigail'e mi bağış yaptığını bilemez. Alice, ödemeyle birlikte hash'lenmiş bir değer ekleyebilir ve ardından bunun kendi bağışı olduğunu kanıtlamak için Dave'e ön görüntüyü (preimage) sağlayabilir. Alternatif olarak, yukarıda belirtildiği gibi, Alice Dave'e Vpriv değerini verirse, ödemenin kimden geldiğini zaten bilir.
Bu çözümle ilgili temel sorun, bu gizlilik Bill'e fayda sağladığında Alice'in gizliliği önemsemesini gerektirmesidir. Alice itibarını korumak isteyebilir, böylece Bill'in arkadaşı Bob da ona bağış yapacaktır. Ancak Bill'i ifşa etmeyi umursamaması da mümkündür, çünkü o zaman Carol kazanırsa ne olacağından korkacaktır. Bill sonuçta Alice'e daha da fazla destek sağlayabilir.
Birden fazla gizli katman kullanmak
Bill'in gizliliğini korumak için Alice'e güvenmek yerine, Bill bunu kendisi yapabilir. Kurgusal kişiler olan Bob ve Bella için birden fazla meta-adres oluşturabilir. Bill daha sonra Bob'a ETH gönderir ve "Bob" (aslında Bill'dir) bunu Bella'ya gönderir. "Bella" (yine Bill) bunu Alice'e gönderir.
Carol hala trafik analizi yapabilir ve Bill'den Bob'a, Bella'ya ve Alice'e giden boru hattını görebilir. Ancak, "Bob" ve "Bella" ETH'yi başka amaçlar için de kullanıyorsa, Alice gizli adresten bilinen kampanya adresine hemen para çekse bile, Bill'in Alice'e herhangi bir şey transfer ettiği anlaşılmayacaktır.
Gizli adres uygulaması yazmak
Bu makale, GitHub'da bulunan (opens in a new tab) bir gizli adres uygulamasını açıklamaktadır.
Araçlar
Kullanabileceğimiz bir TypeScript gizli adres kütüphanesi (opens in a new tab) var. Ancak, kriptografik işlemler CPU yoğun olabilir. Bunları Rust (opens in a new tab) gibi derlenmiş bir dilde uygulamayı ve kodu tarayıcıda çalıştırmak için WASM (opens in a new tab) kullanmayı tercih ediyorum.
Vite (opens in a new tab) ve React (opens in a new tab) kullanacağız. Bunlar endüstri standardı araçlardır; onlara aşina değilseniz, bu öğreticiyi kullanabilirsiniz. Vite'ı kullanmak için Node'a ihtiyacımız var.
Gizli adresleri iş başında görün
-
Gerekli araçları yükleyin: Rust (opens in a new tab) ve Node (opens in a new tab).
-
GitHub deposunu klonlayın.
git clone https://github.com/qbzzt/251022-stealth-addresses.git cd 251022-stealth-addresses -
Ön koşulları yükleyin ve Rust kodunu derleyin.
cd src/rust-wasm rustup target add wasm32-unknown-unknown cargo install wasm-pack wasm-pack build --target web -
Web sunucusunu başlatın.
cd ../.. npm install npm run dev -
Uygulamaya (opens in a new tab) göz atın. Bu uygulama sayfasının iki çerçevesi vardır: biri Alice'in kullanıcı arayüzü, diğeri ise Bill'inki için. İki çerçeve iletişim kurmaz; sadece kolaylık sağlamak için aynı sayfadadırlar.
-
Alice olarak, Generate a Stealth Meta-Address (Gizli Meta-Adres Oluştur) seçeneğine tıklayın. Bu, yeni gizli adresi ve karşılık gelen özel anahtarları görüntüleyecektir. Gizli meta-adresi panoya kopyalayın.
-
Bill olarak, yeni gizli meta-adresi yapıştırın ve Generate an address (Bir adres oluştur) seçeneğine tıklayın. Bu size Alice için fonlanacak adresi verir.
-
Adresi ve Bill'in açık anahtarını kopyalayın ve Alice'in kullanıcı arayüzündeki "Private key for address generated by Bill" (Bill tarafından oluşturulan adres için özel anahtar) alanına yapıştırın. Bu alanlar doldurulduğunda, o adresteki varlıklara erişmek için özel anahtarı göreceksiniz.
-
Özel anahtarın adrese karşılık geldiğinden emin olmak için çevrimiçi bir hesap makinesi (opens in a new tab) kullanabilirsiniz.
Program nasıl çalışır
WASM bileşeni
WASM'a derlenen kaynak kodu Rust (opens in a new tab) ile yazılmıştır. Bunu src/rust_wasm/src/lib.rs (opens in a new tab) içinde görebilirsiniz. Bu kod, öncelikle JavaScript kodu ile eth-stealth-addresses kütüphanesi (opens in a new tab) arasında bir arayüzdür.
Cargo.toml
Rust'taki Cargo.toml (opens in a new tab), JavaScript'teki package.json (opens in a new tab) dosyasına benzer. Paket bilgilerini, bağımlılık bildirimlerini vb. içerir.
[package]
name = "rust-wasm"
version = "0.1.0"
edition = "2024"
[dependencies]
eth-stealth-addresses = "0.1.0"
hex = "0.4.3"
wasm-bindgen = "0.2.104"
getrandom = { version = "0.2", features = ["js"] }
getrandom (opens in a new tab) paketinin rastgele değerler üretmesi gerekir. Bu, tamamen algoritmik yollarla yapılamaz; bir entropi kaynağı olarak fiziksel bir sürece erişim gerektirir. Bu tanım, bu entropiyi içinde çalıştığımız tarayıcıya sorarak alacağımızı belirtir.
console_error_panic_hook = "0.1.7"
Bu kütüphane (opens in a new tab), WASM kodu paniklediğinde ve devam edemediğinde bize daha anlamlı hata mesajları verir.
[lib]
crate-type = ["cdylib", "rlib"]
WASM kodu üretmek için gereken çıktı türü.
lib.rs
Bu, asıl Rust kodudur.
use wasm_bindgen::prelude::*;
Rust'tan bir WASM paketi oluşturmak için tanımlar. Bunlar burada (opens in a new tab) belgelenmiştir.
use eth_stealth_addresses::{
generate_stealth_meta_address,
generate_stealth_address,
compute_stealth_key
};
eth-stealth-addresses kütüphanesinden (opens in a new tab) ihtiyaç duyduğumuz işlevler.
use hex::{decode,encode};
Rust, değerler için tipik olarak bayt dizileri (arrays) (opens in a new tab) ([u8; <size>]) kullanır. Ancak JavaScript'te tipik olarak onaltılık (hexadecimal) dizeler kullanırız. hex kütüphanesi (opens in a new tab) bizim için bir gösterimden diğerine çeviri yapar.
#[wasm_bindgen]
Bu işlevi JavaScript'ten çağırabilmek için WASM bağlamaları (bindings) oluşturun.
pub fn wasm_generate_stealth_meta_address() -> String {
Birden fazla alana sahip bir nesneyi döndürmenin en kolay yolu bir JSON dizesi döndürmektir.
let (address, spend_private_key, view_private_key) =
generate_stealth_meta_address();
generate_stealth_meta_address (opens in a new tab) üç alan döndürür:
- Meta-adres (Kpub ve Vpub)
- Görüntüleme özel anahtarı (Vpriv)
- Harcama özel anahtarı (Kpriv)
Demet (tuple) (opens in a new tab) sözdizimi bu değerleri tekrar ayırmamızı sağlar.
format!("{{\"address\":\"{}\",\"view_private_key\":\"{}\",\"spend_private_key\":\"{}\"}}",
encode(address),
encode(view_private_key),
encode(spend_private_key)
)
}
JSON kodlu dizeyi oluşturmak için format! (opens in a new tab) makrosunu kullanın. Dizileri onaltılık dizelere dönüştürmek için hex::encode (opens in a new tab) kullanın.
fn str_to_array<const N: usize>(s: &str) -> Option<[u8; N]> {
Bu işlev, (JavaScript tarafından sağlanan) onaltılık bir dizeyi bir bayt dizisine dönüştürür. JavaScript kodu tarafından sağlanan değerleri ayrıştırmak için kullanırız. Bu işlev, Rust'ın dizileri ve vektörleri nasıl işlediğinden dolayı karmaşıktır.
<const N: usize> ifadesine jenerik (generic) (opens in a new tab) denir. N, döndürülen dizinin uzunluğunu kontrol eden bir parametredir. İşlev aslında str_to_array::<n> olarak adlandırılır, burada n dizi uzunluğudur.
Dönüş değeri Option<[u8; N]> şeklindedir, bu da döndürülen dizinin isteğe bağlı (optional) (opens in a new tab) olduğu anlamına gelir. Bu, başarısız olabilecek işlevler için Rust'ta tipik bir modeldir.
Örneğin, str_to_array::10("bad060a7") çağırırsak, işlevin on değerlik bir dizi döndürmesi gerekir, ancak girdi yalnızca dört bayttır. İşlevin başarısız olması gerekir ve bunu None döndürerek yapar. str_to_array::4("bad060a7") için dönüş değeri Some<[0xba, 0xd0, 0x60, 0xa7]> olacaktır.
// decode, Result<Vec<u8>, _> döndürür
let vec = decode(s).ok()?;
hex::decode (opens in a new tab) işlevi bir Result<Vec<u8>, FromHexError> döndürür. Result (opens in a new tab) türü, başarılı bir sonuç (Ok(value)) veya bir hata (Err(error)) içerebilir.
.ok() yöntemi, Result değerini bir Option değerine dönüştürür; bunun değeri başarılıysa Ok() değeri, değilse None olur. Son olarak, soru işareti operatörü (opens in a new tab) mevcut işlevleri iptal eder ve Option boşsa bir None döndürür. Aksi takdirde, değeri açar (unwrap) ve onu döndürür (bu durumda, vec değişkenine bir değer atamak için).
Bu, hataları ele almak için garip bir şekilde karmaşık bir yöntem gibi görünüyor, ancak Result ve Option tüm hataların öyle ya da böyle ele alınmasını sağlar.
if vec.len() != N { return None; }
Bayt sayısı yanlışsa, bu bir başarısızlıktır ve None döndürürüz.
// try_into, vec'i tüketir ve [u8; N] oluşturmaya çalışır
let array: [u8; N] = vec.try_into().ok()?;
Rust'ın iki dizi türü vardır. Diziler (Arrays) (opens in a new tab) sabit bir boyuta sahiptir. Vektörler (Vectors) (opens in a new tab) büyüyebilir ve küçülebilir. hex::decode bir vektör döndürür, ancak eth_stealth_addresses kütüphanesi diziler almak ister. .try_into() (opens in a new tab) bir değeri başka bir türe dönüştürür, örneğin bir vektörü bir diziye.
Some(array)
}
Rust, bir işlevin sonunda bir değer döndürürken return (opens in a new tab) anahtar kelimesini kullanmanızı gerektirmez.
#[wasm_bindgen]
pub fn wasm_generate_stealth_address(stealth_address: &str) -> Option<String> {
Bu işlev, hem Vpub hem de Kpub içeren bir açık meta-adres alır. Gizli adresi, yayınlanacak açık anahtarı (Rpub) ve yayınlanan adreslerden hangilerinin Alice'e ait olabileceğinin belirlenmesini hızlandıran bir baytlık bir tarama değeri döndürür.
Tarama değeri, paylaşılan sırrın (S = GRprivVpriv) bir parçasıdır. Bu değer Alice tarafından kullanılabilir ve bunu kontrol etmek, f(Kpub+G*hash(S)) değerinin yayınlanan adrese eşit olup olmadığını kontrol etmekten çok daha hızlıdır.
let (address, r_pub, scan) =
generate_stealth_address(&str_to_array::<66>(stealth_address)?);
Kütüphanenin generate_stealth_address (opens in a new tab) işlevini kullanıyoruz.
format!("{{\"address\":\"{}\",\"rPub\":\"{}\",\"scan\":\"{}\"}}",
encode(address),
encode(r_pub),
encode(&[scan])
).into()
}
JSON kodlu çıktı dizesini hazırlayın.
#[wasm_bindgen]
pub fn wasm_compute_stealth_key(
address: &str,
bill_pub_key: &str,
view_private_key: &str,
spend_private_key: &str
) -> Option<String> {
.
.
.
}
Bu işlev, adresten para çekmek için özel anahtarı (Rpriv) hesaplamak üzere kütüphanenin compute_stealth_key (opens in a new tab) işlevini kullanır. Bu hesaplama şu değerleri gerektirir:
- Adres (Adres=f(Ppub))
- Bill tarafından oluşturulan açık anahtar (Rpub)
- Görüntüleme özel anahtarı (Vpriv)
- Harcama özel anahtarı (Kpriv)
#[wasm_bindgen(start)]
#[wasm_bindgen(start)] (opens in a new tab), işlevin WASM kodu başlatıldığında yürütüleceğini belirtir.
pub fn main() {
console_error_panic_hook::set_once();
}
Bu kod, panik çıktısının JavaScript konsoluna gönderilmesini belirtir. Bunu iş başında görmek için uygulamayı kullanın ve Bill'e geçersiz bir meta-adres verin (sadece bir onaltılık basamağı değiştirin). JavaScript konsolunda şu hatayı göreceksiniz:
rust_wasm.js:236 panicked at /home/ori/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs:701:9:
assertion `left == right` failed
left: 0
right: 1
Ardından bir yığın izlemesi (stack trace) gelir. Sonra Bill'e geçerli meta-adresi verin ve Alice'e geçersiz bir adres veya geçersiz bir açık anahtar verin. Şu hatayı göreceksiniz:
rust_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:
keys do not generate stealth address
Yine, ardından bir yığın izlemesi gelir.
Kullanıcı arayüzü
Kullanıcı arayüzü React (opens in a new tab) kullanılarak yazılmıştır ve Vite (opens in a new tab) tarafından sunulmaktadır. Bu öğreticiyi kullanarak onlar hakkında bilgi edinebilirsiniz. Burada Wagmi (opens in a new tab)'ye gerek yoktur çünkü doğrudan bir blokzincir veya cüzdan ile etkileşime girmiyoruz.
Kullanıcı arayüzünün tek belirgin olmayan kısmı WASM bağlantısıdır. İşte nasıl çalıştığı.
vite.config.js
Bu dosya Vite yapılandırmasını (opens in a new tab) içerir.
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import wasm from "vite-plugin-wasm";
// https://vite.dev/config/
export default defineConfig({
plugins: [react(), wasm()],
})
İki Vite eklentisine ihtiyacımız var: react (opens in a new tab) ve wasm (opens in a new tab).
App.jsx
Bu dosya uygulamanın ana bileşenidir. İki bileşeni içeren bir kapsayıcıdır: Alice ve Bill, bu kullanıcılar için kullanıcı arayüzleri. WASM için ilgili kısım başlatma kodudur.
import init from './rust-wasm/pkg/rust_wasm.js'
wasm-pack (opens in a new tab) kullandığımızda, burada kullandığımız iki dosya oluşturur: asıl kodu içeren bir wasm dosyası (burada, src/rust-wasm/pkg/rust_wasm_bg.wasm) ve onu kullanmak için tanımları içeren bir JavaScript dosyası (burada, src/rust_wasm/pkg/rust_wasm.js). Bu JavaScript dosyasının varsayılan dışa aktarımı (default export), WASM'ı başlatmak için çalışması gereken koddur.
function App() {
.
.
.
useEffect(() => {
const loadWasm = async () => {
try {
await init();
setWasmReady(true)
} catch (err) {
console.error('Error loading wasm:', err)
alert("Wasm error: " + err)
}
}
loadWasm()
}, []
)
useEffect kancası (hook) (opens in a new tab), durum değişkenleri değiştiğinde yürütülen bir işlev belirlemenizi sağlar. Burada, durum değişkenleri listesi boştur ([]), bu nedenle bu işlev sayfa yüklendiğinde yalnızca bir kez yürütülür.
Etki (effect) işlevinin hemen dönmesi gerekir. WASM init gibi asenkron kodları kullanmak için (.wasm dosyasını yüklemesi gerektiğinden zaman alır), dahili bir async (opens in a new tab) işlevi tanımlarız ve onu bir await olmadan çalıştırırız.
Bill.jsx
Bu, Bill için kullanıcı arayüzüdür. Alice tarafından sağlanan gizli meta-adrese dayalı bir adres oluşturmak gibi tek bir eylemi vardır.
import { wasm_generate_stealth_address } from './rust-wasm/pkg/rust_wasm.js'
Varsayılan dışa aktarıma ek olarak, wasm-pack tarafından oluşturulan JavaScript kodu, WASM kodundaki her işlev için bir işlev dışa aktarır.
<button onClick={() => {
setPublicAddress(JSON.parse(wasm_generate_stealth_address(stealthMetaAddress)))
}}>
WASM işlevlerini çağırmak için, sadece wasm-pack tarafından oluşturulan JavaScript dosyasının dışa aktardığı işlevi çağırırız.
Alice.jsx
Alice.jsx içindeki kod benzerdir, ancak Alice'in iki eylemi vardır:
- Bir meta-adres oluşturmak
- Bill tarafından yayınlanan bir adres için özel anahtarı almak
Sonuç
Gizli adresler her derde deva değildir; doğru kullanılmaları gerekir. Ancak doğru kullanıldıklarında, halka açık bir blokzincir üzerinde gizlilik sağlayabilirler.
Çalışmalarımın daha fazlası için buraya bakın (opens in a new tab).