Merge pull request 'Implements FFI for transactions from Zebra' (#49) from rav001 into dev040

Reviewed-on: #49
This commit is contained in:
pitmutt 2024-04-02 17:09:42 +00:00 committed by Vergara Technologies LLC
commit 204275a9b6
Signed by: Vergara Technologies LLC
GPG Key ID: 99DB473BB4715618
6 changed files with 300 additions and 96 deletions

View File

@ -961,36 +961,6 @@ dependencies = [
"zcash_note_encryption", "zcash_note_encryption",
] ]
[[package]]
name = "orchard"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fb255c3ffdccd3c84fe9ebed72aef64fdc72e6a3e4180dd411002d47abaad42"
dependencies = [
"aes",
"bitvec",
"blake2b_simd",
"ff",
"fpe",
"group",
"halo2_gadgets",
"halo2_proofs",
"hex",
"incrementalmerkletree",
"lazy_static",
"memuse",
"nonempty",
"pasta_curves",
"rand",
"reddsa",
"serde",
"subtle",
"tracing",
"zcash_note_encryption",
"zcash_spec",
"zip32",
]
[[package]] [[package]]
name = "pairing" name = "pairing"
version = "0.23.0" version = "0.23.0"
@ -1314,7 +1284,8 @@ dependencies = [
"borsh 0.10.3", "borsh 0.10.3",
"f4jumble", "f4jumble",
"haskell-ffi", "haskell-ffi",
"orchard 0.7.1", "nonempty",
"orchard",
"proc-macro2", "proc-macro2",
"zcash_address 0.2.0", "zcash_address 0.2.0",
"zcash_client_backend", "zcash_client_backend",
@ -1743,7 +1714,7 @@ dependencies = [
"incrementalmerkletree", "incrementalmerkletree",
"memuse", "memuse",
"nom", "nom",
"orchard 0.6.0", "orchard",
"percent-encoding", "percent-encoding",
"prost", "prost",
"rayon", "rayon",
@ -1806,7 +1777,7 @@ dependencies = [
"lazy_static", "lazy_static",
"memuse", "memuse",
"nonempty", "nonempty",
"orchard 0.6.0", "orchard",
"rand", "rand",
"rand_core", "rand_core",
"sha2 0.10.6", "sha2 0.10.6",
@ -1816,15 +1787,6 @@ dependencies = [
"zcash_note_encryption", "zcash_note_encryption",
] ]
[[package]]
name = "zcash_spec"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7a3bf58b673cb3dacd8ae09ba345998923a197ab0da70d6239d8e8838949e9b"
dependencies = [
"blake2b_simd",
]
[[package]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.6.0" version = "1.6.0"

View File

@ -11,12 +11,13 @@ f4jumble = "0.1"
zcash_address = "0.2.0" zcash_address = "0.2.0"
borsh = "0.10" borsh = "0.10"
bech32 = "0.11" bech32 = "0.11"
orchard = "0.7.0" orchard = "0.6.0"
zcash_note_encryption = "0.4.0" zcash_note_encryption = "0.4.0"
zcash_primitives = "0.13.0" zcash_primitives = "0.13.0"
zcash_client_backend = "0.10.0" zcash_client_backend = "0.10.0"
zip32 = "0.1.0" zip32 = "0.1.0"
proc-macro2 = "1.0.66" proc-macro2 = "1.0.66"
nonempty = "0.7.0"
[features] [features]

View File

@ -10,6 +10,8 @@ use std::{
}, },
}; };
use nonempty::NonEmpty;
use f4jumble; use f4jumble;
use borsh::{BorshDeserialize, BorshSerialize}; use borsh::{BorshDeserialize, BorshSerialize};
@ -32,6 +34,7 @@ use zcash_primitives::{
}, },
zip339::{Count, Mnemonic}, zip339::{Count, Mnemonic},
transaction::components::{ transaction::components::{
amount::Amount,
transparent::{ transparent::{
Bundle as TransparentBundle, Bundle as TransparentBundle,
TxIn, TxIn,
@ -41,7 +44,10 @@ use zcash_primitives::{
}, },
sapling::{ sapling::{
GrothProofBytes, GrothProofBytes,
OutputDescription OutputDescription,
SpendDescription,
Authorized as SaplingAuthorized,
Bundle as SaplingBundle
} }
}, },
sapling::{ sapling::{
@ -78,6 +84,11 @@ use zcash_primitives::zip32::DiversifierIndex;
use zcash_primitives::block::BlockHeader; use zcash_primitives::block::BlockHeader;
use orchard::{ use orchard::{
Bundle as OrchardBundle,
bundle::{
Authorized as OrchardAuthorized,
Flags
},
Action, Action,
keys::{SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope}, keys::{SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope},
note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment}, note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment},
@ -130,12 +141,12 @@ impl<RW> ToHaskell<RW> for HrawTx {
#[derive(BorshSerialize, BorshDeserialize)] #[derive(BorshSerialize, BorshDeserialize)]
pub struct HshieldedOutput { pub struct HshieldedOutput {
cv: Vec<u8>, cv: Hhex,
cmu: Vec<u8>, cmu: Hhex,
eph_key: Vec<u8>, eph_key: Hhex,
enc_txt: Vec<u8>, enc_txt: Hhex,
out_txt: Vec<u8>, out_txt: Hhex,
proof: Vec<u8> proof: Hhex
} }
impl<RW> FromHaskell<RW> for HshieldedOutput { impl<RW> FromHaskell<RW> for HshieldedOutput {
@ -153,9 +164,15 @@ impl<RW> ToHaskell<RW> for HshieldedOutput {
} }
impl HshieldedOutput { impl HshieldedOutput {
fn from_object(s: OutputDescription<GrothProofBytes>) -> Result<HshieldedOutput> { fn from_object(s: &OutputDescription<GrothProofBytes>) -> HshieldedOutput {
let o = HshieldedOutput { cv: s.cv().to_bytes().to_vec(), cmu: s.cmu().to_bytes().to_vec(), eph_key: s.ephemeral_key().0.to_vec(), enc_txt: s.enc_ciphertext().to_vec(), out_txt: s.out_ciphertext().to_vec(), proof: s.zkproof().to_vec() }; HshieldedOutput { cv: Hhex{ bytes: s.cv().to_bytes().to_vec()}, cmu: Hhex{ bytes: s.cmu().to_bytes().to_vec()}, eph_key: Hhex{ bytes: s.ephemeral_key().0.to_vec()}, enc_txt: Hhex{ bytes: s.enc_ciphertext().to_vec()}, out_txt: Hhex{ bytes: s.out_ciphertext().to_vec()}, proof: Hhex{ bytes: s.zkproof().to_vec()} }
Ok(o) }
pub fn pack(sp: &[OutputDescription<GrothProofBytes>]) -> Vec<HshieldedOutput> {
let mut r = Vec::new();
for s in sp {
r.push(HshieldedOutput::from_object(s));
}
return r
} }
} }
@ -183,6 +200,16 @@ impl<RW> FromHaskell<RW> for Haction {
} }
} }
impl Haction {
pub fn pack(sp: &NonEmpty<Action<Signature<SpendAuth>>>) -> Vec<Haction> {
let mut r = Vec::new();
for s in sp {
r.push(Haction {nf: Hhex { bytes: s.nullifier().to_bytes().to_vec()}, rk: Hhex { bytes: <[u8; 32]>::from(s.rk()).to_vec()}, cmx: Hhex{bytes: s.cmx().to_bytes().to_vec()}, eph_key: Hhex{ bytes: s.encrypted_note().epk_bytes.to_vec()}, enc_txt: Hhex {bytes: s.encrypted_note().enc_ciphertext.to_vec()}, out_txt: Hhex {bytes: s.encrypted_note().out_ciphertext.to_vec()}, cv: Hhex {bytes: s.cv_net().to_bytes().to_vec()}, auth: Hhex { bytes: <[u8; 64]>::from(s.authorization()).to_vec()}});
}
return r
}
}
#[derive(BorshSerialize, BorshDeserialize)] #[derive(BorshSerialize, BorshDeserialize)]
pub struct Hnote { pub struct Hnote {
note: u64, note: u64,
@ -235,7 +262,9 @@ pub struct Htx {
txid: Vec<u8>, txid: Vec<u8>,
locktime: u32, locktime: u32,
expiry: u32, expiry: u32,
t_bundle: HTBundle t_bundle: HTBundle,
s_bundle: HSBundle,
o_bundle: HOBundle
} }
impl<RW> ToHaskell<RW> for Htx { impl<RW> ToHaskell<RW> for Htx {
@ -325,6 +354,105 @@ impl Houtpoint {
} }
} }
#[derive(BorshSerialize, BorshDeserialize)]
pub struct HSBundle {
empty: bool,
spends: Vec<Hspend>,
outputs: Vec<HshieldedOutput> ,
value: i64,
sig: Vec<u8>
}
impl<RW> ToHaskell<RW> for HSBundle {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl HSBundle {
pub fn from_bundle(sb: &SaplingBundle<SaplingAuthorized>) -> HSBundle {
let s = Cursor::new(Vec::new());
sb.authorization().binding_sig.write(s.clone()).unwrap();
return HSBundle {empty: false, spends: Hspend::pack(sb.shielded_spends()) , outputs: HshieldedOutput::pack(sb.shielded_outputs()) , value: i64::from(sb.value_balance()) , sig: s.into_inner() }
}
}
#[derive(BorshSerialize, BorshDeserialize)]
pub struct Hspend {
cv: Hhex,
anchor: Hhex,
nullifier: Hhex,
rk: Hhex,
proof: Hhex,
authsig: Hhex
}
impl<RW> ToHaskell<RW> for Hspend {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl Hspend {
pub fn pack(sp: &[SpendDescription<SaplingAuthorized>]) -> Vec<Hspend> {
let mut r = Vec::new();
for s in sp {
let rk = Cursor::new(Vec::new());
let authsig = Cursor::new(Vec::new());
s.rk().write(rk.clone()).unwrap();
s.spend_auth_sig().write(authsig.clone()).unwrap();
r.push(Hspend {cv: Hhex{bytes:s.cv().to_bytes().to_vec()}, anchor: Hhex{bytes:s.anchor().to_bytes().to_vec()}, nullifier: Hhex{bytes:s.nullifier().to_vec()}, rk: Hhex{bytes: rk.into_inner()}, proof: Hhex{bytes:s.zkproof().to_vec()}, authsig: Hhex{bytes:authsig.into_inner()}});
}
return r
}
}
#[derive(BorshSerialize, BorshDeserialize)]
pub struct HOBundle {
empty: bool,
actions: Vec<Haction>,
flags: Hflags,
value: i64,
anchor: Hhex,
proof: Hhex,
bindingsig: Hhex
}
impl<RW> ToHaskell<RW> for HOBundle {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl HOBundle {
pub fn from_bundle(b: &OrchardBundle<OrchardAuthorized, Amount>) -> HOBundle {
return HOBundle {empty: false, actions: Haction::pack(b.actions()), flags: Hflags::pack(b.flags()), value: i64::from(b.value_balance()), anchor: Hhex{ bytes: b.anchor().to_bytes().to_vec()}, proof: Hhex { bytes: b.authorization().proof().as_ref().to_vec()}, bindingsig: Hhex {bytes: <[u8; 64]>::from(b.authorization().binding_signature()).to_vec()}}
}
}
#[derive(BorshSerialize, BorshDeserialize)]
pub struct Hflags {
spends: bool,
outputs: bool
}
impl<RW> ToHaskell<RW> for Hflags {
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
self.serialize(writer)?;
Ok(())
}
}
impl Hflags {
pub fn pack(f: &Flags) -> Hflags {
return Hflags {spends: f.spends_enabled(), outputs: f.outputs_enabled()}
}
}
#[derive(BorshSerialize, BorshDeserialize)] #[derive(BorshSerialize, BorshDeserialize)]
pub struct Hufvk { pub struct Hufvk {
net: u8, net: u8,
@ -674,19 +802,38 @@ pub extern "C" fn rust_wrapper_tx_read(
match parsed_tx { match parsed_tx {
Ok(t) => { Ok(t) => {
let tb = t.transparent_bundle(); let tb = t.transparent_bundle();
match tb { let sb = t.sapling_bundle();
Some(my_tb) => { let ob = t.orchard_bundle();
let h = Htx {txid: t.txid().as_ref().to_vec(), locktime: t.lock_time(), expiry: u32::from(t.expiry_height()), t_bundle: HTBundle::from_bundle(my_tb) }; let h1 = Htx
marshall_to_haskell_var(&h, out, out_len, RW); { txid: t.txid().as_ref().to_vec()
}, , locktime: t.lock_time()
None => { , expiry: u32::from(t.expiry_height())
let h0 = Htx {txid: t.txid().as_ref().to_vec(), locktime: t.lock_time(), expiry: u32::from(t.expiry_height()), t_bundle: HTBundle {empty: true, vin: vec![HTxIn {outpoint: Houtpoint {hash: vec![0], index: 0}, script: vec![0], sequence: 0}], vout: vec![HTxOut {amt: 0, script: vec![0]}], coinbase: true} }; , t_bundle: match tb {
marshall_to_haskell_var(&h0, out, out_len, RW); Some(tb1) => {HTBundle::from_bundle(tb1)},
None => {HTBundle {empty: true, vin: vec![HTxIn {outpoint: Houtpoint {hash: vec![0], index: 0}, script: vec![0], sequence: 0}], vout: vec![HTxOut {amt: 0, script: vec![0]}], coinbase: false}}}
, s_bundle: match sb {
Some(sb1) => {HSBundle::from_bundle(sb1)},
None => {HSBundle{empty: true, spends: vec![Hspend{cv:Hhex { bytes: vec![0]} , anchor:Hhex { bytes: vec![0]} , nullifier:Hhex { bytes: vec![0]} , rk:Hhex { bytes: vec![0]} , proof:Hhex { bytes: vec![0]} , authsig:Hhex { bytes: vec![0]} }], outputs: vec![HshieldedOutput {cv: Hhex { bytes: vec![0]}, cmu: Hhex { bytes: vec![0]}, eph_key: Hhex { bytes: vec![0]}, enc_txt: Hhex { bytes: vec![0]}, out_txt: Hhex { bytes: vec![0]}, proof: Hhex { bytes: vec![0]}}], value: 0, sig: vec![0]}} }
, o_bundle: match ob {
Some(ob1) => {HOBundle::from_bundle(ob1)},
None => {HOBundle{empty: true, actions: vec![Haction {nf:Hhex { bytes: vec![0]} , rk:Hhex { bytes: vec![0]} , cmx:Hhex { bytes: vec![0]} , eph_key:Hhex { bytes: vec![0]} , enc_txt:Hhex { bytes: vec![0]} , out_txt:Hhex { bytes: vec![0]} , cv:Hhex { bytes: vec![0]} , auth:Hhex { bytes: vec![0]} }], flags: Hflags{ spends:false, outputs:false}, value: 0, anchor: Hhex { bytes: vec![0]}, proof: Hhex { bytes: vec![0]} , bindingsig: Hhex { bytes: vec![0]}}}
} }
} };
marshall_to_haskell_var(&h1, out, out_len, RW);
}, },
Err(_e) => { Err(_e) => {
let h0 = Htx {txid: vec![0], locktime: 0, expiry: 0, t_bundle: HTBundle {empty: true, vin: vec![HTxIn {outpoint: Houtpoint {hash: vec![0], index: 0}, script: vec![0], sequence: 0}], vout: vec![HTxOut {amt: 0, script: vec![0]}], coinbase: true} }; let h0 = Htx
{txid: vec![0],
locktime: 0,
expiry: 0,
t_bundle: HTBundle
{empty: true,
vin: vec![HTxIn {outpoint: Houtpoint {hash: vec![0], index: 0}, script: vec![0], sequence: 0}],
vout: vec![HTxOut {amt: 0, script: vec![0]}],
coinbase: true},
s_bundle: HSBundle{empty: true, spends: vec![Hspend{cv:Hhex { bytes: vec![0]} , anchor:Hhex { bytes: vec![0]} , nullifier:Hhex { bytes: vec![0]} , rk:Hhex { bytes: vec![0]} , proof:Hhex { bytes: vec![0]} , authsig:Hhex { bytes: vec![0]} }], outputs: vec![HshieldedOutput {cv: Hhex { bytes: vec![0]}, cmu: Hhex { bytes: vec![0]}, eph_key: Hhex { bytes: vec![0]}, enc_txt: Hhex { bytes: vec![0]}, out_txt: Hhex { bytes: vec![0]}, proof: Hhex { bytes: vec![0]}}], value: 0, sig: vec![0]},
o_bundle: HOBundle{empty: true, actions: vec![Haction {nf:Hhex { bytes: vec![0]} , rk:Hhex { bytes: vec![0]} , cmx:Hhex { bytes: vec![0]} , eph_key:Hhex { bytes: vec![0]} , enc_txt:Hhex { bytes: vec![0]} , out_txt:Hhex { bytes: vec![0]} , cv:Hhex { bytes: vec![0]} , auth:Hhex { bytes: vec![0]} }], flags: Hflags{ spends:false, outputs:false}, value: 0, anchor: Hhex { bytes: vec![0]}, proof: Hhex { bytes: vec![0]} , bindingsig: Hhex { bytes: vec![0]}}
};
marshall_to_haskell_var(&h0, out, out_len, RW); marshall_to_haskell_var(&h0, out, out_len, RW);
} }
} }
@ -847,7 +994,7 @@ pub extern "C" fn rust_wrapper_derive_orchard_spending_key(
out_len: &mut usize out_len: &mut usize
){ ){
let s: Vec<u8> = marshall_from_haskell_var(seed, seed_len, RW); let s: Vec<u8> = marshall_from_haskell_var(seed, seed_len, RW);
let sk = SpendingKey::from_zip32_seed(&s, coin_type, zip32::AccountId::try_from(acc_id).unwrap()); let sk = SpendingKey::from_zip32_seed(&s, coin_type, u32::from(zip32::AccountId::try_from(acc_id).unwrap()));
match sk { match sk {
Ok(key) => { Ok(key) => {
marshall_to_haskell_var(&key.to_bytes().to_vec(), out, out_len, RW); marshall_to_haskell_var(&key.to_bytes().to_vec(), out, out_len, RW);

View File

@ -129,6 +129,8 @@ data Transaction = Transaction
, tx_conf :: !Int , tx_conf :: !Int
, tx_expiry :: !Int , tx_expiry :: !Int
, tx_transpBundle :: !(Maybe TransparentBundle) , tx_transpBundle :: !(Maybe TransparentBundle)
, tx_saplingBundle :: !(Maybe SaplingBundle)
, tx_orchardBundle :: !(Maybe OrchardBundle)
} deriving (Prelude.Show, Eq, Read) } deriving (Prelude.Show, Eq, Read)
-- | The transparent portion of a Zcash transaction -- | The transparent portion of a Zcash transaction
@ -285,6 +287,8 @@ data RawZebraTx = RawZebraTx
, zt_locktime :: !Word32 , zt_locktime :: !Word32
, zt_expiry :: !Word32 , zt_expiry :: !Word32
, zt_tBundle :: !RawTBundle , zt_tBundle :: !RawTBundle
, zt_sBundle :: !RawSBundle
, zt_oBundle :: !RawOBundle
} deriving stock (Eq, Prelude.Show, GHC.Generic) } deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show) deriving anyclass (Data.Structured.Show)
@ -301,6 +305,78 @@ data RawTBundle = RawTBundle
deriving anyclass (Data.Structured.Show) deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawTBundle deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawTBundle
-- | Type for a raw deserialized Zebra Sapling bundle
data RawSBundle = RawSBundle
{ zsb_empty :: !Bool
, zsb_spends :: ![ShieldedSpend]
, zsb_outputs :: ![ShieldedOutput]
, zsb_value :: !Int64
, zsb_sig :: !HexString
} deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawSBundle
data SaplingBundle = SaplingBundle
{ sbSpends :: ![ShieldedSpend]
, sbOutputs :: ![ShieldedOutput]
, sbValue :: !Int64
, sbSig :: !HexString
} deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
fromRawSBundle :: RawSBundle -> Maybe SaplingBundle
fromRawSBundle b =
if zsb_empty b
then Nothing
else Just $
SaplingBundle (zsb_spends b) (zsb_outputs b) (zsb_value b) (zsb_sig b)
-- | Type for a raw deseralized Zebra Orchard bundle
data RawOBundle = RawOBundle
{ zob_empty :: !Bool
, zob_actions :: ![OrchardAction]
, zob_flags :: !OrchardFlags
, zob_value :: !Int64
, zob_anchor :: !HexString
, zob_proof :: !HexString
, zob_sig :: !HexString
} deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct RawOBundle
-- | Type for an Orchard Bundle
data OrchardBundle = OrchardBundle
{ obActions :: ![OrchardAction]
, obFlags :: !OrchardFlags
, obValue :: !Int64
, obAnchor :: !HexString
, obProof :: !HexString
, obSig :: !HexString
} deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
fromRawOBundle :: RawOBundle -> Maybe OrchardBundle
fromRawOBundle b =
if zob_empty b
then Nothing
else Just $
OrchardBundle
(zob_actions b)
(zob_flags b)
(zob_value b)
(zob_anchor b)
(zob_proof b)
(zob_sig b)
-- | Type for the Orchard bundle flags
data OrchardFlags = OrchardFlags
{ of_spends :: !Bool
, of_outputs :: !Bool
} deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardFlags
-- | Type for the response from the `zebrad` RPC method `getinfo` -- | Type for the response from the `zebrad` RPC method `getinfo`
data ZebraGetInfo = ZebraGetInfo data ZebraGetInfo = ZebraGetInfo
{ zgi_build :: !T.Text { zgi_build :: !T.Text
@ -427,7 +503,7 @@ data ShieldedOutput = ShieldedOutput
, s_encCipherText :: !HexString -- ^ The output note encrypted to the recipient , s_encCipherText :: !HexString -- ^ The output note encrypted to the recipient
, s_outCipherText :: !HexString -- ^ A ciphertext enabling the sender to recover the output note , s_outCipherText :: !HexString -- ^ A ciphertext enabling the sender to recover the output note
, s_proof :: !HexString -- ^ Zero-knowledge proof using the Sapling Output circuit , s_proof :: !HexString -- ^ Zero-knowledge proof using the Sapling Output circuit
} deriving stock (Eq, Prelude.Show, GHC.Generic) } deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show) deriving anyclass (Data.Structured.Show)
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedOutput deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct ShieldedOutput
@ -482,10 +558,10 @@ data RawUA = RawUA
-- | Type to represent a Unified Full Viewing Key -- | Type to represent a Unified Full Viewing Key
data UnifiedFullViewingKey = UnifiedFullViewingKey data UnifiedFullViewingKey = UnifiedFullViewingKey
{ net :: Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@. { net :: !Word8 -- ^ Number representing the network the key belongs to. @1@ for @mainnet@, @2@ for @testnet@ and @3@ for @regtestnet@.
, o_key :: BS.ByteString -- ^ Raw bytes of the Orchard Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316) , o_key :: !BS.ByteString -- ^ Raw bytes of the Orchard Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316)
, s_key :: BS.ByteString -- ^ Raw bytes of the Sapling Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316) , s_key :: !BS.ByteString -- ^ Raw bytes of the Sapling Full Viewing Key as specified in [ZIP-316](https://zips.z.cash/zip-0316)
, t_key :: BS.ByteString -- ^ Raw bytes of the P2PKH chain code and public key as specified in [ZIP-316](https://zips.z.cash/zip-0316) , t_key :: !BS.ByteString -- ^ Raw bytes of the P2PKH chain code and public key as specified in [ZIP-316](https://zips.z.cash/zip-0316)
} deriving stock (Eq, Prelude.Show, GHC.Generic) } deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show) deriving anyclass (Data.Structured.Show)
@ -493,14 +569,14 @@ data UnifiedFullViewingKey = UnifiedFullViewingKey
-- | Type to represent an Orchard Action as provided by the @getrawtransaction@ RPC method of @zcashd@, and defined in the [Zcash Protocol](https://zips.z.cash/protocol/protocol.pdf) -- | Type to represent an Orchard Action as provided by the @getrawtransaction@ RPC method of @zcashd@, and defined in the [Zcash Protocol](https://zips.z.cash/protocol/protocol.pdf)
data OrchardAction = OrchardAction data OrchardAction = OrchardAction
{ nf :: HexString -- ^ The nullifier of the input note { nf :: !HexString -- ^ The nullifier of the input note
, rk :: HexString -- ^ The randomized validating key for @auth@ , rk :: !HexString -- ^ The randomized validating key for @auth@
, cmx :: HexString -- ^ The x-coordinate of the note commitment for the output note , cmx :: !HexString -- ^ The x-coordinate of the note commitment for the output note
, eph_key :: HexString -- ^ An encoding of an ephemeral Pallas public key , eph_key :: !HexString -- ^ An encoding of an ephemeral Pallas public key
, enc_ciphertext :: HexString -- ^ The output note encrypted to the recipient , enc_ciphertext :: !HexString -- ^ The output note encrypted to the recipient
, out_ciphertext :: HexString -- ^ A ciphertext enabling the sender to recover the output note , out_ciphertext :: !HexString -- ^ A ciphertext enabling the sender to recover the output note
, cv :: HexString -- ^ A value commitment to the net value of the input note minus the output note , cv :: !HexString -- ^ A value commitment to the net value of the input note minus the output note
, auth :: HexString -- ^ A signature authorizing the spend in this Action , auth :: !HexString -- ^ A signature authorizing the spend in this Action
} deriving stock (Eq, Prelude.Show, GHC.Generic, Read) } deriving stock (Eq, Prelude.Show, GHC.Generic, Read)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show) deriving anyclass (Data.Structured.Show)
@ -521,9 +597,9 @@ instance FromJSON OrchardAction where
-- | Type to represent a decoded note -- | Type to represent a decoded note
data DecodedNote = DecodedNote data DecodedNote = DecodedNote
{ a_value :: Int64 -- ^ The amount of the transaction in _zatoshis_. { a_value :: !Int64 -- ^ The amount of the transaction in _zatoshis_.
, a_recipient :: BS.ByteString -- ^ The recipient Orchard receiver. , a_recipient :: !BS.ByteString -- ^ The recipient Orchard receiver.
, a_memo :: BS.ByteString -- ^ The decoded shielded memo field. , a_memo :: !BS.ByteString -- ^ The decoded shielded memo field.
} deriving stock (Eq, Prelude.Show, GHC.Generic) } deriving stock (Eq, Prelude.Show, GHC.Generic)
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
deriving anyclass (Data.Structured.Show) deriving anyclass (Data.Structured.Show)

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,7 @@ cabal-version: 3.0
-- see: https://github.com/sol/hpack -- see: https://github.com/sol/hpack
name: zcash-haskell name: zcash-haskell
version: 0.5.2.0 version: 0.5.3.0
synopsis: Utilities to interact with the Zcash blockchain synopsis: Utilities to interact with the Zcash blockchain
description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme> description: Please see the README on the repo at <https://git.vergara.tech/Vergara_Tech/zcash-haskell#readme>
category: Blockchain category: Blockchain