web3-bignum-1.0.1.0: src/Data/BigNum.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
-- |
-- Module : Data.BigNum
-- Copyright : Aleksandr Krupenkin 2016-2024
-- License : Apache-2.0
--
-- Maintainer : mail@akru.me
-- Stability : experimental
-- Portability : unportable
--
-- Big numbers and codecs for Haskell Web3 library.
--
module Data.BigNum (Word256, Word128, H160, h160, H256, h256, H512, h512) where
import Codec.Scale ()
import Codec.Scale.Class (Decode (..), Encode (..))
import Data.ByteArray (ByteArrayAccess, Bytes,
convert)
import qualified Data.ByteArray as A (length)
import Data.ByteArray.HexString.Convert (FromHex (..), ToHex (..),
fromBytes)
import Data.Maybe (fromJust)
import Data.Serialize.Get (getByteString)
import Data.Serialize.Put (putByteString)
import Data.String (IsString (..))
import Data.WideWord.Word128 (Word128 (..))
import Data.WideWord.Word256 (Word256 (..))
instance Encode Word128 where
put (Word128 l h)= put h >> put l
instance Decode Word128 where
get = flip Word128 <$> get <*> get
instance Encode Word256 where
put (Word256 lx hx l h) = do
put h
put l
put hx
put lx
instance Decode Word256 where
get = do
h <- get
l <- get
hx <- get
lx <- get
return (Word256 lx hx l h)
-- | 20 byte of data.
newtype H160 = H160 Bytes
deriving (Eq, Ord, ByteArrayAccess)
-- | Convert any 20 byte array into H160 type, otherwise returns Nothing.
h160 :: ByteArrayAccess a => a -> Maybe H160
h160 ba
| A.length ba == 20 = Just $ H160 (convert ba)
| otherwise = Nothing
instance FromHex H160 where
fromHex bs
| A.length bs == 20 = Right $ H160 (convert bs)
| otherwise = Left ("wrong length: " ++ show (A.length bs))
instance ToHex H160 where
toHex = fromBytes
instance Show H160 where
show = show . toHex
instance IsString H160 where
fromString = either error id . fromHex . fromString
instance Encode H160 where
put = putByteString . convert
instance Decode H160 where
get = (fromJust . h160) <$> getByteString 20
-- | 32 byte of data.
newtype H256 = H256 Bytes
deriving (Eq, Ord, ByteArrayAccess)
-- | Convert any 32 byte array into H256 type, otherwise returns Nothing.
h256 :: ByteArrayAccess a => a -> Maybe H256
h256 ba
| A.length ba == 32 = Just $ H256 (convert ba)
| otherwise = Nothing
instance FromHex H256 where
fromHex bs
| A.length bs == 32 = Right $ H256 (convert bs)
| otherwise = Left ("wrong length: " ++ show (A.length bs))
instance ToHex H256 where
toHex = fromBytes
instance Show H256 where
show = show . toHex
instance IsString H256 where
fromString = either error id . fromHex . fromString
instance Encode H256 where
put = putByteString . convert
instance Decode H256 where
get = (fromJust . h256) <$> getByteString 32
-- | 64 byte of data.
newtype H512 = H512 Bytes
deriving (Eq, Ord, ByteArrayAccess)
-- | Convert any 64 byte array into H512 type, otherwise returns Nothing.
h512 :: ByteArrayAccess a => a -> Maybe H512
h512 ba
| A.length ba == 64 = Just $ H512 (convert ba)
| otherwise = Nothing
instance FromHex H512 where
fromHex bs
| A.length bs == 64 = Right $ H512 (convert bs)
| otherwise = Left ("wrong length: " ++ show (A.length bs))
instance ToHex H512 where
toHex = fromBytes
instance Show H512 where
show = show . toHex
instance IsString H512 where
fromString = either error id . fromHex . fromString
instance Encode H512 where
put = putByteString . convert
instance Decode H512 where
get = (fromJust . h512) <$> getByteString 64