module Ethereum.Analyzer.EVM.Disasm ( EvmBytecode(..) , EvmHexString(..) , HasEvmBytecode(..) , disasm ) where import Protolude hiding (show) import Blockchain.Data.Code import Blockchain.ExtWord import Blockchain.Util import Blockchain.VM.Code import Blockchain.VM.Opcodes import Data.HexString class HasEvmBytecode a where evmBytecodeOf :: a -> EvmBytecode newtype EvmBytecode = EvmBytecode { unEvmBytecode :: ByteString } deriving (Show, Eq) newtype EvmHexString = EvmHexString { unEvmHexString :: Text } deriving (Show, Eq) instance HasEvmBytecode EvmBytecode where evmBytecodeOf = identity instance HasEvmBytecode EvmHexString where evmBytecodeOf = EvmBytecode . toBytes . hexString . encodeUtf8 . unEvmHexString instance HasEvmBytecode Code where evmBytecodeOf (Code bs) = EvmBytecode bs evmBytecodeOf _ = EvmBytecode "" disasm :: HasEvmBytecode a => a -> [(Word256, Operation)] disasm a = let bs = (unEvmBytecode . evmBytecodeOf) a hardlimit = 10000 in disasmBSAt bs 0 hardlimit disasmBSAt :: ByteString -> Word256 -> Int -> [(Word256, Operation)] disasmBSAt "" _ _ = [] disasmBSAt _ _ 0 = [] disasmBSAt bs base limit = (base, op) : disasmBSAt (safeDrop next bs) (base + next) (limit - 1) where (op, next) = getOperationAt' bs 0