ethereum-analyzer-cli 1.2.0 → 1.3.0
raw patch · 5 files changed
+145/−53 lines, 5 filesdep +protoludedep +tostringnew-component:exe:ea-bytecode-vis
Dependencies added: protolude, tostring
Files
- ethereum-analyzer-cli.cabal +24/−7
- exec_src/BytecodeVisMain.hs +34/−0
- exec_src/DumpCodeMain.hs +9/−46
- src/Ethereum/Executable/BytecodeVisMain.hs +26/−0
- src/Ethereum/Executable/DumpCodeMain.hs +52/−0
ethereum-analyzer-cli.cabal view
@@ -1,5 +1,5 @@ name: ethereum-analyzer-cli-version: 1.2.0+version: 1.3.0 synopsis: A CLI frontend for ethereum-analyzer. homepage: https://github.com/ethereumK/ethereum-analyzer license: Apache-2.0@@ -21,7 +21,7 @@ source-repository this type: git location: https://github.com/zchn/ethereum-analyzer- tag: v1.2.0+ tag: v1.3.0 subdir: ethereum-analyzer-cli library@@ -29,16 +29,24 @@ , aeson , bytestring , conduit-combinators+ , directory+ , ethereum-analyzer , ethereum-analyzer-deps , exceptions , hexstring , http-conduit , json-rpc+ , monad-logger+ , mtl+ , protolude , text+ , tostring , unordered-containers , vector - exposed-modules: Ethereum.Jsonrpc.Client+ exposed-modules: Ethereum.Executable.BytecodeVisMain+ Ethereum.Executable.DumpCodeMain+ other-modules: Ethereum.Jsonrpc.Client ghc-options: -Wall hs-source-dirs: src buildable: True@@ -48,14 +56,23 @@ executable ea-dump-contract main-is: DumpCodeMain.hs build-depends: base >= 4 && < 5- , directory- , ethereum-analyzer , ethereum-analyzer-cli , ethereum-analyzer-deps , hflags , monad-logger- , mtl- , text+ , protolude+ ghc-options: -Wall+ hs-source-dirs: exec_src+ buildable: True+ default-language: Haskell98++executable ea-bytecode-vis+ main-is: BytecodeVisMain.hs+ build-depends: base >= 4 && < 5+ , ethereum-analyzer-cli+ , hflags+ , monad-logger+ , protolude ghc-options: -Wall hs-source-dirs: exec_src buildable: True
+ exec_src/BytecodeVisMain.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE OverloadedStrings, TemplateHaskell, FlexibleContexts+ #-}+{-# LANGUAGE NoImplicitPrelude #-}++-- | Dump all contracts.+module Main+ ( main+ ) where++import Control.Monad.Logger+import Ethereum.Executable.BytecodeVisMain (bytecodeVisMain)+import HFlags+import Protolude++defineFlag+ "bytecode"+ ("" :: Text)+ "The bytecode. Will read from STDIN if empty."++defineFlag+ "outDot"+ ("" :: Text)+ "The dot file path. Will print to STDOUT if empty"++defineFlag+ "dummy"+ False+ "dummy flag for https://github.com/nilcons/hflags/issues/14"++main :: IO ()+main = do+ s <- $initHFlags "ea-bytecode-vis"+ putText $ "Flags: " <> show s+ runStdoutLoggingT (bytecodeVisMain flags_bytecode flags_outDot)
exec_src/DumpCodeMain.hs view
@@ -6,15 +6,10 @@ ( main ) where -import Ethereum.Jsonrpc.Client import Blockchain.Output+import Ethereum.Executable.DumpCodeMain import Control.Monad.Logger-import Control.Monad.Trans-import Data.Maybe-import Data.Text as T hiding (map) import HFlags-import Numeric-import System.Directory as SD defineFlag "jrpcServer"@@ -25,48 +20,16 @@ defineFlag "contractDir" ("contracts" :: String) "Directory for contact files." --- https://github.com/nilcons/hflags/issues/14-return []+defineFlag+ "dummy"+ False+ "dummy flag for https://github.com/nilcons/hflags/issues/14" main :: IO () main = do s <- $initHFlags "ea-dump-contract" putStrLn $ "Flags: " ++ show s- flip runLoggingT printLogMsg (dumpContracts flags_jrpcServer flags_jrpcPort)--dumpContracts :: String -> Int -> LoggingT IO ()-dumpContracts server port = do- $logInfo "Dumping eth contracts."- ver <- web3ClientVersion server port- $logInfo $ T.append "version is " ver- latest_bNum <- ethBlockNumber server port- let parsed_bns = readHex $ Prelude.drop 2 $ T.unpack latest_bNum- $logInfo $ T.pack $ "parsing block number: " ++ show parsed_bns- let latest_bn = fst $ Prelude.head $ parsed_bns- $logInfo $ T.pack $ "block number is " ++ show latest_bn- enumerateContractAt server port latest_bn- return ()--enumerateContractAt :: String -> Int -> Int -> LoggingT IO ()-enumerateContractAt _ _ 0 = return ()-enumerateContractAt s p bn = do- $logInfo $ T.pack $ "processing block " ++ show bn- transactions <- ethGetTransactionsByBlockNumber s p (T.pack $ show bn)- -- $logInfo $ T.pack $ "transactions: " ++ show transactions- addresses <- catMaybes <$> mapM (ethGetContractAddrByTxHash s p) transactions- -- $logInfo $ T.pack $ "addresses: " ++ show addresses- mapM_- (\addr -> do- let fpath = flags_contractDir ++ "/" ++ T.unpack addr ++ ".contract"- fileExists <- lift $ doesFileExist fpath- if fileExists- then $logInfo $ T.pack $ "skipping: " ++ show addr- else do- textCode <- ethGetCode s p addr- lift $ writeFile fpath $ T.unpack $ T.drop 2 textCode- -- $logInfo $ T.append "textCode is " textCode- )- addresses- -- code <- getCode server port "0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe"- -- $logInfo $ T.pack $ "decompiled code is " ++ formatCode code- enumerateContractAt s p (bn - 1)+ flip+ runLoggingT+ printLogMsg+ (dumpContracts flags_jrpcServer flags_jrpcPort flags_contractDir)
+ src/Ethereum/Executable/BytecodeVisMain.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE NoImplicitPrelude #-}++module Ethereum.Executable.BytecodeVisMain+ ( bytecodeVisMain+ ) where++import Control.Monad.Logger+import Data.String.ToString+import Data.Text (null)+import Ethereum.Analyzer.Disasm+import Ethereum.Analyzer.Util+import Protolude hiding (null)++bytecodeVisMain :: Text -> Text -> LoggingT IO ()+bytecodeVisMain hexstring dotFilepath = do+ hs <-+ if null hexstring+ then lift getLine+ else return hexstring+ let (ctorDot, dispDot) = disasmToDotText2 $ EvmHexString hs+ if null dotFilepath+ then putText dispDot+ else do+ lift $ writeFile (toString dotFilepath) dispDot+ lift $ writeFile (toString $ dotFilepath <> "ctor.dot") ctorDot
+ src/Ethereum/Executable/DumpCodeMain.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE OverloadedStrings, TemplateHaskell, FlexibleContexts+ #-}++-- | Dump all contracts.+module Ethereum.Executable.DumpCodeMain+ ( dumpContracts+ ) where++import Ethereum.Jsonrpc.Client+import Control.Monad.Logger+import Control.Monad.Trans+import Data.Maybe+import Data.Text as T hiding (map)+import Numeric+import System.Directory as SD++dumpContracts :: String -> Int -> String -> LoggingT IO ()+dumpContracts server port contractDir = do+ $logInfo "Dumping eth contracts."+ ver <- web3ClientVersion server port+ $logInfo $ T.append "version is " ver+ latest_bNum <- ethBlockNumber server port+ let parsed_bns = readHex $ Prelude.drop 2 $ T.unpack latest_bNum+ $logInfo $ T.pack $ "parsing block number: " ++ show parsed_bns+ let latest_bn = fst $ Prelude.head $ parsed_bns+ $logInfo $ T.pack $ "block number is " ++ show latest_bn+ enumerateContractAt server port contractDir latest_bn+ return ()++enumerateContractAt :: String -> Int -> String -> Int -> LoggingT IO ()+enumerateContractAt _ _ _ 0 = return ()+enumerateContractAt s p contractDir bn = do+ $logInfo $ T.pack $ "processing block " ++ show bn+ transactions <- ethGetTransactionsByBlockNumber s p (T.pack $ show bn)+ -- $logInfo $ T.pack $ "transactions: " ++ show transactions+ addresses <- catMaybes <$> mapM (ethGetContractAddrByTxHash s p) transactions+ -- $logInfo $ T.pack $ "addresses: " ++ show addresses+ mapM_+ (\addr -> do+ let fpath = contractDir ++ "/" ++ T.unpack addr ++ ".contract"+ fileExists <- lift $ doesFileExist fpath+ if fileExists+ then $logInfo $ T.pack $ "skipping: " ++ show addr+ else do+ textCode <- ethGetCode s p addr+ lift $ writeFile fpath $ T.unpack $ T.drop 2 textCode+ -- $logInfo $ T.append "textCode is " textCode+ )+ addresses+ -- code <- getCode server port "0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe"+ -- $logInfo $ T.pack $ "disasmd code is " ++ formatCode code+ enumerateContractAt s p contractDir (bn - 1)