Compare commits
No commits in common. "173445612d3f7e86324e2c440102aa2b3df253c8" and "ebfac8438f8daacb8156c40b8694dcc7412c34d9" have entirely different histories.
173445612d
...
ebfac8438f
7 changed files with 5 additions and 186 deletions
|
@ -14,15 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
`decodeExchangeAddress` a function to obtaina a TransparentAddress object from an ExchangeAddress in HRF
|
`decodeExchangeAddress` a function to obtaina a TransparentAddress object from an ExchangeAddress in HRF
|
||||||
- Added new type ExchangeAddress
|
- Added new type ExchangeAddress
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Orchard note nullifier calculation
|
|
||||||
|
|
||||||
## [0.5.5.2]
|
## [0.5.5.2]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Added function to encode a Sappling Address in Human Readable Format Using a SaplingReceiver
|
- Added unction to encode a Sappling Address in Human Readable Format Using a SaplingReceiver
|
||||||
`encodeSaplingAddress` a zcash sapling address is returned or Nothing if the function fails
|
`encodeSaplingAddress` a zcash sapling address is returned or Nothing if the function fails
|
||||||
- Added decoding and encoding test
|
- Added decoding and encoding test
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,6 @@ use orchard::{
|
||||||
note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment},
|
note::{Nullifier, TransmittedNoteCiphertext, ExtractedNoteCommitment},
|
||||||
note_encryption::OrchardDomain,
|
note_encryption::OrchardDomain,
|
||||||
primitives::redpallas::{VerificationKey, SpendAuth, Signature},
|
primitives::redpallas::{VerificationKey, SpendAuth, Signature},
|
||||||
tree::MerkleHashOrchard,
|
|
||||||
value::ValueCommitment
|
value::ValueCommitment
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -908,7 +907,7 @@ pub extern "C" fn rust_wrapper_orchard_note_decrypt_sk(
|
||||||
let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action);
|
let result = zcash_note_encryption::try_note_decryption(&domain, &pivk, &action);
|
||||||
match result {
|
match result {
|
||||||
Some((n, r, m)) => {
|
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 hn = Hnote {note: n.value().inner(), recipient: r.to_raw_address_bytes().to_vec(), memo: m.to_vec(), nullifier: vec![0]};
|
||||||
marshall_to_haskell_var(&hn, out, out_len, RW);
|
marshall_to_haskell_var(&hn, out, out_len, RW);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -1259,95 +1258,6 @@ pub extern "C" fn rust_wrapper_read_sapling_position(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn rust_wrapper_read_orchard_commitment_tree(
|
|
||||||
tree: *const u8,
|
|
||||||
tree_len: usize,
|
|
||||||
node: *const u8,
|
|
||||||
node_len: usize,
|
|
||||||
out: *mut u8,
|
|
||||||
out_len: &mut usize
|
|
||||||
){
|
|
||||||
let tree_in: Vec<u8> = marshall_from_haskell_var(tree, tree_len, RW);
|
|
||||||
let tree_reader = Cursor::new(tree_in);
|
|
||||||
let ct = read_commitment_tree::<MerkleHashOrchard, Cursor<Vec<u8>>, 32>(tree_reader);
|
|
||||||
match ct {
|
|
||||||
Ok(mut comm_tree) => {
|
|
||||||
let node_in: Vec<u8> = marshall_from_haskell_var(node, node_len, RW);
|
|
||||||
let orchard_note_comm = ExtractedNoteCommitment::from_bytes(&to_array(node_in));
|
|
||||||
if orchard_note_comm.is_some().into() {
|
|
||||||
let n = MerkleHashOrchard::from_cmx(&orchard_note_comm.unwrap());
|
|
||||||
comm_tree.append(n);
|
|
||||||
let mut out_bytes: Vec<u8> = Vec::new();
|
|
||||||
let result = write_commitment_tree(&comm_tree, &mut out_bytes );
|
|
||||||
match result {
|
|
||||||
Ok(()) => {
|
|
||||||
let h = Hhex { bytes: out_bytes};
|
|
||||||
marshall_to_haskell_var(&h, out, out_len, RW);
|
|
||||||
},
|
|
||||||
Err(_e) => {
|
|
||||||
let h0 = Hhex { bytes: vec![0]};
|
|
||||||
marshall_to_haskell_var(&h0, out, out_len, RW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let h0 = Hhex { bytes: vec![0]};
|
|
||||||
marshall_to_haskell_var(&h0, out, out_len, RW);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(_e) => {
|
|
||||||
let h0 = Hhex { bytes: vec![0]};
|
|
||||||
marshall_to_haskell_var(&h0, out, out_len, RW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn rust_wrapper_read_orchard_witness(
|
|
||||||
tree: *const u8,
|
|
||||||
tree_len: usize,
|
|
||||||
out: *mut u8,
|
|
||||||
out_len: &mut usize
|
|
||||||
){
|
|
||||||
let tree_in: Vec<u8> = marshall_from_haskell_var(tree, tree_len, RW);
|
|
||||||
let tree_reader = Cursor::new(tree_in);
|
|
||||||
let ct: CommitmentTree<MerkleHashOrchard, 32> = read_commitment_tree(tree_reader).unwrap();
|
|
||||||
let inc_wit = IncrementalWitness::from_tree(ct);
|
|
||||||
let mut out_bytes: Vec<u8> = Vec::new();
|
|
||||||
let result = write_incremental_witness(&inc_wit, &mut out_bytes);
|
|
||||||
match result {
|
|
||||||
Ok(()) => {
|
|
||||||
let h = Hhex { bytes: out_bytes};
|
|
||||||
marshall_to_haskell_var(&h, out, out_len, RW);
|
|
||||||
},
|
|
||||||
Err(_e) => {
|
|
||||||
let h0 = Hhex { bytes: vec![0]};
|
|
||||||
marshall_to_haskell_var(&h0, out, out_len, RW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
pub extern "C" fn rust_wrapper_read_orchard_position(
|
|
||||||
wit: *const u8,
|
|
||||||
wit_len: usize,
|
|
||||||
) -> u64 {
|
|
||||||
let wit_in: Vec<u8> = marshall_from_haskell_var(wit, wit_len, RW);
|
|
||||||
let wit_reader = Cursor::new(wit_in);
|
|
||||||
let iw: IncrementalWitness<MerkleHashOrchard, 32> = read_incremental_witness(wit_reader).unwrap();
|
|
||||||
let path = iw.path();
|
|
||||||
match path {
|
|
||||||
Some(p) => {
|
|
||||||
let pos = p.position();
|
|
||||||
return u64::from(pos);
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn rust_wrapper_decode_sapling_address(
|
pub extern "C" fn rust_wrapper_decode_sapling_address(
|
||||||
sapling: *const u8,
|
sapling: *const u8,
|
||||||
|
@ -1393,3 +1303,4 @@ pub extern "C" fn rust_wrapper_decode_sapling_address(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -239,23 +239,3 @@ import ZcashHaskell.Types
|
||||||
-> `()'
|
-> `()'
|
||||||
#}
|
#}
|
||||||
|
|
||||||
{# fun unsafe rust_wrapper_read_orchard_commitment_tree as rustWrapperReadOrchardCommitmentTree
|
|
||||||
{ toBorshVar* `BS.ByteString'&
|
|
||||||
, toBorshVar* `BS.ByteString'&
|
|
||||||
, getVarBuffer `Buffer HexString'&
|
|
||||||
}
|
|
||||||
-> `()'
|
|
||||||
#}
|
|
||||||
|
|
||||||
{# fun unsafe rust_wrapper_read_orchard_witness as rustWrapperReadOrchardWitness
|
|
||||||
{ toBorshVar* `BS.ByteString'&
|
|
||||||
, getVarBuffer `Buffer HexString'&
|
|
||||||
}
|
|
||||||
-> `()'
|
|
||||||
#}
|
|
||||||
|
|
||||||
{# fun pure unsafe rust_wrapper_read_orchard_position as rustWrapperReadOrchardPosition
|
|
||||||
{ toBorshVar* `BS.ByteString'&
|
|
||||||
}
|
|
||||||
-> `Word64'
|
|
||||||
#}
|
|
||||||
|
|
|
@ -23,15 +23,12 @@ import C.Zcash
|
||||||
, rustWrapperOrchardCheck
|
, rustWrapperOrchardCheck
|
||||||
, rustWrapperOrchardNoteDecode
|
, rustWrapperOrchardNoteDecode
|
||||||
, rustWrapperOrchardNoteDecodeSK
|
, rustWrapperOrchardNoteDecodeSK
|
||||||
, rustWrapperReadOrchardCommitmentTree
|
|
||||||
, rustWrapperReadOrchardPosition
|
|
||||||
, rustWrapperReadOrchardWitness
|
|
||||||
, rustWrapperUADecode
|
, rustWrapperUADecode
|
||||||
, rustWrapperUfvkDecode
|
, rustWrapperUfvkDecode
|
||||||
)
|
)
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Char8 as C
|
import qualified Data.ByteString.Char8 as C
|
||||||
import Data.HexString (HexString(..), fromRawBytes, toBytes)
|
import Data.HexString (fromRawBytes, toBytes)
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
import Data.Word
|
import Data.Word
|
||||||
|
@ -187,35 +184,3 @@ decryptOrchardActionSK sk scope oa =
|
||||||
decodedAction =
|
decodedAction =
|
||||||
withPureBorshVarBuffer $
|
withPureBorshVarBuffer $
|
||||||
rustWrapperOrchardNoteDecodeSK (getBytes sk) oa (scope == External)
|
rustWrapperOrchardNoteDecodeSK (getBytes sk) oa (scope == External)
|
||||||
|
|
||||||
-- | Update a Orchard commitment tree
|
|
||||||
updateOrchardCommitmentTree ::
|
|
||||||
OrchardCommitmentTree -- ^ the base tree
|
|
||||||
-> HexString -- ^ the new note commitment
|
|
||||||
-> Maybe OrchardCommitmentTree
|
|
||||||
updateOrchardCommitmentTree tree cmx =
|
|
||||||
if BS.length (hexBytes updatedTree) > 1
|
|
||||||
then Just $ OrchardCommitmentTree updatedTree
|
|
||||||
else Nothing
|
|
||||||
where
|
|
||||||
updatedTree =
|
|
||||||
withPureBorshVarBuffer $
|
|
||||||
rustWrapperReadOrchardCommitmentTree
|
|
||||||
(hexBytes $ orchTree tree)
|
|
||||||
(hexBytes cmx)
|
|
||||||
|
|
||||||
-- | Get the Orchard incremental witness from a commitment tree
|
|
||||||
getOrchardWitness :: OrchardCommitmentTree -> Maybe OrchardWitness
|
|
||||||
getOrchardWitness tree =
|
|
||||||
if BS.length (hexBytes wit) > 1
|
|
||||||
then Just $ OrchardWitness wit
|
|
||||||
else Nothing
|
|
||||||
where
|
|
||||||
wit =
|
|
||||||
withPureBorshVarBuffer $
|
|
||||||
rustWrapperReadOrchardWitness (hexBytes $ orchTree tree)
|
|
||||||
|
|
||||||
-- | Get the Sapling note position from a witness
|
|
||||||
getOrchardNotePosition :: OrchardWitness -> Integer
|
|
||||||
getOrchardNotePosition =
|
|
||||||
fromIntegral . rustWrapperReadOrchardPosition . hexBytes . orchWit
|
|
||||||
|
|
|
@ -623,16 +623,6 @@ instance FromJSON OrchardAction where
|
||||||
a <- obj .: "spendAuthSig"
|
a <- obj .: "spendAuthSig"
|
||||||
pure $ OrchardAction n r c ephKey encText outText cval a
|
pure $ OrchardAction n r c ephKey encText outText cval a
|
||||||
|
|
||||||
-- | Type for a Orchard note commitment tree
|
|
||||||
newtype OrchardCommitmentTree = OrchardCommitmentTree
|
|
||||||
{ orchTree :: HexString
|
|
||||||
} deriving (Eq, Prelude.Show, Read)
|
|
||||||
|
|
||||||
-- | Type for a Sapling incremental witness
|
|
||||||
newtype OrchardWitness = OrchardWitness
|
|
||||||
{ orchWit :: HexString
|
|
||||||
} deriving (Eq, Prelude.Show, Read)
|
|
||||||
|
|
||||||
-- | 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_.
|
||||||
|
|
23
test/Spec.hs
23
test/Spec.hs
|
@ -68,9 +68,7 @@ import ZcashHaskell.Types
|
||||||
, CoinType(..)
|
, CoinType(..)
|
||||||
, DecodedNote(..)
|
, DecodedNote(..)
|
||||||
, OrchardAction(..)
|
, OrchardAction(..)
|
||||||
, OrchardCommitmentTree(..)
|
|
||||||
, OrchardSpendingKey(..)
|
, OrchardSpendingKey(..)
|
||||||
, OrchardWitness(..)
|
|
||||||
, Phrase(..)
|
, Phrase(..)
|
||||||
, RawData(..)
|
, RawData(..)
|
||||||
, RawOutPoint(..)
|
, RawOutPoint(..)
|
||||||
|
@ -882,27 +880,6 @@ main = do
|
||||||
getSaplingNotePosition <$>
|
getSaplingNotePosition <$>
|
||||||
(getSaplingWitness =<< updateSaplingCommitmentTree tree cmu1)
|
(getSaplingWitness =<< updateSaplingCommitmentTree tree cmu1)
|
||||||
p `shouldBe` Just 129405
|
p `shouldBe` Just 129405
|
||||||
describe "Orchard commitment trees" $ do
|
|
||||||
let tree =
|
|
||||||
OrchardCommitmentTree $
|
|
||||||
hexString
|
|
||||||
"01d5c803729654208f33d33dc68ef539ea098abc5aec215ae67c4d8aa10a14e11d01bb83047c72eb4f71813d00dee37082169546df2d7097bf7fd187ef6a93063b281f015e710ed46b53b48b12733652e150f9dcbc7e7b571cf64f294cf903864c78882f01cac32bc901f501f714a028f7ebe44c1dd8b42661be1c96730066a6fa6ede653600000000000001746e6bc066a10e7f80a9ff8993dcb25c819edd64f2ca10ac248ef7848d41450500011e6191f91b3fceb62dc881a156e1b9d2e88e09dca25093cf9c4936c8869fb41a013bf8b923e4187754e85175748d9cce4824a6787e4258977b5bfe1ba59012c032000001f3bbdc62260c4fca5c84bf3487246d4542da48eeeec8ec40c1029b6908eef83c00000000000000000000000000000000"
|
|
||||||
let cmx =
|
|
||||||
hexString
|
|
||||||
"d5c803729654208f33d33dc68ef539ea098abc5aec215ae67c4d8aa10a14e11d"
|
|
||||||
it "Commitment tree is updated correctly" $ do
|
|
||||||
let t1 = updateOrchardCommitmentTree tree cmx
|
|
||||||
t1 `shouldNotBe` Nothing
|
|
||||||
it "Incremental witness is generated" $ do
|
|
||||||
let t1 = updateOrchardCommitmentTree tree cmx
|
|
||||||
case t1 of
|
|
||||||
Nothing -> assertFailure "Failed to append node to tree"
|
|
||||||
Just t -> getOrchardWitness t `shouldNotBe` Nothing
|
|
||||||
it "Position of note is obtained" $ do
|
|
||||||
let p =
|
|
||||||
getOrchardNotePosition <$>
|
|
||||||
(getOrchardWitness =<< updateOrchardCommitmentTree tree cmx)
|
|
||||||
p `shouldBe` Just 39432
|
|
||||||
describe "Extract Sapling Address - UA Valid" $ do
|
describe "Extract Sapling Address - UA Valid" $ do
|
||||||
let sr =
|
let sr =
|
||||||
getSaplingFromUA
|
getSaplingFromUA
|
||||||
|
|
|
@ -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.5.3
|
version: 0.5.5.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
|
||||||
|
|
Loading…
Reference in a new issue