-- | -- Module : Network.Ethereum.Web3.Encoding -- Copyright : Alexander Krupenkin 2016 -- License : BSD3 -- -- Maintainer : mail@akru.me -- Stability : experimental -- Portability : portable -- -- Web3 ABI encoding data support. -- module Network.Ethereum.Web3.Encoding (ABIEncoding(..)) where import qualified Data.Attoparsec.Text as P import Data.Attoparsec.Text.Lazy (Parser, maybeResult, parse) import Data.Monoid ((<>)) import Data.Text (Text) import qualified Data.Text as T import qualified Data.Text.Lazy as LT import Data.Text.Lazy.Builder (Builder, fromLazyText, fromText, toLazyText) import Network.Ethereum.Web3.Address (Address) import qualified Network.Ethereum.Web3.Address as A import Network.Ethereum.Web3.Encoding.Internal -- | Contract ABI data codec class ABIEncoding a where toDataBuilder :: a -> Builder fromDataParser :: Parser a -- | Encode value into abi-encoding represenation toData :: a -> Text {-# INLINE toData #-} toData = LT.toStrict . toLazyText . toDataBuilder -- | Parse encoded value fromData :: Text -> Maybe a {-# INLINE fromData #-} fromData = maybeResult . parse fromDataParser . LT.fromStrict instance ABIEncoding Bool where toDataBuilder = int256HexBuilder . fromEnum fromDataParser = fmap toEnum int256HexParser instance ABIEncoding Integer where toDataBuilder = int256HexBuilder fromDataParser = int256HexParser instance ABIEncoding Int where toDataBuilder = int256HexBuilder fromDataParser = int256HexParser instance ABIEncoding Word where toDataBuilder = int256HexBuilder fromDataParser = int256HexParser instance ABIEncoding Text where toDataBuilder = textBuilder fromDataParser = textParser instance ABIEncoding Address where toDataBuilder = alignR . fromText . A.toText fromDataParser = either error id . A.fromText <$> (P.take 24 *> P.take 40) instance ABIEncoding a => ABIEncoding [a] where toDataBuilder x = int256HexBuilder (length x) <> foldMap toDataBuilder x fromDataParser = do len <- int256HexParser take len <$> P.many1 fromDataParser