Fix Sapling spend parsing #69
5 changed files with 85 additions and 33 deletions
|
@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [0.5.5.3]
|
## [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
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Orchard note nullifier calculation
|
- Orchard note nullifier calculation
|
||||||
|
|
|
@ -43,25 +43,6 @@ import Foreign.Rust.Marshall.Variable
|
||||||
, withPureBorshVarBuffer
|
, withPureBorshVarBuffer
|
||||||
)
|
)
|
||||||
import ZcashHaskell.Types
|
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)
|
import ZcashHaskell.Utils (decodeBech32, encodeBech32, encodeBech32m)
|
||||||
|
|
||||||
-- | Check if given bytesting is a valid encoded shielded address
|
-- | Check if given bytesting is a valid encoded shielded address
|
||||||
|
|
|
@ -22,6 +22,7 @@ import qualified Data.ByteArray as BA
|
||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import Data.ByteString.Base58 (bitcoinAlphabet, decodeBase58, encodeBase58)
|
import Data.ByteString.Base58 (bitcoinAlphabet, decodeBase58, encodeBase58)
|
||||||
import Data.Char (chr)
|
import Data.Char (chr)
|
||||||
|
import qualified Data.ByteString.Char8 as BC
|
||||||
import Data.HexString
|
import Data.HexString
|
||||||
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
|
||||||
|
@ -30,19 +31,20 @@ import Haskoin.Address (Address(..))
|
||||||
import qualified Haskoin.Crypto.Hash as H
|
import qualified Haskoin.Crypto.Hash as H
|
||||||
import Haskoin.Crypto.Keys.Extended
|
import Haskoin.Crypto.Keys.Extended
|
||||||
import ZcashHaskell.Types
|
import ZcashHaskell.Types
|
||||||
( AccountId
|
-- ( AccountId
|
||||||
, CoinType(..)
|
-- , CoinType(..)
|
||||||
, Scope(..)
|
-- , Scope(..)
|
||||||
, Seed(..)
|
-- , Seed(..)
|
||||||
, ToBytes(..)
|
-- , ToBytes(..)
|
||||||
, TransparentAddress(..)
|
-- , TransparentAddress(..)
|
||||||
, TransparentReceiver(..)
|
-- , TransparentReceiver(..)
|
||||||
, TransparentSpendingKey(..)
|
-- , TransparentSpendingKey(..)
|
||||||
, TransparentType(..)
|
-- , TransparentType(..)
|
||||||
, ZcashNet(..)
|
-- , ZcashNet(..)
|
||||||
, getTransparentPrefix
|
-- , getTransparentPrefix
|
||||||
, getValue
|
-- , getValue
|
||||||
)
|
-- )
|
||||||
|
import ZcashHaskell.Utils( encodeBech32m, decodeBech32 )
|
||||||
|
|
||||||
-- | Required for `TransparentReceiver` encoding and decoding
|
-- | Required for `TransparentReceiver` encoding and decoding
|
||||||
sha256 :: BS.ByteString -> BS.ByteString
|
sha256 :: BS.ByteString -> BS.ByteString
|
||||||
|
@ -142,3 +144,43 @@ decodeTransparentAddress taddress = do
|
||||||
TransparentReceiver P2PKH (fromRawBytes transparentReceiver)
|
TransparentReceiver P2PKH (fromRawBytes transparentReceiver)
|
||||||
else Nothing
|
else Nothing
|
||||||
_ -> 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 ExchangeAddress
|
||||||
|
decodeExchangeAddress:: T.Text-> Maybe ExchangeAddress
|
||||||
|
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 $
|
||||||
|
ExchangeAddress MainNet $
|
||||||
|
TransparentReceiver P2PKH (fromRawBytes transparentReceiver)
|
||||||
|
else do
|
||||||
|
if hr == tTest
|
||||||
|
then Just $
|
||||||
|
ExchangeAddress TestNet $
|
||||||
|
TransparentReceiver P2PKH (fromRawBytes transparentReceiver)
|
||||||
|
else Nothing
|
||||||
|
else Nothing
|
||||||
|
else Nothing
|
|
@ -434,6 +434,12 @@ data TransparentAddress = TransparentAddress
|
||||||
, ta_receiver :: !TransparentReceiver
|
, ta_receiver :: !TransparentReceiver
|
||||||
} deriving (Eq, Prelude.Show, Read)
|
} 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
|
-- | Wrapper types for transparent elements
|
||||||
data RawTxIn = RawTxIn
|
data RawTxIn = RawTxIn
|
||||||
{ rti_outpoint :: !RawOutPoint
|
{ rti_outpoint :: !RawOutPoint
|
||||||
|
|
16
test/Spec.hs
16
test/Spec.hs
|
@ -1115,6 +1115,22 @@ main = do
|
||||||
p
|
p
|
||||||
dn `shouldNotBe` Nothing
|
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 eadr = decodeExchangeAddress addr
|
||||||
|
eadr `shouldNotBe` Nothing
|
||||||
|
|
||||||
-- | Properties
|
-- | Properties
|
||||||
prop_PhraseLength :: Property
|
prop_PhraseLength :: Property
|
||||||
prop_PhraseLength =
|
prop_PhraseLength =
|
||||||
|
|
Loading…
Reference in a new issue