Skip to content
This repository has been archived by the owner on Jul 25, 2018. It is now read-only.

Commit

Permalink
ABI array fixes
Browse files Browse the repository at this point in the history
Now correctly parses ABI array types,
and shows ABI array values in traces.
  • Loading branch information
mbrock committed Nov 8, 2017
1 parent d48484b commit fb8e843
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 37 deletions.
21 changes: 11 additions & 10 deletions default.nix
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{ mkDerivation, abstract-par, aeson, ansi-wl-pprint, async, base
, base16-bytestring, base64-bytestring, binary, brick, bytestring
, cereal, containers, cryptonite, data-dword, deepseq, directory
, fgl, filepath, ghci-pretty, here, HUnit, lens, lens-aeson, memory
, monad-par, mtl, multiset, operational, optparse-generic, process
, QuickCheck, quickcheck-text, readline, restless-git, rosezipper
, scientific, stdenv, tasty, tasty-hunit, tasty-quickcheck
, temporary, text, text-format, time, transformers, tree-view
, unordered-containers, vector, vty, wreq
, fgl, filepath, ghci-pretty, here, HUnit, lens, lens-aeson
, megaparsec, memory, monad-par, mtl, multiset, operational
, optparse-generic, process, QuickCheck, quickcheck-text, readline
, restless-git, rosezipper, scientific, stdenv, tasty, tasty-hunit
, tasty-quickcheck, temporary, text, text-format, time
, transformers, tree-view, unordered-containers, vector, vty, wreq
}:
mkDerivation {
pname = "hevm";
Expand All @@ -19,10 +19,11 @@ mkDerivation {
abstract-par aeson ansi-wl-pprint base base16-bytestring
base64-bytestring binary brick bytestring cereal containers
cryptonite data-dword deepseq directory fgl filepath ghci-pretty
lens lens-aeson memory monad-par mtl multiset operational
optparse-generic process QuickCheck quickcheck-text readline
restless-git rosezipper scientific temporary text text-format time
transformers tree-view unordered-containers vector vty wreq
lens lens-aeson megaparsec memory monad-par mtl multiset
operational optparse-generic process QuickCheck quickcheck-text
readline restless-git rosezipper scientific temporary text
text-format time transformers tree-view unordered-containers vector
vty wreq
];
executableHaskellDepends = [
aeson ansi-wl-pprint async base base16-bytestring base64-bytestring
Expand Down
1 change: 1 addition & 0 deletions hevm.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ library
transformers == 0.5.*,
lens >= 4.15.1 && < 4.16,
lens-aeson >= 1.0.1 && < 1.1,
megaparsec == 6.*,
memory >= 0.14.5 && < 0.15,
monad-par >= 0.3 && < 0.4,
mtl >= 2.2.1 && < 2.3,
Expand Down
1 change: 1 addition & 0 deletions shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ let
restless-git =
with pkgs.haskell.lib;
dontCheck (self.callPackage restless-git {});
megaparsec = super.megaparsec_6_2_0;
});
};

Expand Down
60 changes: 42 additions & 18 deletions src/EVM/ABI.hs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ module EVM.ABI
import EVM.Keccak (abiKeccak)
import EVM.Types ()

import Control.Monad (replicateM, replicateM_, forM_)
import Control.Monad (replicateM, replicateM_, forM_, void)
import Data.Binary.Get (Get, label, getWord8, getWord32be, skip)
import Data.Binary.Put (Put, runPut, putWord8, putWord32be)
import Data.Bits (shiftL, shiftR, (.&.))
import Data.ByteString (ByteString)
import Data.DoubleWord (Word256, Int256, Word160, signedWord)
import Data.Monoid ((<>))
import Data.Text (Text, pack, unpack, isPrefixOf)
import Data.Text (Text, pack)
import Data.Text.Encoding (encodeUtf8)
import Data.Vector (Vector)
import Data.Word (Word32, Word8)
Expand All @@ -68,6 +68,9 @@ import qualified Data.ByteString.Lazy as BSLazy
import qualified Data.Text as Text
import qualified Data.Vector as Vector

import qualified Text.Megaparsec as P
import qualified Text.Megaparsec.Char as P

data AbiValue
= AbiUInt Int Word256
| AbiInt Int Int256
Expand Down Expand Up @@ -286,22 +289,43 @@ abiCalldata s xs = BSLazy.toStrict . runPut $ do
putAbiSeq xs

parseTypeName :: Text -> Maybe AbiType
parseTypeName = \case
"address" ->
Just AbiAddressType
"bool" ->
Just AbiBoolType
"bytes" ->
Just AbiBytesDynamicType
"string" ->
Just AbiStringType
x | "uint" `isPrefixOf` x ->
Just . AbiUIntType . read . unpack $ Text.drop 4 x
x | "int" `isPrefixOf` x ->
Just . AbiIntType . read . unpack $ Text.drop 3 x
x | "bytes" `isPrefixOf` x ->
Just . AbiBytesType . read . unpack $ Text.drop 5 x
x -> error (show x)
parseTypeName = P.parseMaybe typeWithArraySuffix

typeWithArraySuffix :: P.Parsec () Text AbiType
typeWithArraySuffix = do
base <- basicType
sizes <-
P.many $
P.between
(P.char '[') (P.char ']')
(P.many P.digitChar)

let
parseSize :: AbiType -> [Char] -> AbiType
parseSize t "" = AbiArrayDynamicType t
parseSize t s = AbiArrayType (read s) t

pure (foldl parseSize base sizes)

basicType :: P.Parsec () Text AbiType
basicType =
P.choice
[ P.string "address" *> pure AbiAddressType
, P.string "bool" *> pure AbiBoolType
, P.string "string" *> pure AbiStringType

, sizedType "uint" AbiUIntType
, sizedType "int" AbiIntType
, sizedType "bytes" AbiBytesType

, P.string "bytes" *> pure AbiBytesDynamicType
]

where
sizedType :: Text -> (Int -> AbiType) -> P.Parsec () Text AbiType
sizedType s f = P.try $ do
void (P.string s)
fmap (f . read) (P.some P.digitChar)

pack32 :: Int -> [Word32] -> Word256
pack32 n xs =
Expand Down
31 changes: 22 additions & 9 deletions src/EVM/Format.hs
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,29 @@ showAbiValues :: Vector AbiValue -> Text
showAbiValues vs =
"(" <> intercalate ", " (toList (fmap showAbiValue vs)) <> ")"

showAbiArray :: Vector AbiValue -> Text
showAbiArray vs =
"[" <> intercalate ", " (toList (fmap showAbiValue vs)) <> "]"

showAbiValue :: AbiValue -> Text
showAbiValue (AbiUInt _ w) = humanizeInteger w
showAbiValue (AbiInt _ w) = humanizeInteger w
showAbiValue (AbiAddress w160) = pack $ "0x" ++ (showHex w160 "")
showAbiValue (AbiBool b) = pack $ show b
showAbiValue (AbiBytes _ bs) = formatBytes bs
showAbiValue (AbiBytesDynamic bs) = formatBinary bs
showAbiValue (AbiString bs) = formatQString bs
-- TODO: arrays
showAbiValue value = pack $ show value
showAbiValue (AbiUInt _ w) =
pack $ show w
showAbiValue (AbiInt _ w) =
pack $ show w
showAbiValue (AbiBool b) =
pack $ show b
showAbiValue (AbiAddress w160) =
pack $ "0x" ++ (showHex w160 "")
showAbiValue (AbiBytes _ bs) =
formatBytes bs
showAbiValue (AbiBytesDynamic bs) =
formatBinary bs
showAbiValue (AbiString bs) =
formatQString bs
showAbiValue (AbiArray _ _ xs) =
showAbiArray xs
showAbiValue (AbiArrayDynamic _ xs) =
showAbiArray xs

isPrintable :: ByteString -> Bool
isPrintable =
Expand Down

0 comments on commit fb8e843

Please sign in to comment.