mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-02-11 17:55:46 +00:00
zcash_client_sqlite: Support sending to t-addrs
This commit is contained in:
parent
1c60a79ec1
commit
1cbeac9d59
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -676,6 +676,7 @@ name = "zcash_client_sqlite"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bech32 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bs58 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ff 0.4.0",
|
||||
"pairing 0.14.2",
|
||||
"protobuf 2.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -8,6 +8,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
bech32 = "0.7"
|
||||
bs58 = { version = "0.2", features = ["check"] }
|
||||
ff = { path = "../ff" }
|
||||
pairing = { path = "../pairing" }
|
||||
protobuf = "2"
|
||||
|
63
zcash_client_sqlite/src/address.rs
Normal file
63
zcash_client_sqlite/src/address.rs
Normal file
@ -0,0 +1,63 @@
|
||||
//! Structs for handling supported address types.
|
||||
|
||||
use pairing::bls12_381::Bls12;
|
||||
use zcash_client_backend::encoding::{
|
||||
decode_payment_address, decode_transparent_address, encode_payment_address,
|
||||
encode_transparent_address,
|
||||
};
|
||||
use zcash_primitives::{legacy::TransparentAddress, primitives::PaymentAddress};
|
||||
|
||||
#[cfg(feature = "mainnet")]
|
||||
use zcash_client_backend::constants::mainnet::{
|
||||
B58_PUBKEY_ADDRESS_PREFIX, B58_SCRIPT_ADDRESS_PREFIX, HRP_SAPLING_PAYMENT_ADDRESS,
|
||||
};
|
||||
|
||||
#[cfg(not(feature = "mainnet"))]
|
||||
use zcash_client_backend::constants::testnet::{
|
||||
B58_PUBKEY_ADDRESS_PREFIX, B58_SCRIPT_ADDRESS_PREFIX, HRP_SAPLING_PAYMENT_ADDRESS,
|
||||
};
|
||||
|
||||
/// An address that funds can be sent to.
|
||||
pub enum RecipientAddress {
|
||||
Shielded(PaymentAddress<Bls12>),
|
||||
Transparent(TransparentAddress),
|
||||
}
|
||||
|
||||
impl From<PaymentAddress<Bls12>> for RecipientAddress {
|
||||
fn from(addr: PaymentAddress<Bls12>) -> Self {
|
||||
RecipientAddress::Shielded(addr)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TransparentAddress> for RecipientAddress {
|
||||
fn from(addr: TransparentAddress) -> Self {
|
||||
RecipientAddress::Transparent(addr)
|
||||
}
|
||||
}
|
||||
|
||||
impl RecipientAddress {
|
||||
pub fn from_str(s: &str) -> Option<Self> {
|
||||
if let Ok(Some(pa)) = decode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, s) {
|
||||
Some(pa.into())
|
||||
} else if let Ok(Some(addr)) =
|
||||
decode_transparent_address(&B58_PUBKEY_ADDRESS_PREFIX, &B58_SCRIPT_ADDRESS_PREFIX, s)
|
||||
{
|
||||
Some(addr.into())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_string(&self) -> String {
|
||||
match self {
|
||||
RecipientAddress::Shielded(pa) => {
|
||||
encode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, pa)
|
||||
}
|
||||
RecipientAddress::Transparent(addr) => encode_transparent_address(
|
||||
&B58_PUBKEY_ADDRESS_PREFIX,
|
||||
&B58_SCRIPT_ADDRESS_PREFIX,
|
||||
addr,
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ pub enum ErrorKind {
|
||||
ScanRequired,
|
||||
TableNotEmpty,
|
||||
Bech32(bech32::Error),
|
||||
Base58(bs58::decode::DecodeError),
|
||||
Builder(builder::Error),
|
||||
Database(rusqlite::Error),
|
||||
Io(std::io::Error),
|
||||
@ -65,6 +66,7 @@ impl fmt::Display for Error {
|
||||
ErrorKind::ScanRequired => write!(f, "Must scan blocks first"),
|
||||
ErrorKind::TableNotEmpty => write!(f, "Table is not empty"),
|
||||
ErrorKind::Bech32(e) => write!(f, "{}", e),
|
||||
ErrorKind::Base58(e) => write!(f, "{}", e),
|
||||
ErrorKind::Builder(e) => write!(f, "{:?}", e),
|
||||
ErrorKind::Database(e) => write!(f, "{}", e),
|
||||
ErrorKind::Io(e) => write!(f, "{}", e),
|
||||
@ -93,6 +95,12 @@ impl From<bech32::Error> for Error {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bs58::decode::DecodeError> for Error {
|
||||
fn from(e: bs58::decode::DecodeError) -> Self {
|
||||
Error(ErrorKind::Base58(e))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<builder::Error> for Error {
|
||||
fn from(e: builder::Error) -> Self {
|
||||
Error(ErrorKind::Builder(e))
|
||||
|
@ -39,6 +39,7 @@ use zcash_client_backend::constants::testnet::{
|
||||
HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY, HRP_SAPLING_PAYMENT_ADDRESS,
|
||||
};
|
||||
|
||||
pub mod address;
|
||||
pub mod chain;
|
||||
pub mod error;
|
||||
pub mod init;
|
||||
|
@ -4,12 +4,12 @@ use ff::{PrimeField, PrimeFieldRepr};
|
||||
use pairing::bls12_381::Bls12;
|
||||
use rusqlite::{types::ToSql, Connection, NO_PARAMS};
|
||||
use std::path::Path;
|
||||
use zcash_client_backend::encoding::{encode_extended_full_viewing_key, encode_payment_address};
|
||||
use zcash_client_backend::encoding::encode_extended_full_viewing_key;
|
||||
use zcash_primitives::{
|
||||
jubjub::fs::{Fs, FsRepr},
|
||||
merkle_tree::IncrementalWitness,
|
||||
note_encryption::Memo,
|
||||
primitives::{Diversifier, Note, PaymentAddress},
|
||||
primitives::{Diversifier, Note},
|
||||
prover::TxProver,
|
||||
sapling::Node,
|
||||
transaction::{
|
||||
@ -21,9 +21,9 @@ use zcash_primitives::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
address::RecipientAddress,
|
||||
error::{Error, ErrorKind},
|
||||
get_target_and_anchor_heights, HRP_SAPLING_EXTENDED_FULL_VIEWING_KEY,
|
||||
HRP_SAPLING_PAYMENT_ADDRESS,
|
||||
};
|
||||
|
||||
struct SelectedNoteRow {
|
||||
@ -61,7 +61,7 @@ struct SelectedNoteRow {
|
||||
///
|
||||
/// let account = 0;
|
||||
/// let extsk = spending_key(&[0; 32][..], COIN_TYPE, account);
|
||||
/// let to = extsk.default_address().unwrap().1;
|
||||
/// let to = extsk.default_address().unwrap().1.into();
|
||||
/// match create_to_address(
|
||||
/// "/path/to/data.db",
|
||||
/// SAPLING_CONSENSUS_BRANCH_ID,
|
||||
@ -80,7 +80,7 @@ pub fn create_to_address<P: AsRef<Path>>(
|
||||
consensus_branch_id: u32,
|
||||
prover: impl TxProver,
|
||||
(account, extsk): (u32, &ExtendedSpendingKey),
|
||||
to: &PaymentAddress<Bls12>,
|
||||
to: &RecipientAddress,
|
||||
value: Amount,
|
||||
memo: Option<Memo>,
|
||||
) -> Result<i64, Error> {
|
||||
@ -221,7 +221,12 @@ pub fn create_to_address<P: AsRef<Path>>(
|
||||
selected.witness,
|
||||
)?;
|
||||
}
|
||||
builder.add_sapling_output(ovk, to.clone(), value, memo.clone())?;
|
||||
match to {
|
||||
RecipientAddress::Shielded(to) => {
|
||||
builder.add_sapling_output(ovk, to.clone(), value, memo.clone())
|
||||
}
|
||||
RecipientAddress::Transparent(to) => builder.add_transparent_output(&to, value),
|
||||
}?;
|
||||
let (tx, tx_metadata) = builder.build(consensus_branch_id, prover)?;
|
||||
// We only called add_sapling_output() once.
|
||||
let output_index = match tx_metadata.output_index(0) {
|
||||
@ -263,7 +268,8 @@ pub fn create_to_address<P: AsRef<Path>>(
|
||||
}
|
||||
|
||||
// Save the sent note in the database.
|
||||
let to_str = encode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, to);
|
||||
// TODO: Decide how to save transparent output information.
|
||||
let to_str = to.to_string();
|
||||
if let Some(memo) = memo {
|
||||
let mut stmt_insert_sent_note = data.prepare(
|
||||
"INSERT INTO sent_notes (tx, output_index, from_account, address, value, memo)
|
||||
@ -340,7 +346,7 @@ mod tests {
|
||||
ExtendedFullViewingKey::from(&extsk1),
|
||||
];
|
||||
init_accounts_table(&db_data, &extfvks).unwrap();
|
||||
let to = extsk0.default_address().unwrap().1;
|
||||
let to = extsk0.default_address().unwrap().1.into();
|
||||
|
||||
// Invalid extsk for the given account should cause an error
|
||||
match create_to_address(
|
||||
@ -379,7 +385,7 @@ mod tests {
|
||||
let extsk = ExtendedSpendingKey::master(&[]);
|
||||
let extfvks = [ExtendedFullViewingKey::from(&extsk)];
|
||||
init_accounts_table(&db_data, &extfvks).unwrap();
|
||||
let to = extsk.default_address().unwrap().1;
|
||||
let to = extsk.default_address().unwrap().1.into();
|
||||
|
||||
// We cannot do anything if we aren't synchronised
|
||||
match create_to_address(
|
||||
@ -407,7 +413,7 @@ mod tests {
|
||||
let extsk = ExtendedSpendingKey::master(&[]);
|
||||
let extfvks = [ExtendedFullViewingKey::from(&extsk)];
|
||||
init_accounts_table(&db_data, &extfvks).unwrap();
|
||||
let to = extsk.default_address().unwrap().1;
|
||||
let to = extsk.default_address().unwrap().1.into();
|
||||
|
||||
// Account balance should be zero
|
||||
assert_eq!(get_balance(db_data, 0).unwrap(), Amount::zero());
|
||||
@ -476,7 +482,7 @@ mod tests {
|
||||
|
||||
// Spend fails because there are insufficient verified notes
|
||||
let extsk2 = ExtendedSpendingKey::master(&[]);
|
||||
let to = extsk2.default_address().unwrap().1;
|
||||
let to = extsk2.default_address().unwrap().1.into();
|
||||
match create_to_address(
|
||||
db_data,
|
||||
1,
|
||||
@ -575,7 +581,7 @@ mod tests {
|
||||
|
||||
// Send some of the funds to another address
|
||||
let extsk2 = ExtendedSpendingKey::master(&[]);
|
||||
let to = extsk2.default_address().unwrap().1;
|
||||
let to = extsk2.default_address().unwrap().1.into();
|
||||
create_to_address(
|
||||
db_data,
|
||||
1,
|
||||
|
Loading…
x
Reference in New Issue
Block a user