Browse Source

working

checkpoints
Aditya Kulkarni 5 years ago
parent
commit
9b9641a6f4
  1. 5
      rust-lightclient/Cargo.toml
  2. 4
      rust-lightclient/src/commands.rs
  3. 142
      rust-lightclient/src/lightwallet.rs

5
rust-lightclient/Cargo.toml

@ -8,6 +8,7 @@ tower-grpc = { git = "https://github.com/tower-rs/tower-grpc" }
futures = "0.1"
bytes = "0.4"
env_logger = { version = "0.5", default-features = false }
base58 = "0.1.0"
log = "0.4"
http = "0.1"
prost = "0.5"
@ -25,6 +26,9 @@ rand = "0.5.6"
json = "0.12.0"
bip39 = "0.6.0-beta.1"
clap = "2.33"
secp256k1 = "=0.15.0"
sha2 = "0.8.0"
ripemd160 = "0.8.0"
[dependencies.bellman]
path = "../../librustzcash/bellman"
@ -41,6 +45,7 @@ default-features = false
[dependencies.zcash_primitives]
path = "../../librustzcash/zcash_primitives"
default-features = false
features = ["transparent-inputs"]
[dependencies.zcash_proofs]
path = "../../librustzcash/zcash_proofs"

4
rust-lightclient/src/commands.rs

@ -89,8 +89,8 @@ impl Command for SendCommand {
fn exec(&self, _args: &[String], lightclient: &mut LightClient) {
lightclient.do_send(
"tmHYDCK6PjBMArtDXwPf5bgoFm2Na5fR6Ds".to_string(),
150000,
"ztestsapling1x65nq4dgp0qfywgxcwk9n0fvm4fysmapgr2q00p85ju252h6l7mmxu2jg9cqqhtvzd69jwhgv8d".to_string(),
50000000 - 10000,
None);
}
}

142
rust-lightclient/src/lightwallet.rs

@ -1,5 +1,3 @@
pub extern crate ff;
use std::time::SystemTime;
use std::io::{self, Read, Write};
use std::cmp;
@ -29,6 +27,7 @@ use zcash_primitives::{
components::Amount, components::amount::DEFAULT_FEE,
TxId, Transaction
},
legacy::{TransparentAddress::PublicKey},
note_encryption::{Memo, try_sapling_note_decryption},
zip32::{ExtendedFullViewingKey, ExtendedSpendingKey, ChildIndex},
JUBJUB,
@ -42,11 +41,65 @@ use zcash_primitives::{
use crate::address;
use crate::prover;
use sha2::{Sha256, Digest};
/// Sha256(Sha256(value))
pub fn double_sha256(payload: &[u8]) -> Vec<u8> {
let h1 = Sha256::digest(&payload);
let h2 = Sha256::digest(&h1);
h2.to_vec()
}
use base58::{ToBase58, FromBase58};
const ANCHOR_OFFSET: u32 = 1;
const SAPLING_ACTIVATION_HEIGHT: i32 = 280_000;
/// A trait for converting a [u8] to base58 encoded string.
pub trait ToBase58Check {
/// Converts a value of `self` to a base58 value, returning the owned string.
/// The version is a coin-specific prefix that is added.
/// The suffix is any bytes that we want to add at the end (like the "iscompressed" flag for
/// Secret key encoding)
fn to_base58check(&self, version: &[u8], suffix: &[u8]) -> String;
}
impl ToBase58Check for [u8] {
fn to_base58check(&self, version: &[u8], suffix: &[u8]) -> String {
let mut payload: Vec<u8> = Vec::new();
payload.extend_from_slice(version);
payload.extend_from_slice(self);
payload.extend_from_slice(suffix);
let mut checksum = double_sha256(&payload);
payload.append(&mut checksum[..4].to_vec());
payload.to_base58()
}
}
pub trait FromBase58Check {
fn from_base58check(&self, version: &[u8], suffix: &[u8]) -> Vec<u8>;
}
impl FromBase58Check for str {
fn from_base58check(&self, version: &[u8], suffix: &[u8]) -> Vec<u8> {
let mut payload: Vec<u8> = Vec::new();
let bytes = self.from_base58().unwrap();
let start = version.len();
let end = bytes.len() - (4 + suffix.len());
payload.extend(&bytes[start..end]);
payload
}
}
fn now() -> f64 {
// web_sys::window()
// .expect("should have a Window")
@ -861,32 +914,73 @@ impl LightWallet {
.collect();
// Confirm we were able to select sufficient value
let selected_value = notes
.iter()
.map(|selected| selected.note.value)
.sum::<u64>();
if selected_value < u64::from(target_value) {
eprintln!(
"Insufficient funds (have {}, need {:?})",
selected_value, target_value
);
return None;
}
// let selected_value = notes
// .iter()
// .map(|selected| selected.note.value)
// .sum::<u64>();
// if selected_value < u64::from(target_value) {
// eprintln!(
// "Insufficient funds (have {}, need {:?})",
// selected_value, target_value
// );
// return None;
// }
// Create the transaction
println!("{}: Adding {} inputs", now() - start_time, notes.len());
let mut builder = Builder::new(height);
for selected in notes.iter() {
if let Err(e) = builder.add_sapling_spend(
extsk.clone(),
selected.diversifier,
selected.note.clone(),
selected.witness.clone(),
) {
eprintln!("Error adding note: {:?}", e);
return None;
}
}
// for selected in notes.iter() {
// if let Err(e) = builder.add_sapling_spend(
// extsk.clone(),
// selected.diversifier,
// selected.note.clone(),
// selected.witness.clone(),
// ) {
// eprintln!("Error adding note: {:?}", e);
// return None;
// }
// }
// TODO: Temp - Add a transparent input manually for testing
use zcash_primitives::transaction::components::{TxOut, OutPoint};
use zcash_primitives::legacy::Script;
let sk_bytes = "cPYbNomCYVh7Sih2LAFg5WEkGT6kMBfdLzWpdSm8qyrgd7viztVq".from_base58check(&[0xEF], &[0x01]);
println!("sk bytes {}", sk_bytes.len());
let sk = secp256k1::SecretKey::from_slice(&sk_bytes).unwrap();
let secp = secp256k1::Secp256k1::new();
let pk = secp256k1::PublicKey::from_secret_key(&secp, &sk);
// Address
let mut hash160 = ripemd160::Ripemd160::new();
hash160.input(sha2::Sha256::digest(&pk.serialize().to_vec()));
let addr = hash160.result().to_base58check(&[0x1D, 0x25], &[]);
println!("Address = {}", addr);
let mut script_hash = [0u8; 32];
script_hash.copy_from_slice(&hex::decode("d8cd8ca083b3f7e1290c51ba5fb3366fbc4e749256446638318022d8672a6862").unwrap()[0..32]);
script_hash.reverse();
let utxo = OutPoint {
hash: script_hash,
n: 0
};
let mut script_pubkey = hex::decode("76a914433bf369d77494b07f3ebdec0d09a2edfdc4481688ac").unwrap();
let script = Script{0: script_pubkey};
match script.address().unwrap() {
PublicKey(p) => println!("{}", p.to_base58check(&[0x1D, 0x25], &[])),
_ => {}
};
let coin = TxOut {
value: Amount::from_u64(50000000).unwrap(),
script_pubkey: script,
};
builder.add_transparent_input(sk, utxo, coin).unwrap();
// Compute memo if it exists
let encoded_memo = memo.map(|s| Memo::from_str(&s).unwrap() );

Loading…
Cancel
Save