From e6d16267ee2000c4ef70087fd19db746e8e0ae95 Mon Sep 17 00:00:00 2001 From: "Rene V. Vergara" Date: Wed, 17 Apr 2024 20:36:04 -0400 Subject: [PATCH 1/3] rvv040 - Functions to create and decode an ExchangeAddress added New DataType ExchangeAddress added. --- src/ZcashHaskell/Sapling.hs | 19 --------- src/ZcashHaskell/Transparent.hs | 70 ++++++++++++++++++++++++++------- src/ZcashHaskell/Types.hs | 6 +++ test/Spec.hs | 16 ++++++++ 4 files changed, 78 insertions(+), 33 deletions(-) diff --git a/src/ZcashHaskell/Sapling.hs b/src/ZcashHaskell/Sapling.hs index fb62a7a..6e3c7b0 100644 --- a/src/ZcashHaskell/Sapling.hs +++ b/src/ZcashHaskell/Sapling.hs @@ -43,25 +43,6 @@ import Foreign.Rust.Marshall.Variable , withPureBorshVarBuffer ) import ZcashHaskell.Types ---import ZcashHaskell.Types --- ( AccountId --- , CoinType --- , DecodedNote(..) --- , RawData(..) --- , RawTxResponse(..) --- , SaplingAddress(..) --- , SaplingCommitmentTree(..) --- , SaplingReceiver(..) --- , SaplingSpendingKey(..) --- , SaplingWitness(..) --- , Scope(..) --- , Seed(..) --- , ShieldedOutput(..) --- , ToBytes(..) --- , ZcashNet(..) --- , decodeHexText --- , getValue --- ) import ZcashHaskell.Utils (decodeBech32, encodeBech32, encodeBech32m) -- | Check if given bytesting is a valid encoded shielded address diff --git a/src/ZcashHaskell/Transparent.hs b/src/ZcashHaskell/Transparent.hs index 366dfe4..a76be58 100644 --- a/src/ZcashHaskell/Transparent.hs +++ b/src/ZcashHaskell/Transparent.hs @@ -22,7 +22,8 @@ import qualified Data.ByteArray as BA import qualified Data.ByteString as BS import Data.ByteString.Base58 (bitcoinAlphabet, decodeBase58, encodeBase58) import Data.Char (chr) -import Data.HexString +import qualified Data.ByteString.Char8 as BC +import Data.HexString import qualified Data.Text as T import qualified Data.Text.Encoding as E import Data.Word @@ -30,19 +31,20 @@ import Haskoin.Address (Address(..)) import qualified Haskoin.Crypto.Hash as H import Haskoin.Crypto.Keys.Extended import ZcashHaskell.Types - ( AccountId - , CoinType(..) - , Scope(..) - , Seed(..) - , ToBytes(..) - , TransparentAddress(..) - , TransparentReceiver(..) - , TransparentSpendingKey(..) - , TransparentType(..) - , ZcashNet(..) - , getTransparentPrefix - , getValue - ) +-- ( AccountId +-- , CoinType(..) +-- , Scope(..) +-- , Seed(..) +-- , ToBytes(..) +-- , TransparentAddress(..) +-- , TransparentReceiver(..) +-- , TransparentSpendingKey(..) +-- , TransparentType(..) +-- , ZcashNet(..) +-- , getTransparentPrefix +-- , getValue +-- ) +import ZcashHaskell.Utils( encodeBech32m, decodeBech32 ) -- | Required for `TransparentReceiver` encoding and decoding sha256 :: BS.ByteString -> BS.ByteString @@ -142,3 +144,43 @@ decodeTransparentAddress taddress = do TransparentReceiver P2PKH (fromRawBytes transparentReceiver) else Nothing _ -> Nothing + +-- | Encode an Exchange Addresss into HRF from TransparentReceiver +encodeExchangeAddress:: ZcashNet -> TransparentReceiver -> Maybe T.Text +encodeExchangeAddress net tr = do + case (tr_type tr) of + P2PKH -> do + case net of + MainNet -> do + let vhash = encodeBech32m (BC.pack "tex") (toBytes (tr_bytes tr)) + Just vhash + TestNet -> do + let vhash = encodeBech32m (BC.pack "textest") (toBytes (tr_bytes tr)) + Just vhash + _ -> Nothing + +-- | Decode an Exchange Address into a TransparentAddress +decodeExchangeAddress:: T.Text-> Maybe TransparentAddress +decodeExchangeAddress ex = do + if (T.length ex ) > 1 + then do + let rawd = decodeBech32 (E.encodeUtf8 ex) + let tMain = BS.unpack (BC.pack "tex") + let tTest = BS.unpack (BC.pack "textest") + let tFail = BS.unpack (BC.pack "fail") + let hr = BS.unpack (hrp rawd) + if hr /= tFail + then do + let transparentReceiver = bytes rawd + if hr == tMain + then Just $ + TransparentAddress MainNet $ + TransparentReceiver P2PKH (fromRawBytes transparentReceiver) + else do + if hr == tTest + then Just $ + TransparentAddress TestNet $ + TransparentReceiver P2PKH (fromRawBytes transparentReceiver) + else Nothing + else Nothing + else Nothing \ No newline at end of file diff --git a/src/ZcashHaskell/Types.hs b/src/ZcashHaskell/Types.hs index c6d9c34..54da7aa 100644 --- a/src/ZcashHaskell/Types.hs +++ b/src/ZcashHaskell/Types.hs @@ -434,6 +434,12 @@ data TransparentAddress = TransparentAddress , ta_receiver :: !TransparentReceiver } deriving (Eq, Prelude.Show, Read) +-- | Type to represent a TEX Zcash addresses +data ExchangeAddress = ExchangeAddress + { ex_network :: !ZcashNet + , ex_address :: !TransparentReceiver + } deriving (Eq, Prelude.Show, Read) + -- | Wrapper types for transparent elements data RawTxIn = RawTxIn { rti_outpoint :: !RawOutPoint diff --git a/test/Spec.hs b/test/Spec.hs index 5931df8..245b824 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -1068,6 +1068,22 @@ main = do p dn `shouldNotBe` Nothing + describe "Generate an ExchangeAddress (MainNet) from transparent address" $ do + let ta = decodeTransparentAddress "t1dMjvesbzdG41xgKaGU3HgwYJwSgbCK54e" + it "Try to generate valid ExchangeAddress from Transparent Address" $ do + case ta of + Nothing -> assertFailure "Failed to decode transparent address" + Just t -> do + case (tr_type (ta_receiver t) ) of + P2SH -> assertFailure "P2SH not supported for ExchengeAddress generation" + P2PKH -> do + let exch = encodeExchangeAddress (ta_network t) (ta_receiver t) + case exch of + Nothing -> assertFailure "Failed to encode Exchange address" + Just addr -> do + let tadr = decodeExchangeAddress addr + tadr `shouldNotBe` Nothing + -- | Properties prop_PhraseLength :: Property prop_PhraseLength = From 1b2c6dce2486b656f2fa7a6324d180d1d74e8c77 Mon Sep 17 00:00:00 2001 From: "Rene V. Vergara" Date: Wed, 17 Apr 2024 20:51:12 -0400 Subject: [PATCH 2/3] rvv040 - Update CHANGE.LOG file --- CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf9c65..42449e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ 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.5.5.3] + +### Added + +- Added unction to generate an ExchangeAddress in Human Readable Format Using a TransparentAddress in HRF + `encodeExchangeAddress` a function to create a ExchangeAddress in HRF + `decodeExchangeAddress` a function to obtaina a TransparentAddress object from an ExchangeAddress in HRF +- Added new type ExchangeAddress + ## [0.5.5.2] ### Added @@ -13,8 +22,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `encodeSaplingAddress` a zcash sapling address is returned or Nothing if the function fails - Added decoding and encoding test - - ## [0.5.5.1] ### Added From ebfac8438f8daacb8156c40b8694dcc7412c34d9 Mon Sep 17 00:00:00 2001 From: "Rene V. Vergara" Date: Thu, 18 Apr 2024 08:30:14 -0400 Subject: [PATCH 3/3] rvv040 - decodeExchangeAddress modified to return an ExcahngeAddress object --- src/ZcashHaskell/Transparent.hs | 8 ++++---- test/Spec.hs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ZcashHaskell/Transparent.hs b/src/ZcashHaskell/Transparent.hs index a76be58..4bdc46d 100644 --- a/src/ZcashHaskell/Transparent.hs +++ b/src/ZcashHaskell/Transparent.hs @@ -159,8 +159,8 @@ encodeExchangeAddress net tr = do Just vhash _ -> Nothing --- | Decode an Exchange Address into a TransparentAddress -decodeExchangeAddress:: T.Text-> Maybe TransparentAddress +-- | Decode an Exchange Address into a ExchangeAddress +decodeExchangeAddress:: T.Text-> Maybe ExchangeAddress decodeExchangeAddress ex = do if (T.length ex ) > 1 then do @@ -174,12 +174,12 @@ decodeExchangeAddress ex = do let transparentReceiver = bytes rawd if hr == tMain then Just $ - TransparentAddress MainNet $ + ExchangeAddress MainNet $ TransparentReceiver P2PKH (fromRawBytes transparentReceiver) else do if hr == tTest then Just $ - TransparentAddress TestNet $ + ExchangeAddress TestNet $ TransparentReceiver P2PKH (fromRawBytes transparentReceiver) else Nothing else Nothing diff --git a/test/Spec.hs b/test/Spec.hs index 245b824..7c868e7 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -1081,8 +1081,8 @@ main = do case exch of Nothing -> assertFailure "Failed to encode Exchange address" Just addr -> do - let tadr = decodeExchangeAddress addr - tadr `shouldNotBe` Nothing + let eadr = decodeExchangeAddress addr + eadr `shouldNotBe` Nothing -- | Properties prop_PhraseLength :: Property