Address conversion to string now defined for all inputs

This commit is contained in:
Jean-Pierre Rupp 2019-04-12 14:25:21 +01:00
parent 1d1373f06f
commit a1c2ca9c55
10 changed files with 38 additions and 37 deletions

3
.hindent.yaml Normal file
View File

@ -0,0 +1,3 @@
indent-size: 4
line-length: 80
force-trailing-newline: true

View File

@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## 0.9.0
### Changed
- Address conversion to string now defined for all inputs.
## 0.8.4 ## 0.8.4
### Added ### Added
- Add reward computation to block functions. - Add reward computation to block functions.

View File

@ -1,5 +1,5 @@
name: haskoin-core name: haskoin-core
version: 0.8.4 version: 0.9.0
synopsis: Bitcoin & Bitcoin Cash library for Haskell synopsis: Bitcoin & Bitcoin Cash library for Haskell
description: 'Haskoin Core is a complete Bitcoin and Bitcoin Cash library of functions and data types for Haskell developers.' description: 'Haskoin Core is a complete Bitcoin and Bitcoin Cash library of functions and data types for Haskell developers.'
category: Bitcoin, Finance, Network category: Bitcoin, Finance, Network

View File

@ -127,7 +127,7 @@ base58put net (ScriptAddress h) = do
base58put _ _ = error "Cannot serialize this address as Base58" base58put _ _ = error "Cannot serialize this address as Base58"
addrToJSON :: Network -> Address -> Value addrToJSON :: Network -> Address -> Value
addrToJSON net = String . addrToString net addrToJSON net a = toJSON (addrToString net a)
-- | JSON parsing for Bitcoin addresses. Works with 'Base58', 'CashAddr' and -- | JSON parsing for Bitcoin addresses. Works with 'Base58', 'CashAddr' and
-- 'Bech32'. -- 'Bech32'.
@ -140,29 +140,23 @@ addrFromJSON net =
-- | Convert address to human-readable string. Uses 'Base58', 'Bech32', or -- | Convert address to human-readable string. Uses 'Base58', 'Bech32', or
-- 'CashAddr' depending on network. -- 'CashAddr' depending on network.
addrToString :: Network -> Address -> Text addrToString :: Network -> Address -> Maybe Text
addrToString net a@PubKeyAddress {getAddrHash160 = h} addrToString net a@PubKeyAddress {getAddrHash160 = h}
| isNothing (getCashAddrPrefix net) = | isNothing (getCashAddrPrefix net) =
encodeBase58Check $ runPut $ base58put net a Just . encodeBase58Check . runPut $ base58put net a
| otherwise = | otherwise =
fromMaybe (error "Colud not encode a CashAddr") $
cashAddrEncode net 0 (S.encode h) cashAddrEncode net 0 (S.encode h)
addrToString net a@ScriptAddress {getAddrHash160 = h} addrToString net a@ScriptAddress {getAddrHash160 = h}
| isNothing (getCashAddrPrefix net) = | isNothing (getCashAddrPrefix net) =
encodeBase58Check $ runPut $ base58put net a Just . encodeBase58Check . runPut $ base58put net a
| otherwise = | otherwise =
fromMaybe (error "Could not encode a CashAddr") $
cashAddrEncode net 1 (S.encode h) cashAddrEncode net 1 (S.encode h)
addrToString net WitnessPubKeyAddress {getAddrHash160 = h} = addrToString net WitnessPubKeyAddress {getAddrHash160 = h} = do
let mt = do hrp <- getBech32Prefix net
hrp <- getBech32Prefix net segwitEncode hrp 0 (B.unpack (S.encode h))
segwitEncode hrp 0 (B.unpack (S.encode h)) addrToString net WitnessScriptAddress {getAddrHash256 = h} = do
in fromMaybe (error "Could not encode a Bech32 address") mt hrp <- getBech32Prefix net
addrToString net WitnessScriptAddress {getAddrHash256 = h} = segwitEncode hrp 0 (B.unpack (S.encode h))
let mt = do
hrp <- getBech32Prefix net
segwitEncode hrp 0 (B.unpack (S.encode h))
in fromMaybe (error "Could not encode a Bech32 address") mt
-- | Parse 'Base58', 'Bech32' or 'CashAddr' address, depending on network. -- | Parse 'Base58', 'Bech32' or 'CashAddr' address, depending on network.
stringToAddr :: Network -> Text -> Maybe Address stringToAddr :: Network -> Text -> Maybe Address

View File

@ -44,79 +44,79 @@ spec = do
describe "cashaddr to base58 translation test vectors" $ do describe "cashaddr to base58 translation test vectors" $ do
it "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu" $ do it "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu" $ do
let addr = let addr =
addrToString bch <$> addrToString bch =<<
stringToAddr btc "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu" stringToAddr btc "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu"
addr `shouldBe` addr `shouldBe`
Just "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a" Just "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"
it "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR" $ do it "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR" $ do
let addr = let addr =
addrToString bch <$> addrToString bch =<<
stringToAddr btc "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR" stringToAddr btc "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR"
addr `shouldBe` addr `shouldBe`
Just "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy" Just "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"
it "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb" $ do it "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb" $ do
let addr = let addr =
addrToString bch <$> addrToString bch =<<
stringToAddr btc "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb" stringToAddr btc "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb"
addr `shouldBe` addr `shouldBe`
Just "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r" Just "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"
it "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC" $ do it "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC" $ do
let addr = let addr =
addrToString bch <$> addrToString bch =<<
stringToAddr btc "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC" stringToAddr btc "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC"
addr `shouldBe` addr `shouldBe`
Just "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq" Just "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"
it "3LDsS579y7sruadqu11beEJoTjdFiFCdX4" $ do it "3LDsS579y7sruadqu11beEJoTjdFiFCdX4" $ do
let addr = let addr =
addrToString bch <$> addrToString bch =<<
stringToAddr btc "3LDsS579y7sruadqu11beEJoTjdFiFCdX4" stringToAddr btc "3LDsS579y7sruadqu11beEJoTjdFiFCdX4"
addr `shouldBe` addr `shouldBe`
Just "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e" Just "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"
it "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw" $ do it "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw" $ do
let addr = let addr =
addrToString bch <$> addrToString bch =<<
stringToAddr btc "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw" stringToAddr btc "31nwvkZwyPdgzjBJZXfDmSWsC4ZLKpYyUw"
addr `shouldBe` addr `shouldBe`
Just "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37" Just "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"
describe "base58 to cashaddr translation test vectors" $ do describe "base58 to cashaddr translation test vectors" $ do
it "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a" $ do it "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a" $ do
let addr = let addr =
addrToString btc <$> addrToString btc =<<
stringToAddr stringToAddr
bch bch
"bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a" "bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a"
addr `shouldBe` Just "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu" addr `shouldBe` Just "1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu"
it "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy" $ do it "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy" $ do
let addr = let addr =
addrToString btc <$> addrToString btc =<<
stringToAddr stringToAddr
bch bch
"bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy" "bitcoincash:qr95sy3j9xwd2ap32xkykttr4cvcu7as4y0qverfuy"
addr `shouldBe` Just "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR" addr `shouldBe` Just "1KXrWXciRDZUpQwQmuM1DbwsKDLYAYsVLR"
it "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r" $ do it "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r" $ do
let addr = let addr =
addrToString btc <$> addrToString btc =<<
stringToAddr stringToAddr
bch bch
"bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r" "bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r"
addr `shouldBe` Just "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb" addr `shouldBe` Just "16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb"
it "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq" $ do it "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq" $ do
let addr = let addr =
addrToString btc <$> addrToString btc =<<
stringToAddr stringToAddr
bch bch
"bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq" "bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq"
addr `shouldBe` Just "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC" addr `shouldBe` Just "3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC"
it "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e" $ do it "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e" $ do
let addr = let addr =
addrToString btc <$> addrToString btc =<<
stringToAddr stringToAddr
bch bch
"bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e" "bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e"
addr `shouldBe` Just "3LDsS579y7sruadqu11beEJoTjdFiFCdX4" addr `shouldBe` Just "3LDsS579y7sruadqu11beEJoTjdFiFCdX4"
it "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37" $ do it "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37" $ do
let addr = let addr =
addrToString btc <$> addrToString btc =<<
stringToAddr stringToAddr
bch bch
"bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37" "bitcoincash:pqq3728yw0y47sqn6l2na30mcw6zm78dzq5ucqzc37"

View File

@ -39,7 +39,7 @@ props net = do
it "encodes and decodes address" $ it "encodes and decodes address" $
property $ property $
forAll arbitraryAddress $ \a -> forAll arbitraryAddress $ \a ->
stringToAddr net (addrToString net a) == Just a (stringToAddr net =<< addrToString net a) == Just a
it "shows and reads address" $ it "shows and reads address" $
property $ forAll arbitraryAddress $ \a -> read (show a) == a property $ forAll arbitraryAddress $ \a -> read (show a) == a

View File

@ -136,10 +136,10 @@ checkKeyCompressed = do
checkMatchingAddress :: Assertion checkMatchingAddress :: Assertion
checkMatchingAddress = do checkMatchingAddress = do
assertBool "Key 1" $ addr1 == addrToString btc (pubKeyAddr pub1) assertBool "Key 1" $ Just addr1 == addrToString btc (pubKeyAddr pub1)
assertBool "Key 2" $ addr2 == addrToString btc (pubKeyAddr pub2) assertBool "Key 2" $ Just addr2 == addrToString btc (pubKeyAddr pub2)
assertBool "Key 1C" $ addr1C == addrToString btc (pubKeyAddr pub1C) assertBool "Key 1C" $ Just addr1C == addrToString btc (pubKeyAddr pub1C)
assertBool "Key 2C" $ addr2C == addrToString btc (pubKeyAddr pub2C) assertBool "Key 2C" $ Just addr2C == addrToString btc (pubKeyAddr pub2C)
checkSignatures :: Hash256 -> Assertion checkSignatures :: Hash256 -> Assertion
checkSignatures h = do checkSignatures h = do

View File

@ -293,7 +293,7 @@ runXKeyVec (v, m) = do
assertBool "xPrvID" $ encodeHex (S.encode $ xPrvID m) == head v assertBool "xPrvID" $ encodeHex (S.encode $ xPrvID m) == head v
assertBool "xPrvFP" $ encodeHex (S.encode $ xPrvFP m) == v !! 1 assertBool "xPrvFP" $ encodeHex (S.encode $ xPrvFP m) == v !! 1
assertBool "xPrvAddr" $ assertBool "xPrvAddr" $
addrToString btc (xPubAddr $ deriveXPubKey m) == v !! 2 addrToString btc (xPubAddr $ deriveXPubKey m) == Just (v !! 2)
assertBool "prvKey" $ encodeHex (getSecKey $ xPrvKey m) == v !! 3 assertBool "prvKey" $ encodeHex (getSecKey $ xPrvKey m) == v !! 3
assertBool "xPrvWIF" $ xPrvWif btc m == v !! 4 assertBool "xPrvWIF" $ xPrvWif btc m == v !! 4
assertBool "pubKey" $ assertBool "pubKey" $

View File

@ -364,7 +364,7 @@ runMulSigVector (a, ops) = assertBool "multisig vector" $ Just a == b
b = do b = do
o <- s o <- s
d <- eitherToMaybe $ decodeOutput o d <- eitherToMaybe $ decodeOutput o
return . addrToString btc $ payToScriptAddress d addrToString btc $ payToScriptAddress d
sigDecodeMap :: Network -> (Text, Int) -> Spec sigDecodeMap :: Network -> (Text, Int) -> Spec
sigDecodeMap net (_, i) = sigDecodeMap net (_, i) =

View File

@ -170,7 +170,7 @@ testBuildAddrTx net a (TestCoin v)
| isScriptAddress a = Right (PayScriptHash (getAddrHash160 a)) == out | isScriptAddress a = Right (PayScriptHash (getAddrHash160 a)) == out
| otherwise = undefined | otherwise = undefined
where where
tx = buildAddrTx net [] [(addrToString net a, v)] tx = buildAddrTx net [] [(fromJust (addrToString net a), v)]
out = out =
decodeOutputBS $ decodeOutputBS $
scriptOutput $ scriptOutput $