module Ethereum.Analyzer.Disasm ( EvmBytecode(..) , EvmHexString(..) , HasEvmBytecode(..) , disasm ) where import Blockchain.Data.Code import Blockchain.ExtWord import Blockchain.Util import Blockchain.VM.Code import Blockchain.VM.Opcodes import Data.ByteString import Data.HexString import Data.Text import Data.Text.Encoding 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 = id 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