From e6d16267ee2000c4ef70087fd19db746e8e0ae95 Mon Sep 17 00:00:00 2001 From: "Rene V. Vergara" Date: Wed, 17 Apr 2024 20:36:04 -0400 Subject: [PATCH] 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 =