Merge pull request 'Implement transaction creation' (#73) from rav001 into dev040
Reviewed-on: #73
This commit is contained in:
commit
c9f13643e4
8 changed files with 682 additions and 58 deletions
21
CHANGELOG.md
21
CHANGELOG.md
|
@ -5,6 +5,27 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [0.6.1.0]
|
||||
|
||||
### Added
|
||||
|
||||
- Function to create a raw transaction
|
||||
- New types for transaction creation:
|
||||
- `Rseed`
|
||||
- `TransparentTxSpend`
|
||||
- `SaplingTxSpend`
|
||||
- `OrchardTxSpend`
|
||||
- `OutgoingNote`
|
||||
- Rust crates:
|
||||
- `secp256k1`
|
||||
- `jubjub`
|
||||
- `rand_core`
|
||||
|
||||
|
||||
### Changed
|
||||
|
||||
- `DecodedNote` type now includes a field for `rho` and one for `rseed`
|
||||
|
||||
## [0.6.0.0]
|
||||
|
||||
### Added
|
||||
|
|
168
librustzcash-wrapper/Cargo.lock
generated
168
librustzcash-wrapper/Cargo.lock
generated
|
@ -318,6 +318,12 @@ dependencies = [
|
|||
"tinyvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea184aa71bb362a1157c896979544cc23974e08fd265f29ea96b59f0b4a555b"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
|
@ -703,6 +709,19 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hdwallet"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a03ba7d4c9ea41552cd4351965ff96883e629693ae85005c501bb4b9e1c48a7"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"rand_core",
|
||||
"ring",
|
||||
"secp256k1",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.1"
|
||||
|
@ -796,6 +815,15 @@ dependencies = [
|
|||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jubjub"
|
||||
version = "0.10.0"
|
||||
|
@ -1313,6 +1341,30 @@ version = "0.7.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.16.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ripemd"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f"
|
||||
dependencies = [
|
||||
"digest 0.10.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.20"
|
||||
|
@ -1336,10 +1388,13 @@ dependencies = [
|
|||
"f4jumble",
|
||||
"haskell-ffi",
|
||||
"incrementalmerkletree",
|
||||
"jubjub",
|
||||
"nonempty",
|
||||
"orchard",
|
||||
"proc-macro2",
|
||||
"rand_core",
|
||||
"sapling-crypto",
|
||||
"secp256k1",
|
||||
"zcash_address 0.2.0",
|
||||
"zcash_client_backend",
|
||||
"zcash_note_encryption",
|
||||
|
@ -1385,6 +1440,24 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "secp256k1"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894"
|
||||
dependencies = [
|
||||
"secp256k1-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "secp256k1-sys"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "secrecy"
|
||||
version = "0.8.0"
|
||||
|
@ -1661,6 +1734,12 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
|
@ -1673,6 +1752,70 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.32",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.92"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96"
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.68"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.0"
|
||||
|
@ -1684,6 +1827,28 @@ dependencies = [
|
|||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
|
@ -1882,6 +2047,7 @@ dependencies = [
|
|||
"ff",
|
||||
"fpe",
|
||||
"group",
|
||||
"hdwallet",
|
||||
"hex",
|
||||
"incrementalmerkletree",
|
||||
"jubjub",
|
||||
|
@ -1891,7 +2057,9 @@ dependencies = [
|
|||
"rand",
|
||||
"rand_core",
|
||||
"redjubjub",
|
||||
"ripemd",
|
||||
"sapling-crypto",
|
||||
"secp256k1",
|
||||
"sha2 0.10.6",
|
||||
"subtle",
|
||||
"tracing",
|
||||
|
|
|
@ -13,13 +13,16 @@ borsh = "0.10"
|
|||
bech32 = "0.11"
|
||||
orchard = "0.7.1"
|
||||
zcash_note_encryption = "0.4.0"
|
||||
zcash_primitives = "0.14.0"
|
||||
zcash_primitives = { version = "0.14.0", features = ["transparent-inputs"]}
|
||||
zcash_client_backend = "0.11.1"
|
||||
sapling-crypto = "0.1.3"
|
||||
zip32 = "0.1.0"
|
||||
proc-macro2 = "1.0.66"
|
||||
nonempty = "0.7.0"
|
||||
incrementalmerkletree = "0.5.0"
|
||||
secp256k1 = "0.26.0"
|
||||
jubjub = "0.10.0"
|
||||
rand_core = { version = "0.6.4", features = ["getrandom"]}
|
||||
|
||||
|
||||
[features]
|
||||
|
|
|
@ -12,6 +12,8 @@ use std::{
|
|||
|
||||
use nonempty::NonEmpty;
|
||||
|
||||
use rand_core::OsRng;
|
||||
|
||||
use f4jumble;
|
||||
|
||||
use borsh::{BorshDeserialize, BorshSerialize};
|
||||
|
@ -23,6 +25,10 @@ use haskell_ffi::{
|
|||
FromHaskell, HaskellSize, ToHaskell
|
||||
};
|
||||
|
||||
use secp256k1::SecretKey;
|
||||
|
||||
use jubjub::Fr;
|
||||
|
||||
use incrementalmerkletree::{
|
||||
frontier::CommitmentTree,
|
||||
witness::IncrementalWitness
|
||||
|
@ -39,8 +45,13 @@ use sapling_crypto::{
|
|||
Node,
|
||||
MerklePath,
|
||||
PaymentAddress,
|
||||
Anchor as SaplingAnchor,
|
||||
value::ValueCommitment as SaplingValueCommitment,
|
||||
note::ExtractedNoteCommitment as SaplingNoteCommitment,
|
||||
note::{
|
||||
ExtractedNoteCommitment as SaplingNoteCommitment,
|
||||
Note as SaplingNote,
|
||||
Rseed
|
||||
},
|
||||
keys::{
|
||||
PreparedIncomingViewingKey as SaplingPreparedIncomingViewingKey,
|
||||
ExpandedSpendingKey,
|
||||
|
@ -57,6 +68,11 @@ use sapling_crypto::{
|
|||
Authorized as SaplingAuthorized,
|
||||
Bundle as SaplingBundle
|
||||
},
|
||||
value::NoteValue as SaplingNoteValue,
|
||||
circuit::{
|
||||
SpendParameters,
|
||||
OutputParameters
|
||||
},
|
||||
zip32::{
|
||||
sapling_find_address,
|
||||
DiversifierKey
|
||||
|
@ -70,9 +86,24 @@ use zcash_primitives::{
|
|||
read_incremental_witness,
|
||||
write_incremental_witness
|
||||
},
|
||||
legacy::{
|
||||
Script,
|
||||
TransparentAddress
|
||||
},
|
||||
zip339::{Count, Mnemonic},
|
||||
transaction::components::{
|
||||
amount::Amount,
|
||||
transaction::{
|
||||
Transaction,
|
||||
fees::zip317::FeeRule,
|
||||
builder::{
|
||||
Builder,
|
||||
Error,
|
||||
BuildConfig
|
||||
},
|
||||
components::{
|
||||
amount::{
|
||||
Amount,
|
||||
NonNegativeAmount
|
||||
},
|
||||
transparent::{
|
||||
Bundle as TransparentBundle,
|
||||
TxIn,
|
||||
|
@ -80,8 +111,9 @@ use zcash_primitives::{
|
|||
OutPoint,
|
||||
Authorized
|
||||
}
|
||||
}
|
||||
},
|
||||
transaction::Transaction,
|
||||
memo::MemoBytes,
|
||||
consensus::{
|
||||
BranchId::Nu5,
|
||||
MainNetwork,
|
||||
|
@ -107,6 +139,7 @@ use zcash_client_backend::keys::sapling::{
|
|||
use zcash_primitives::zip32::DiversifierIndex;
|
||||
|
||||
use orchard::{
|
||||
Address as OrchardAddress,
|
||||
Bundle as OrchardBundle,
|
||||
bundle::{
|
||||
Authorized as OrchardAuthorized,
|
||||
|
@ -114,11 +147,18 @@ use orchard::{
|
|||
},
|
||||
Action,
|
||||
keys::{SpendingKey, FullViewingKey, PreparedIncomingViewingKey, Scope},
|
||||
note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment},
|
||||
note::{RandomSeed, Note, Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment},
|
||||
note_encryption::OrchardDomain,
|
||||
primitives::redpallas::{VerificationKey, SpendAuth, Signature},
|
||||
tree::MerkleHashOrchard,
|
||||
value::ValueCommitment
|
||||
tree::{
|
||||
MerklePath as OrchardMerklePath,
|
||||
MerkleHashOrchard,
|
||||
Anchor as OrchardAnchor
|
||||
},
|
||||
value::{
|
||||
ValueCommitment,
|
||||
NoteValue
|
||||
}
|
||||
};
|
||||
|
||||
use bech32::{
|
||||
|
@ -255,7 +295,9 @@ pub struct Hnote {
|
|||
note: u64,
|
||||
recipient: Vec<u8>,
|
||||
memo: Vec<u8>,
|
||||
nullifier: Vec<u8>
|
||||
nullifier: Vec<u8>,
|
||||
rho: Vec<u8>,
|
||||
rseed: Hrseed
|
||||
}
|
||||
|
||||
impl<RW> ToHaskell<RW> for Hnote {
|
||||
|
@ -265,6 +307,27 @@ impl<RW> ToHaskell<RW> for Hnote {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub struct Hrseed {
|
||||
kind: u8,
|
||||
bytes: Vec<u8>
|
||||
}
|
||||
|
||||
|
||||
impl<RW> FromHaskell<RW> for Hrseed {
|
||||
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||
let x = Hrseed::deserialize(buf)?;
|
||||
Ok(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<RW> ToHaskell<RW> for Hrseed {
|
||||
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
|
||||
self.serialize(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub struct Hua {
|
||||
net: u8,
|
||||
|
@ -363,6 +426,13 @@ pub struct HTxOut {
|
|||
script: Vec<u8>
|
||||
}
|
||||
|
||||
impl<RW> FromHaskell<RW> for HTxOut {
|
||||
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||
let x = HTxOut::deserialize(buf)?;
|
||||
Ok(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<RW> ToHaskell<RW> for HTxOut {
|
||||
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
|
||||
self.serialize(writer)?;
|
||||
|
@ -374,6 +444,9 @@ impl HTxOut {
|
|||
pub fn pack(t: &TxOut) -> HTxOut {
|
||||
return HTxOut { amt: i64::from_le_bytes(t.value.to_i64_le_bytes()) , script: t.script_pubkey.0.clone() }
|
||||
}
|
||||
pub fn unpack(&self) -> TxOut {
|
||||
TxOut { value: NonNegativeAmount::from_nonnegative_i64(self.amt).unwrap(), script_pubkey: Script(self.script.clone())}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
|
@ -382,6 +455,13 @@ pub struct Houtpoint {
|
|||
index: u32
|
||||
}
|
||||
|
||||
impl<RW> FromHaskell<RW> for Houtpoint {
|
||||
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||
let x = Houtpoint::deserialize(buf)?;
|
||||
Ok(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<RW> ToHaskell<RW> for Houtpoint {
|
||||
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
|
||||
self.serialize(writer)?;
|
||||
|
@ -393,6 +473,31 @@ impl Houtpoint {
|
|||
pub fn pack(o: &OutPoint) -> Houtpoint {
|
||||
return Houtpoint {hash: o.hash().to_vec() , index: o.n() }
|
||||
}
|
||||
|
||||
pub fn unpack(&self) -> OutPoint {
|
||||
OutPoint::new(to_array(self.hash.clone()), self.index)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub struct HtransparentInput {
|
||||
sk: Vec<u8>,
|
||||
utxo: Houtpoint,
|
||||
coin: HTxOut
|
||||
}
|
||||
|
||||
impl<RW> FromHaskell<RW> for HtransparentInput {
|
||||
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||
let x = HtransparentInput::deserialize(buf)?;
|
||||
Ok(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<RW> ToHaskell<RW> for HtransparentInput {
|
||||
fn to_haskell<W: Write>(&self, writer: &mut W, _tag: PhantomData<RW>) -> Result<()> {
|
||||
self.serialize(writer)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
|
@ -447,6 +552,52 @@ impl Hspend {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub struct HsaplingInput {
|
||||
sk: Vec<u8>,
|
||||
note: Hnote,
|
||||
iw: Vec<u8>
|
||||
}
|
||||
|
||||
impl<RW> FromHaskell<RW> for HsaplingInput {
|
||||
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||
let x = HsaplingInput::deserialize(buf)?;
|
||||
Ok(x)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub struct HorchardInput {
|
||||
sk: Vec<u8>,
|
||||
note: Hnote,
|
||||
iw: Vec<u8>
|
||||
}
|
||||
|
||||
impl<RW> FromHaskell<RW> for HorchardInput {
|
||||
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||
let x = HorchardInput::deserialize(buf)?;
|
||||
Ok(x)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub struct Houtput {
|
||||
kind: u8,
|
||||
ovk: Vec<u8>,
|
||||
to: Vec<u8>,
|
||||
amt: u64,
|
||||
memo: Vec<u8>,
|
||||
chg: bool
|
||||
}
|
||||
|
||||
impl<RW> FromHaskell<RW> for Houtput {
|
||||
fn from_haskell(buf: &mut &[u8], _tag: PhantomData<RW>) -> Result<Self> {
|
||||
let x = Houtput::deserialize(buf)?;
|
||||
Ok(x)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(BorshSerialize, BorshDeserialize)]
|
||||
pub struct HOBundle {
|
||||
empty: bool,
|
||||
|
@ -771,23 +922,31 @@ pub extern "C" fn rust_wrapper_sapling_esk_decrypt(
|
|||
match result {
|
||||
Some((n, r, m)) => {
|
||||
let nullifier = n.nf(&nk, pos);
|
||||
let hn = Hnote {note: n.value().inner(), recipient: r.to_bytes().to_vec(), memo: m.as_slice().to_vec(), nullifier: nullifier.to_vec() };
|
||||
let rseed = match n.rseed() {
|
||||
Rseed::BeforeZip212(x) => {
|
||||
Hrseed {kind: 1, bytes: x.to_bytes().to_vec()}
|
||||
},
|
||||
Rseed::AfterZip212(y) => {
|
||||
Hrseed {kind: 2, bytes: y.to_vec()}
|
||||
}
|
||||
};
|
||||
let hn = Hnote {note: n.value().inner(), recipient: r.to_bytes().to_vec(), memo: m.as_slice().to_vec(), nullifier: nullifier.to_vec(), rho: vec![0], rseed };
|
||||
marshall_to_haskell_var(&hn, out, out_len, RW);
|
||||
},
|
||||
None => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0]};
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed{ kind: 0, bytes: vec![0]}};
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_e1) => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0] };
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed{ kind: 0, bytes: vec![0]} };
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_e) => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0] };
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed{ kind: 0, bytes: vec![0]} };
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
|
@ -816,23 +975,31 @@ pub extern "C" fn rust_wrapper_sapling_note_decrypt_v2(
|
|||
let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action3);
|
||||
match result {
|
||||
Some((n, r, m)) => {
|
||||
let hn = Hnote {note: n.value().inner(), recipient: r.to_bytes().to_vec(), memo: m.as_slice().to_vec(), nullifier: vec![0]};
|
||||
let rseed = match n.rseed() {
|
||||
Rseed::BeforeZip212(x) => {
|
||||
Hrseed { kind: 1, bytes: x.to_bytes().to_vec()}
|
||||
},
|
||||
Rseed::AfterZip212(y) => {
|
||||
Hrseed { kind: 2, bytes: y.to_vec()}
|
||||
}
|
||||
};
|
||||
let hn = Hnote {note: n.value().inner(), recipient: r.to_bytes().to_vec(), memo: m.as_slice().to_vec(), nullifier: vec![0], rho: vec![0], rseed};
|
||||
marshall_to_haskell_var(&hn, out, out_len, RW);
|
||||
}
|
||||
None => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0]};
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_e1) => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0] , nullifier: vec![0]};
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0] , nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_e) => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0]};
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
|
@ -866,17 +1033,19 @@ pub extern "C" fn rust_wrapper_orchard_note_decrypt(
|
|||
let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action);
|
||||
match result {
|
||||
Some((n, r, m)) => {
|
||||
let hn = Hnote {note: n.value().inner(), recipient: r.to_raw_address_bytes().to_vec(), memo: m.to_vec(), nullifier: vec![0]};
|
||||
let rho = n.rho().to_bytes().to_vec();
|
||||
let rseed = Hrseed {kind: 3, bytes: n.rseed().as_bytes().to_vec()};
|
||||
let hn = Hnote {note: n.value().inner(), recipient: r.to_raw_address_bytes().to_vec(), memo: m.to_vec(), nullifier: vec![0], rho, rseed};
|
||||
marshall_to_haskell_var(&hn, out, out_len, RW);
|
||||
}
|
||||
None => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0]};
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
},
|
||||
None => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0]};
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
|
@ -914,11 +1083,13 @@ pub extern "C" fn rust_wrapper_orchard_note_decrypt_sk(
|
|||
let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action);
|
||||
match result {
|
||||
Some((n, r, m)) => {
|
||||
let hn = Hnote {note: n.value().inner(), recipient: r.to_raw_address_bytes().to_vec(), memo: m.to_vec(), nullifier: n.nullifier(&fvk).to_bytes().to_vec()};
|
||||
let rho = n.rho().to_bytes().to_vec();
|
||||
let rseed = Hrseed {kind: 3, bytes: n.rseed().as_bytes().to_vec()};
|
||||
let hn = Hnote {note: n.value().inner(), recipient: r.to_raw_address_bytes().to_vec(), memo: m.to_vec(), nullifier: n.nullifier(&fvk).to_bytes().to_vec(), rho, rseed};
|
||||
marshall_to_haskell_var(&hn, out, out_len, RW);
|
||||
}
|
||||
None => {
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0]};
|
||||
let hn0 = Hnote { note: 0, recipient: vec![0], memo: vec![0], nullifier: vec![0], rho: vec![0], rseed: Hrseed {kind: 0, bytes: vec![0]}};
|
||||
marshall_to_haskell_var(&hn0, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
|
@ -1454,8 +1625,193 @@ pub extern "C" fn rust_wrapper_decode_sapling_address(
|
|||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_wrapper_create_transaction(
|
||||
sapling: *const u8,
|
||||
sapling_len: usize,
|
||||
sap_wit: *const u8,
|
||||
sap_wit_len: usize,
|
||||
orch_wit: *const u8,
|
||||
orch_wit_len: usize,
|
||||
t_input: *const u8,
|
||||
t_input_len: usize,
|
||||
s_input: *const u8,
|
||||
s_input_len: usize,
|
||||
o_input: *const u8,
|
||||
o_input_len: usize,
|
||||
out_list: *const u8,
|
||||
out_list_len: usize,
|
||||
sapspend: *const u8,
|
||||
sapspend_len: usize,
|
||||
sapoutput: *const u8,
|
||||
sapoutput_len: usize,
|
||||
net: bool,
|
||||
bl_height: u32,
|
||||
out: *mut u8,
|
||||
out_len: &mut usize){
|
||||
let sap_wit_in: Vec<u8> = marshall_from_haskell_var(sap_wit, sap_wit_len, RW);
|
||||
let sap_wit_reader = Cursor::new(sap_wit_in);
|
||||
let sap_iw: Option<IncrementalWitness<Node, SAPLING_DEPTH>> = read_incremental_witness(sap_wit_reader).ok();
|
||||
let sap_anchor = match sap_iw {
|
||||
Some(s_iw) => {
|
||||
Some(SaplingAnchor::from(s_iw.root()))
|
||||
},
|
||||
None => {
|
||||
None
|
||||
}
|
||||
};
|
||||
let orch_wit_in: Vec<u8> = marshall_from_haskell_var(orch_wit, orch_wit_len, RW);
|
||||
let orch_wit_reader = Cursor::new(orch_wit_in);
|
||||
let orch_iw: Option<IncrementalWitness<MerkleHashOrchard, 32>> = read_incremental_witness(orch_wit_reader).ok();
|
||||
let orch_anchor = match orch_iw {
|
||||
Some(o_iw) => {
|
||||
Some(OrchardAnchor::from(o_iw.root()))
|
||||
},
|
||||
None => {
|
||||
None
|
||||
}
|
||||
};
|
||||
let build_config = BuildConfig::Standard {sapling_anchor: sap_anchor, orchard_anchor: orch_anchor};
|
||||
let mut main_builder = Builder::new(MainNetwork, BlockHeight::from(bl_height), build_config);
|
||||
let mut test_builder = Builder::new(TestNetwork, BlockHeight::from(bl_height), build_config);
|
||||
let trans_input: Vec<HtransparentInput> = marshall_from_haskell_var(t_input, t_input_len, RW);
|
||||
for t_in in trans_input {
|
||||
if t_in.sk.len() > 1 {
|
||||
let k = SecretKey::from_slice(&t_in.sk).unwrap();
|
||||
if net {
|
||||
match main_builder.add_transparent_input(k, t_in.utxo.unpack(), t_in.coin.unpack()) {
|
||||
Ok(()) => {
|
||||
continue;
|
||||
},
|
||||
Err(_e) => { println!("Error reading transparent input"); }
|
||||
}
|
||||
} else {
|
||||
match test_builder.add_transparent_input(k, t_in.utxo.unpack(), t_in.coin.unpack()) {
|
||||
Ok(()) => {
|
||||
continue;
|
||||
},
|
||||
Err(_e) => { println!("Error reading transparent input"); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let sap_input: Vec<HsaplingInput> = marshall_from_haskell_var(s_input, s_input_len, RW);
|
||||
for s_in in sap_input {
|
||||
if s_in.sk.len() > 1 {
|
||||
let sp_key = ExtendedSpendingKey::from_bytes(&s_in.sk);
|
||||
match sp_key {
|
||||
Ok(sk) => {
|
||||
let pay_addr = PaymentAddress::from_bytes(&to_array(s_in.note.recipient)).unwrap();
|
||||
let rseed = if s_in.note.rseed.kind == 1 {
|
||||
Rseed::BeforeZip212(Fr::from_bytes(&to_array(s_in.note.rseed.bytes)).unwrap())
|
||||
} else {
|
||||
Rseed::AfterZip212(to_array(s_in.note.rseed.bytes))
|
||||
};
|
||||
let note = SaplingNote::from_parts(pay_addr, SaplingNoteValue::from_raw(s_in.note.note), rseed);
|
||||
let wit_reader = Cursor::new(s_in.iw);
|
||||
let iw: IncrementalWitness<Node, SAPLING_DEPTH> = read_incremental_witness(wit_reader).unwrap();
|
||||
let merkle_path = iw.path().unwrap();
|
||||
if net {
|
||||
let _mb = main_builder.add_sapling_spend::<String>(&sk, note, merkle_path).unwrap();
|
||||
} else {
|
||||
let _tb = test_builder.add_sapling_spend::<String>(&sk, note, merkle_path).unwrap();
|
||||
}
|
||||
},
|
||||
Err(_e) => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let orch_input: Vec<HorchardInput> = marshall_from_haskell_var(o_input, o_input_len, RW);
|
||||
for o_in in orch_input {
|
||||
if o_in.sk.len() > 1 {
|
||||
let sp_key = SpendingKey::from_bytes(o_in.sk[0..32].try_into().unwrap()).unwrap();
|
||||
let pay_addr = OrchardAddress::from_raw_address_bytes(&to_array(o_in.note.recipient)).unwrap();
|
||||
let rho = Nullifier::from_bytes(&to_array(o_in.note.rho)).unwrap();
|
||||
let rseed = RandomSeed::from_bytes(to_array(o_in.note.rseed.bytes), &rho).unwrap();
|
||||
let val = NoteValue::from_raw(o_in.note.note);
|
||||
let note = Note::from_parts(pay_addr, val, rho, rseed).unwrap();
|
||||
let wit_reader = Cursor::new(o_in.iw);
|
||||
let iw: IncrementalWitness<MerkleHashOrchard, 32> = read_incremental_witness(wit_reader).unwrap();
|
||||
let merkle_path = OrchardMerklePath::from(iw.path().unwrap());
|
||||
if net {
|
||||
let _mb = main_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path).unwrap();
|
||||
} else {
|
||||
let _tb = test_builder.add_orchard_spend::<String>(&sp_key, note, merkle_path).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
let outputs: Vec<Houtput> = marshall_from_haskell_var(out_list, out_list_len, RW);
|
||||
for output in outputs {
|
||||
match output.kind {
|
||||
1 => {
|
||||
let recipient = TransparentAddress::PublicKeyHash(to_array(output.to));
|
||||
let val = NonNegativeAmount::from_u64(output.amt).unwrap();
|
||||
if net {
|
||||
let _mb = main_builder.add_transparent_output(&recipient, val);
|
||||
} else {
|
||||
let _tb = test_builder.add_transparent_output(&recipient, val);
|
||||
}
|
||||
},
|
||||
2 => {
|
||||
let recipient = TransparentAddress::ScriptHash(to_array(output.to));
|
||||
let val = NonNegativeAmount::from_u64(output.amt).unwrap();
|
||||
if net {
|
||||
let _mb = main_builder.add_transparent_output(&recipient, val);
|
||||
} else {
|
||||
let _tb = test_builder.add_transparent_output(&recipient, val);
|
||||
}
|
||||
},
|
||||
3 => {
|
||||
let ovk = Some(ExpandedSpendingKey::from_spending_key(&output.ovk).ovk);
|
||||
let recipient = PaymentAddress::from_bytes(&to_array(output.to)).unwrap();
|
||||
let val = NonNegativeAmount::from_u64(output.amt).unwrap();
|
||||
let memo = MemoBytes::from_bytes(&output.memo).unwrap();
|
||||
if net {
|
||||
let _mb = main_builder.add_sapling_output::<String>(ovk, recipient, val, memo);
|
||||
} else {
|
||||
let _tb = test_builder.add_sapling_output::<String>(ovk, recipient, val, memo);
|
||||
}
|
||||
},
|
||||
4 => {
|
||||
let sk = SpendingKey::from_bytes(output.ovk[0..32].try_into().unwrap()).unwrap();
|
||||
let ovk = if output.chg {
|
||||
Some(FullViewingKey::from(&sk).to_ovk(Scope::Internal))
|
||||
}else {
|
||||
Some(FullViewingKey::from(&sk).to_ovk(Scope::External))
|
||||
};
|
||||
let recipient = OrchardAddress::from_raw_address_bytes(&to_array(output.to)).unwrap();
|
||||
let val = output.amt;
|
||||
let memo = MemoBytes::from_bytes(&output.memo).unwrap();
|
||||
if net {
|
||||
let _mb = main_builder.add_orchard_output::<String>(ovk, recipient, val, memo);
|
||||
} else {
|
||||
let _tb = test_builder.add_orchard_output::<String>(ovk, recipient, val, memo);
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
let spend_params_in: Vec<u8> = marshall_from_haskell_var(sapspend, sapspend_len, RW);
|
||||
let spend_params_reader = Cursor::new(spend_params_in);
|
||||
let spend_prover = SpendParameters::read(spend_params_reader, true).unwrap();
|
||||
let output_params_in: Vec<u8> = marshall_from_haskell_var(sapoutput, sapoutput_len, RW);
|
||||
let output_params_reader = Cursor::new(output_params_in);
|
||||
let output_prover = OutputParameters::read(output_params_reader, true).unwrap();
|
||||
let result = if net {
|
||||
main_builder.build(OsRng, &spend_prover, &output_prover, &FeeRule::standard())
|
||||
} else {
|
||||
test_builder.build(OsRng, &spend_prover, &output_prover, &FeeRule::standard())
|
||||
};
|
||||
match result {
|
||||
Ok(r) => {
|
||||
let mut out_bytes: Vec<u8> = Vec::new();
|
||||
let _t = r.transaction().write_v5(&mut out_bytes);
|
||||
let h = Hhex {bytes: out_bytes};
|
||||
marshall_to_haskell_var(&h, out, out_len, RW);
|
||||
},
|
||||
Err(_e) => {
|
||||
let x = Hhex {bytes: vec![0]};
|
||||
marshall_to_haskell_var(&x, out, out_len, RW);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -275,3 +275,19 @@ import ZcashHaskell.Types
|
|||
}
|
||||
-> `()'
|
||||
#}
|
||||
|
||||
{# fun unsafe rust_wrapper_create_transaction as rustWrapperCreateTx
|
||||
{ toBorshVar* `BS.ByteString'&
|
||||
, toBorshVar* `BS.ByteString'&
|
||||
, toBorshVar* `[TransparentTxSpend]'&
|
||||
, toBorshVar* `[SaplingTxSpend]'&
|
||||
, toBorshVar* `[OrchardTxSpend]'&
|
||||
, toBorshVar* `[OutgoingNote]'&
|
||||
, toBorshVar* `BS.ByteString'&
|
||||
, toBorshVar* `BS.ByteString'&
|
||||
, `Bool'
|
||||
, `Word64'
|
||||
, getVarBuffer `Buffer HexString'&
|
||||
}
|
||||
-> `()'
|
||||
#}
|
||||
|
|
|
@ -21,8 +21,8 @@ import Crypto.Secp256k1
|
|||
import qualified Data.ByteArray as BA
|
||||
import qualified Data.ByteString as BS
|
||||
import Data.ByteString.Base58 (bitcoinAlphabet, decodeBase58, encodeBase58)
|
||||
import Data.Char (chr)
|
||||
import qualified Data.ByteString.Char8 as BC
|
||||
import Data.Char (chr)
|
||||
import Data.HexString
|
||||
import qualified Data.Text as T
|
||||
import qualified Data.Text.Encoding as E
|
||||
|
@ -31,6 +31,7 @@ import Haskoin.Address (Address(..))
|
|||
import qualified Haskoin.Crypto.Hash as H
|
||||
import Haskoin.Crypto.Keys.Extended
|
||||
import ZcashHaskell.Types
|
||||
|
||||
-- ( AccountId
|
||||
-- , CoinType(..)
|
||||
-- , Scope(..)
|
||||
|
@ -44,7 +45,7 @@ import ZcashHaskell.Types
|
|||
-- , getTransparentPrefix
|
||||
-- , getValue
|
||||
-- )
|
||||
import ZcashHaskell.Utils( encodeBech32m, decodeBech32 )
|
||||
import ZcashHaskell.Utils (decodeBech32, encodeBech32m)
|
||||
|
||||
-- | Required for `TransparentReceiver` encoding and decoding
|
||||
sha256 :: BS.ByteString -> BS.ByteString
|
||||
|
@ -127,21 +128,29 @@ decodeTransparentAddress taddress = do
|
|||
189 ->
|
||||
Just $
|
||||
TransparentAddress MainNet $
|
||||
TransparentReceiver P2SH (fromRawBytes transparentReceiver)
|
||||
TransparentReceiver
|
||||
P2SH
|
||||
(fromRawBytes transparentReceiver)
|
||||
186 ->
|
||||
Just $
|
||||
TransparentAddress TestNet $
|
||||
TransparentReceiver P2SH (fromRawBytes transparentReceiver)
|
||||
TransparentReceiver
|
||||
P2SH
|
||||
(fromRawBytes transparentReceiver)
|
||||
184 ->
|
||||
Just $
|
||||
TransparentAddress MainNet $
|
||||
TransparentReceiver P2PKH (fromRawBytes transparentReceiver)
|
||||
TransparentReceiver
|
||||
P2PKH
|
||||
(fromRawBytes transparentReceiver)
|
||||
_ -> Nothing
|
||||
29 ->
|
||||
if sb == 37
|
||||
then Just $
|
||||
TransparentAddress TestNet $
|
||||
TransparentReceiver P2PKH (fromRawBytes transparentReceiver)
|
||||
TransparentReceiver
|
||||
P2PKH
|
||||
(fromRawBytes transparentReceiver)
|
||||
else Nothing
|
||||
_ -> Nothing
|
||||
|
||||
|
@ -180,7 +189,9 @@ decodeExchangeAddress ex = do
|
|||
if hr == tTest
|
||||
then Just $
|
||||
ExchangeAddress TestNet $
|
||||
TransparentReceiver P2PKH (fromRawBytes transparentReceiver)
|
||||
TransparentReceiver
|
||||
P2PKH
|
||||
(fromRawBytes transparentReceiver)
|
||||
else Nothing
|
||||
else Nothing
|
||||
else Nothing
|
|
@ -638,11 +638,60 @@ data DecodedNote = DecodedNote
|
|||
, a_recipient :: !BS.ByteString -- ^ The recipient Orchard receiver.
|
||||
, a_memo :: !BS.ByteString -- ^ The decoded shielded memo field.
|
||||
, a_nullifier :: !HexString -- ^ The calculated nullifier
|
||||
, a_rho :: !BS.ByteString
|
||||
, a_rseed :: !Rseed
|
||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||
deriving anyclass (Data.Structured.Show)
|
||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct DecodedNote
|
||||
|
||||
data Rseed = Rseed
|
||||
{ rs_kind :: !Word8
|
||||
, rs_bytes :: !BS.ByteString
|
||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||
deriving anyclass (Data.Structured.Show)
|
||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct Rseed
|
||||
|
||||
data TransparentTxSpend = TransparentTxSpend
|
||||
{ ts_sk :: !BS.ByteString
|
||||
, ts_utxo :: !RawOutPoint
|
||||
, ts_coin :: !RawTxOut
|
||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||
deriving anyclass (Data.Structured.Show)
|
||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct TransparentTxSpend
|
||||
|
||||
data SaplingTxSpend = SaplingTxSpend
|
||||
{ ss_sk :: !BS.ByteString
|
||||
, ss_note :: !DecodedNote
|
||||
, ss_iw :: !BS.ByteString
|
||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||
deriving anyclass (Data.Structured.Show)
|
||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct SaplingTxSpend
|
||||
|
||||
data OrchardTxSpend = OrchardTxSpend
|
||||
{ ss_sk :: !BS.ByteString
|
||||
, ss_note :: !DecodedNote
|
||||
, ss_iw :: !BS.ByteString
|
||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||
deriving anyclass (Data.Structured.Show)
|
||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OrchardTxSpend
|
||||
|
||||
data OutgoingNote = OutGoingNote
|
||||
{ on_kind :: !Word8
|
||||
, on_key :: !BS.ByteString
|
||||
, on_recipient :: !BS.ByteString
|
||||
, on_amt :: !Word64
|
||||
, on_memo :: !BS.ByteString
|
||||
, on_chg :: !Bool
|
||||
} deriving stock (Eq, Prelude.Show, GHC.Generic)
|
||||
deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo)
|
||||
deriving anyclass (Data.Structured.Show)
|
||||
deriving (BorshSize, ToBorsh, FromBorsh) via AsStruct OutgoingNote
|
||||
|
||||
-- * Classes
|
||||
-- | Class to represent types with a bytestring representation
|
||||
class ToBytes a where
|
||||
|
|
|
@ -5,7 +5,7 @@ cabal-version: 3.0
|
|||
-- see: https://github.com/sol/hpack
|
||||
|
||||
name: zcash-haskell
|
||||
version: 0.6.0.0
|
||||
version: 0.6.1.0
|
||||
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>
|
||||
category: Blockchain
|
||||
|
|
Loading…
Reference in a new issue