Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

main infrastructure

  • Loading branch information...
commit 158380b5991449d214e84b2b0b68ea8783bca40c 1 parent cdba169
Alexander Bernauer authored
View
13 bitcoin-script-engine.cabal
@@ -16,15 +16,20 @@ library
ghc-options: -Wall
hs-source-dirs: src
build-depends:
- bytestring >= 0.9.1.10
+ bytestring >= 0.9.1.10,
+ parsec >= 3.1.1
exposed-modules:
- Language.Bitcoin.Machine
- Language.Bitcoin.Opcodes
+ Language.Bitcoin.Types
Language.Bitcoin.Simulator
+ Language.Bitcoin.Assembler
+ Language.Bitcoin.Parser
-executable bitcoin-script-engine
+executable bitcoin-script
hs-source-dirs: src
main-is: Main.hs
+ other-modules:
+ Language.Bitcoin.Main
+ Language.Bitcoin.Options
build-depends: base >= 4
ghc-options: -Wall
View
138 src/Language/Bitcoin/Assembler.hs
@@ -0,0 +1,138 @@
+module Language.Bitcoin.Assembler
+-- export {{{1
+(
+ run_assembler, run_disassembler
+) where
+
+-- imports
+import Language.Bitcoin.Types
+
+-- run_assembler :: Code -> Binary {{{1
+run_assembler :: Code -> Binary
+run_assembler = undefined
+
+-- run_disassembler :: Binary -> Code {{{1
+run_disassembler :: Binary -> Code
+run_disassembler = undefined
+
+--opcodes :: [(Opcode, Int)]
+--opcodes = [
+-- (OP_FALSE, 0)
+-- , (OP_0, 0)
+-- , (OP_1NEGATE, 79)
+-- , (OP_TRUE, 81)
+-- , (OP_1, 81)
+-- , (OP_2, 82)
+-- , (OP_3, 83)
+-- , (OP_4, 84)
+-- , (OP_5, 85)
+-- , (OP_6, 86)
+-- , (OP_7, 87)
+-- , (OP_8, 88)
+-- , (OP_9, 89)
+-- , (OP_10, 90)
+-- , (OP_11, 91)
+-- , (OP_12, 92)
+-- , (OP_13, 93)
+-- , (OP_14, 94)
+-- , (OP_15, 95)
+-- , (OP_16, 96)
+-- , (OP_NOP, 97)
+-- , (OP_IF, 99)
+-- , (OP_NOTIF, 100)
+-- , (OP_ELSE, 103)
+-- , (OP_ENDIF, 104)
+-- , (OP_VERIFY, 105)
+-- , (OP_RETURN, 106)
+-- , (OP_TOALTSTACK, 107)
+-- , (OP_FROMALTSTACK, 108)
+-- , (OP_IFDUP, 115)
+-- , (OP_DEPTH, 116)
+-- , (OP_DROP, 117)
+-- , (OP_DUP, 118)
+-- , (OP_NIP, 119)
+-- , (OP_OVER, 120)
+-- , (OP_PICK, 121)
+-- , (OP_ROLL, 122)
+-- , (OP_ROT, 123)
+-- , (OP_SWAP, 124)
+-- , (OP_TUCK, 125)
+-- , (OP_2DROP, 109)
+-- , (OP_2DUP, 110)
+-- , (OP_3DUP, 111)
+-- , (OP_2OVER, 112)
+-- , (OP_2ROT, 113)
+-- , (OP_2SWAP, 114)
+-- , (OP_CAT, 126)
+-- , (OP_SUBSTR, 127)
+-- , (OP_LEFT, 128)
+-- , (OP_RIGHT, 129)
+-- , (OP_SIZE, 130)
+-- , (OP_INVERT, 131)
+-- , (OP_AND, 132)
+-- , (OP_OR, 133)
+-- , (OP_XOR, 134)
+-- , (OP_EQUAL, 135)
+-- , (OP_EQUALVERIFY, 136)
+-- , (OP_1ADD, 139)
+-- , (OP_1SUB, 140)
+-- , (OP_2MUL, 141)
+-- , (OP_2DIV, 142)
+-- , (OP_NEGATE, 143)
+-- , (OP_ABS, 144)
+-- , (OP_NOT, 145)
+-- , (OP_0NOTEQUAL, 146)
+-- , (OP_ADD, 147)
+-- , (OP_SUB, 148)
+-- , (OP_MUL, 149)
+-- , (OP_DIV, 150)
+-- , (OP_MOD, 151)
+-- , (OP_LSHIFT, 152)
+-- , (OP_RSHIFT, 153)
+-- , (OP_BOOLAND, 154)
+-- , (OP_BOOLOR, 155)
+-- , (OP_NUMEQUAL, 156)
+-- , (OP_NUMEQUALVERIFY, 157)
+-- , (OP_NUMNOTEQUAL, 158)
+-- , (OP_LESSTHAN, 159)
+-- , (OP_GREATERTHAN, 160)
+-- , (OP_LESSTHANOREQUAL, 161)
+-- , (OP_GREATERTHANOREQUAL, 162)
+-- , (OP_MIN, 163)
+-- , (OP_MAX, 164)
+-- , (OP_WITHIN, 165)
+-- , (OP_RIPEMD160, 166)
+-- , (OP_SHA1, 167)
+-- , (OP_SHA256, 168)
+-- , (OP_HASH160, 169)
+-- , (OP_HASH256, 170)
+-- , (OP_CODESEPARATOR, 171)
+-- , (OP_CHECKSIG, 172)
+-- , (OP_CHECKSIGVERIFY, 173)
+-- , (OP_CHECKMULTISIG, 174)
+-- , (OP_CHECKMULTISIGVERIFY, 175)
+-- , (OP_PUBKEYHASH, 253)
+-- , (OP_PUBKEY, 254)
+-- , (OP_INVALIDOPCODE, 255)
+-- , (OP_RESERVED, 80)
+-- , (OP_VER, 98)
+-- , (OP_VERIF, 101)
+-- , (OP_VERNOTIF, 102)
+-- , (OP_RESERVED1, 137)
+-- , (OP_RESERVED2, 138)
+-- , (OP_NOP1, 176)
+-- , (OP_NOP2, 177)
+-- , (OP_NOP3, 178)
+-- , (OP_NOP4, 179)
+-- , (OP_NOP5, 180)
+-- , (OP_NOP6, 181)
+-- , (OP_NOP7, 182)
+-- , (OP_NOP8, 183)
+-- , (OP_NOP9, 184)
+-- , (OP_NOP10, 185)
+-- ]
+--
+--instance Enum Opcode where
+-- fromEnum opcode = fromJust $ lookup opcode opcodes
+-- toEnum byte = fst $ fromJust $ find ((==byte) . snd) opcodes
+--
View
28 src/Language/Bitcoin/Machine.hs
@@ -1,28 +0,0 @@
-module Language.Bitcoin.Machine where
-
-import Language.Bitcoin.Opcodes (Opcode)
-import Data.Word
-
-type Data = [Word8]
-type Stack = [Data]
-
-data Command =
- CmdOpcode Opcode
- | CmdData Data
- deriving (Show, Eq)
-
-type Script = [Command]
-
-data Machine = Machine Script Stack Stack deriving (Show)
-
-data ResultCode =
- Success
- | Failure String
- | Error String
-
-instance Show ResultCode where
- show Success = "Bitcoin script completed successfully."
- show (Failure what) = "Bitcoin script failed: " ++ what
- show (Error what) = "Bitcoin script is illegal: " ++ what
-
-data Result = Result Machine ResultCode deriving (Show)
View
48 src/Language/Bitcoin/Main.hs
@@ -0,0 +1,48 @@
+module Language.Bitcoin.Main where
+
+import qualified Data.ByteString.Char8 as B
+import Language.Bitcoin.Options
+import Language.Bitcoin.Types (ResultCode(Error), Result(Result))
+import Language.Bitcoin.Simulator (run_simulator)
+import Language.Bitcoin.Assembler (run_assembler, run_disassembler)
+import Language.Bitcoin.Parser (run_parser)
+import System.Environment (getArgs, getProgName)
+import System.Exit (exitWith, ExitCode(ExitFailure))
+import System.IO (stderr, hPutStrLn)
+
+main :: IO ()
+main = do
+ prg <- getProgName
+ args <- getArgs
+ opts <- exitOnError $ options prg args
+ input <- B.readFile $ optInput opts
+ output <- exitOnError $ runAction opts input
+ if (optOutput opts /= optOutput defaultOptions)
+ then B.writeFile (optOutput opts) output
+ else return ()
+
+runAction :: Options -> B.ByteString -> Either String B.ByteString
+runAction opts input
+ | optAssembler opts = assembler input
+ | optDisassembler opts = disassembler input
+ | optSimulator opts = simulator input
+ | otherwise = error "internal error"
+
+assembler :: B.ByteString -> Either String B.ByteString
+assembler code = Right $ run_assembler code
+
+disassembler :: B.ByteString -> Either String B.ByteString
+disassembler binary = Right $ run_disassembler binary
+
+simulator :: B.ByteString -> Either String B.ByteString
+simulator code =
+ case run_parser code of
+ Left parseError -> Left $ show parseError
+ Right script ->
+ case run_simulator script of
+ result@(Result (Error _) _) -> Left $ show result
+ result -> Right $ B.pack (show result)
+
+exitOnError :: Either String a -> IO a
+exitOnError (Left e) = hPutStrLn stderr e >> exitWith (ExitFailure 1)
+exitOnError (Right x) = return x
View
266 src/Language/Bitcoin/Opcodes.hs
@@ -1,266 +0,0 @@
-module Language.Bitcoin.Opcodes
-(
- Opcode(..)
-) where
-
-import Data.Maybe (fromJust)
-import Data.List (find)
-
-data Opcode =
--- constants
- OP_0 | OP_FALSE
- | LENGTH Int
- | OP_PUSHDATA1
- | OP_PUSHDATA2
- | OP_PUSHDATA4
- | OP_1NEGATE
- | OP_1 | OP_TRUE
- | OP_2
- | OP_3
- | OP_4
- | OP_5
- | OP_6
- | OP_7
- | OP_8
- | OP_9
- | OP_10
- | OP_11
- | OP_12
- | OP_13
- | OP_14
- | OP_15
- | OP_16
--- flow control
- | OP_NOP
- | OP_IF
- | OP_NOTIF
- | OP_ELSE
- | OP_ENDIF
- | OP_VERIFY
- | OP_RETURN
--- stack
- | OP_TOALTSTACK
- | OP_FROMALTSTACK
- | OP_IFDUP
- | OP_DEPTH
- | OP_DROP
- | OP_DUP
- | OP_NIP
- | OP_OVER
- | OP_PICK
- | OP_ROLL
- | OP_ROT
- | OP_SWAP
- | OP_TUCK
- | OP_2DROP
- | OP_2DUP
- | OP_3DUP
- | OP_2OVER
- | OP_2ROT
- | OP_2SWAP
--- splice
- | OP_CAT
- | OP_SUBSTR
- | OP_LEFT
- | OP_RIGHT
- | OP_SIZE
--- bitwise logic
- | OP_INVERT
- | OP_AND
- | OP_OR
- | OP_XOR
- | OP_EQUAL
- | OP_EQUALVERIFY
--- arithmetic
- | OP_1ADD
- | OP_1SUB
- | OP_2MUL
- | OP_2DIV
- | OP_NEGATE
- | OP_ABS
- | OP_NOT
- | OP_0NOTEQUAL
- | OP_ADD
- | OP_SUB
- | OP_MUL
- | OP_DIV
- | OP_MOD
- | OP_LSHIFT
- | OP_RSHIFT
- | OP_BOOLAND
- | OP_BOOLOR
- | OP_NUMEQUAL
- | OP_NUMEQUALVERIFY
- | OP_NUMNOTEQUAL
- | OP_LESSTHAN
- | OP_GREATERTHAN
- | OP_LESSTHANOREQUAL
- | OP_GREATERTHANOREQUAL
- | OP_MIN
- | OP_MAX
- | OP_WITHIN
--- crypto
- | OP_RIPEMD160
- | OP_SHA1
- | OP_SHA256
- | OP_HASH160
- | OP_HASH256
- | OP_CODESEPARATOR
- | OP_CHECKSIG
- | OP_CHECKSIGVERIFY
- | OP_CHECKMULTISIG
- | OP_CHECKMULTISIGVERIFY
--- pseudo
- | OP_PUBKEYHASH
- | OP_PUBKEY
- | OP_INVALIDOPCODE
--- reserved
- | OP_RESERVED
- | OP_VER
- | OP_VERIF
- | OP_VERNOTIF
- | OP_RESERVED1
- | OP_RESERVED2
- | OP_NOP1
- | OP_NOP2
- | OP_NOP3
- | OP_NOP4
- | OP_NOP5
- | OP_NOP6
- | OP_NOP7
- | OP_NOP8
- | OP_NOP9
- | OP_NOP10
- deriving (Show, Read, Eq)
-
-opcodes :: [(Opcode, Int)]
-opcodes = [
- (OP_FALSE, 0)
- , (OP_0, 0)
- , (LENGTH 1, 1)
- , (OP_PUSHDATA1, 76)
- , (OP_PUSHDATA2, 77)
- , (OP_PUSHDATA4, 78)
- , (OP_1NEGATE, 79)
- , (OP_TRUE, 81)
- , (OP_1, 81)
- , (OP_2, 82)
- , (OP_3, 83)
- , (OP_4, 84)
- , (OP_5, 85)
- , (OP_6, 86)
- , (OP_7, 87)
- , (OP_8, 88)
- , (OP_9, 89)
- , (OP_10, 90)
- , (OP_11, 91)
- , (OP_12, 92)
- , (OP_13, 93)
- , (OP_14, 94)
- , (OP_15, 95)
- , (OP_16, 96)
- , (OP_NOP, 97)
- , (OP_IF, 99)
- , (OP_NOTIF, 100)
- , (OP_ELSE, 103)
- , (OP_ENDIF, 104)
- , (OP_VERIFY, 105)
- , (OP_RETURN, 106)
- , (OP_TOALTSTACK, 107)
- , (OP_FROMALTSTACK, 108)
- , (OP_IFDUP, 115)
- , (OP_DEPTH, 116)
- , (OP_DROP, 117)
- , (OP_DUP, 118)
- , (OP_NIP, 119)
- , (OP_OVER, 120)
- , (OP_PICK, 121)
- , (OP_ROLL, 122)
- , (OP_ROT, 123)
- , (OP_SWAP, 124)
- , (OP_TUCK, 125)
- , (OP_2DROP, 109)
- , (OP_2DUP, 110)
- , (OP_3DUP, 111)
- , (OP_2OVER, 112)
- , (OP_2ROT, 113)
- , (OP_2SWAP, 114)
- , (OP_CAT, 126)
- , (OP_SUBSTR, 127)
- , (OP_LEFT, 128)
- , (OP_RIGHT, 129)
- , (OP_SIZE, 130)
- , (OP_INVERT, 131)
- , (OP_AND, 132)
- , (OP_OR, 133)
- , (OP_XOR, 134)
- , (OP_EQUAL, 135)
- , (OP_EQUALVERIFY, 136)
- , (OP_1ADD, 139)
- , (OP_1SUB, 140)
- , (OP_2MUL, 141)
- , (OP_2DIV, 142)
- , (OP_NEGATE, 143)
- , (OP_ABS, 144)
- , (OP_NOT, 145)
- , (OP_0NOTEQUAL, 146)
- , (OP_ADD, 147)
- , (OP_SUB, 148)
- , (OP_MUL, 149)
- , (OP_DIV, 150)
- , (OP_MOD, 151)
- , (OP_LSHIFT, 152)
- , (OP_RSHIFT, 153)
- , (OP_BOOLAND, 154)
- , (OP_BOOLOR, 155)
- , (OP_NUMEQUAL, 156)
- , (OP_NUMEQUALVERIFY, 157)
- , (OP_NUMNOTEQUAL, 158)
- , (OP_LESSTHAN, 159)
- , (OP_GREATERTHAN, 160)
- , (OP_LESSTHANOREQUAL, 161)
- , (OP_GREATERTHANOREQUAL, 162)
- , (OP_MIN, 163)
- , (OP_MAX, 164)
- , (OP_WITHIN, 165)
- , (OP_RIPEMD160, 166)
- , (OP_SHA1, 167)
- , (OP_SHA256, 168)
- , (OP_HASH160, 169)
- , (OP_HASH256, 170)
- , (OP_CODESEPARATOR, 171)
- , (OP_CHECKSIG, 172)
- , (OP_CHECKSIGVERIFY, 173)
- , (OP_CHECKMULTISIG, 174)
- , (OP_CHECKMULTISIGVERIFY, 175)
- , (OP_PUBKEYHASH, 253)
- , (OP_PUBKEY, 254)
- , (OP_INVALIDOPCODE, 255)
- , (OP_RESERVED, 80)
- , (OP_VER, 98)
- , (OP_VERIF, 101)
- , (OP_VERNOTIF, 102)
- , (OP_RESERVED1, 137)
- , (OP_RESERVED2, 138)
- , (OP_NOP1, 176)
- , (OP_NOP2, 177)
- , (OP_NOP3, 178)
- , (OP_NOP4, 179)
- , (OP_NOP5, 180)
- , (OP_NOP6, 181)
- , (OP_NOP7, 182)
- , (OP_NOP8, 183)
- , (OP_NOP9, 184)
- , (OP_NOP10, 185)
- ]
-
-instance Enum Opcode where
- fromEnum (LENGTH length)
- | length >= 1 && length < 76 = length
- | otherwise = error "illegal LENGTH opcode"
- fromEnum opcode = fromJust $ lookup opcode opcodes
-
- toEnum number
- | number >= 1 && number < 76 = LENGTH number
- | otherwise = fst $ fromJust $ find ((==number) . snd) opcodes
-
View
80 src/Language/Bitcoin/Options.hs
@@ -0,0 +1,80 @@
+module Language.Bitcoin.Options
+-- export {{{1
+(
+ Options(..), options, defaultOptions, Action(..)
+) where
+
+-- import {{{1
+import Data.List (intersperse)
+import System.Console.GetOpt
+
+-- types {{{1
+data Action =
+ Assembler
+ | Dissasembler
+ | Siulator
+
+data Options = Options {
+ optInput :: String
+ , optOutput :: String
+ , optAssembler :: Bool
+ , optDisassembler :: Bool
+ , optSimulator :: Bool
+ , optHelp :: Bool
+} deriving Show
+
+-- options :: String -> [String] -> Either String Options {{{1
+options :: String -> [String] -> Either String Options
+options prg argv =
+ let use = usage prg in
+ case getOpt Permute available_options argv of
+ (o,[],[]) ->
+ let opts = foldl (flip id) defaultOptions o in
+ if (optHelp opts) then
+ Left $ help use
+ else
+ case checkOptions opts of
+ Nothing -> Right opts
+ Just s -> Left $ err use s
+ (_,n,[]) -> Left $ err use ("unknown options '" ++ unwords n ++ "'")
+ (_,_,es) -> Left $ err use $ concat $ intersperse "\n" es
+
+help :: String -> String
+help use = "Printing usage:\n" ++ use
+
+err :: String -> String -> String
+err use msg = "Error in command line options\n" ++ msg ++ "\n" ++ use
+
+usage :: String -> String
+usage prg = usageInfo ("Usage: " ++ prg ++ " OPTIONS") available_options
+
+available_options :: [OptDescr (Options -> Options)]
+available_options = [
+ Option ['i'] ["input"] (ReqArg (\x opts -> opts {optInput = x}) "input") "input file"
+ , Option ['o'] ["output"] (ReqArg (\x opts -> opts {optOutput = x}) "output") "output file"
+ , Option ['s'] ["assembler"] (NoArg (\opts -> opts {optSimulator = True})) "run the simulator"
+ , Option ['a'] ["assembler"] (NoArg (\opts -> opts {optAssembler = True})) "run the assembler"
+ , Option ['d'] ["disassembler"] (NoArg (\opts -> opts {optDisassembler = True})) "run the disassembler"
+ , Option ['h'] ["help"] (NoArg (\opts -> opts {optHelp = True})) "print help and quit"
+ ]
+
+defaultOptions :: Options
+defaultOptions = Options {
+ optInput = ""
+ , optOutput = ""
+ , optSimulator = False
+ , optAssembler = False
+ , optDisassembler = False
+ , optHelp = False
+}
+
+b2n :: Bool -> Int
+b2n True = 1
+b2n False = 0
+
+checkOptions :: Options -> Maybe String
+checkOptions opts
+ | optInput opts == optInput defaultOptions = Just "input file required"
+ | b2n (optSimulator opts) + b2n (optAssembler opts) + b2n (optDisassembler opts) /= 1 = Just "please choose exactly one action to run"
+ | ((optAssembler opts || optDisassembler opts) && (optOutput opts) == (optOutput defaultOptions)) = Just "output required for assembler and dissasembler action"
+ | otherwise = Nothing
View
34 src/Language/Bitcoin/Parser.hs
@@ -0,0 +1,34 @@
+module Language.Bitcoin.Parser
+-- export {{{1
+(
+ run_parser, run_printer
+) where
+
+-- import {{{1
+import Language.Bitcoin.Types
+import Text.ParserCombinators.Parsec
+import qualified Data.ByteString.Char8 as B
+
+-- run_parser :: Code -> Script {{{1
+run_parser :: Code -> Either ParseError Script
+run_parser code = parse script "(unknown)" (B.unpack code)
+
+
+script :: Parser Script
+script = sepBy operation separator
+
+operation :: Parser Opcode
+operation = opcode -- <|> paste
+
+opcode :: Parser Opcode
+opcode = string "OP_FALSE" >> return OP_FALSE
+--paste = string "PASTE" >> bytes >>= (\bs -> return PASTE DATA (pack bs))
+
+separator :: Parser Char
+separator = char '\n' -- <|> char ';'
+
+
+-- run_printer :: Script -> Code {{{1
+run_printer :: Script -> Code
+run_printer = undefined
+
View
27 src/Language/Bitcoin/Simulator.hs
@@ -1,23 +1,28 @@
module Language.Bitcoin.Simulator
(
- run_simulator
+ run_simulator, run_simulator'
) where
-import Language.Bitcoin.Machine
-import Language.Bitcoin.Opcodes
+import Language.Bitcoin.Types
+import Data.ByteString (unpack)
-run_simulator :: Machine -> Result
-run_simulator machine@(Machine [] stack _) =
+
+run_simulator :: Script -> Result
+run_simulator script = run_simulator' (Machine script [] [])
+
+run_simulator' :: Machine -> Result
+run_simulator' machine@(Machine [] stack _) =
case stack of
- ([1]:_) -> Result machine Success
- _ -> Result machine $ Failure "top stack value is not True"
+ ([1]:_) -> Result Success machine
+ _ -> Result (Failure "top stack value is not True") machine
-run_simulator machine@(Machine ((CmdData _):_) _ _) = Result machine $ Error "unexpected data"
+run_simulator' (Machine ((PASTE _ data_):rest) stack altStack) =
+ run_simulator' (Machine rest (unpack data_ : stack) altStack)
-run_simulator machine@(Machine ((CmdOpcode op):ops) stack altStack) =
+run_simulator' machine@(Machine (op:rest) stack altStack) =
case simpleOp op stack of
- Left what -> Result machine $ Error what
- Right (stack') -> run_simulator $ Machine ops stack' altStack
+ Left what -> Result (Error what) machine
+ Right (stack') -> run_simulator' (Machine rest stack' altStack)
simpleOp :: Opcode -> Stack -> Either String Stack
View
161 src/Language/Bitcoin/Types.hs
@@ -0,0 +1,161 @@
+module Language.Bitcoin.Types where
+
+-- import {{{1
+import Data.Word (Word8)
+import qualified Data.ByteString.Char8 as B
+
+-- types {{{1
+type Binary = B.ByteString
+type Code = B.ByteString
+
+type Item = [Word8]
+type Stack = [Item]
+type Script = [Opcode]
+
+data Machine = Machine Script Stack Stack deriving Show
+
+data ResultCode =
+ Success
+ | Failure String
+ | Error String
+
+instance Show ResultCode where
+ show Success = "Bitcoin script completed successfully."
+ show (Failure what) = "Bitcoin script failed: " ++ what
+ show (Error what) = "Bitcoin script is illegal: " ++ what
+
+data Result = Result ResultCode Machine deriving Show
+
+-- data Opcode = {{{1
+data Opcode =
+-- constants {{{2
+ PASTE Data B.ByteString
+ | OP_0 | OP_FALSE
+ | OP_1NEGATE
+ | OP_1 | OP_TRUE
+ | OP_2
+ | OP_3
+ | OP_4
+ | OP_5
+ | OP_6
+ | OP_7
+ | OP_8
+ | OP_9
+ | OP_10
+ | OP_11
+ | OP_12
+ | OP_13
+ | OP_14
+ | OP_15
+ | OP_16
+-- flow control {{{2
+ | OP_NOP
+ | OP_IF
+ | OP_NOTIF
+ | OP_ELSE
+ | OP_ENDIF
+ | OP_VERIFY
+ | OP_RETURN
+-- stack {{{2
+ | OP_TOALTSTACK
+ | OP_FROMALTSTACK
+ | OP_IFDUP
+ | OP_DEPTH
+ | OP_DROP
+ | OP_DUP
+ | OP_NIP
+ | OP_OVER
+ | OP_PICK
+ | OP_ROLL
+ | OP_ROT
+ | OP_SWAP
+ | OP_TUCK
+ | OP_2DROP
+ | OP_2DUP
+ | OP_3DUP
+ | OP_2OVER
+ | OP_2ROT
+ | OP_2SWAP
+-- splice {{{2
+ | OP_CAT
+ | OP_SUBSTR
+ | OP_LEFT
+ | OP_RIGHT
+ | OP_SIZE
+-- bitwise logic {{{2
+ | OP_INVERT
+ | OP_AND
+ | OP_OR
+ | OP_XOR
+ | OP_EQUAL
+ | OP_EQUALVERIFY
+-- arithmetic {{{2
+ | OP_1ADD
+ | OP_1SUB
+ | OP_2MUL
+ | OP_2DIV
+ | OP_NEGATE
+ | OP_ABS
+ | OP_NOT
+ | OP_0NOTEQUAL
+ | OP_ADD
+ | OP_SUB
+ | OP_MUL
+ | OP_DIV
+ | OP_MOD
+ | OP_LSHIFT
+ | OP_RSHIFT
+ | OP_BOOLAND
+ | OP_BOOLOR
+ | OP_NUMEQUAL
+ | OP_NUMEQUALVERIFY
+ | OP_NUMNOTEQUAL
+ | OP_LESSTHAN
+ | OP_GREATERTHAN
+ | OP_LESSTHANOREQUAL
+ | OP_GREATERTHANOREQUAL
+ | OP_MIN
+ | OP_MAX
+ | OP_WITHIN
+-- crypto {{{2
+ | OP_RIPEMD160
+ | OP_SHA1
+ | OP_SHA256
+ | OP_HASH160
+ | OP_HASH256
+ | OP_CODESEPARATOR
+ | OP_CHECKSIG
+ | OP_CHECKSIGVERIFY
+ | OP_CHECKMULTISIG
+ | OP_CHECKMULTISIGVERIFY
+-- pseudo {{{2
+ | OP_PUBKEYHASH
+ | OP_PUBKEY
+ | OP_INVALIDOPCODE
+-- reserved {{{2
+ | OP_RESERVED
+ | OP_VER
+ | OP_VERIF
+ | OP_VERNOTIF
+ | OP_RESERVED1
+ | OP_RESERVED2
+ | OP_NOP1
+ | OP_NOP2
+ | OP_NOP3
+ | OP_NOP4
+ | OP_NOP5
+ | OP_NOP6
+ | OP_NOP7
+ | OP_NOP8
+ | OP_NOP9
+ | OP_NOP10
+ deriving (Show)
+
+-- data Data = {{{1
+data Data =
+ DATA Word8
+ | OP_PUSHDATA1 Word8
+ | OP_PUSHDATA2 Word8 Word8
+ | OP_PUSHDATA4 Word8 Word8 Word8 Word8
+ deriving (Show)
+
View
7 src/Main.hs
@@ -1,6 +1,3 @@
-module Main where
+module Main (main) where
-import Language.Bitcoin.Opcodes
-
-main::IO()
-main = putStrLn $ show $ fromEnum OP_PUSHDATA1
+import Language.Bitcoin.Main (main)
View
51 test/Language/Bitcoin/Test/Opcodes.hs
@@ -3,42 +3,41 @@ module Language.Bitcoin.Test.Opcodes
tests
) where
-import Language.Bitcoin.Opcodes
-import Language.Bitcoin.Machine
-import Language.Bitcoin.Simulator
+import Language.Bitcoin.Simulator (run_simulator')
+import Language.Bitcoin.Types
import Test.HUnit
tests = TestLabel "Opcodes" $ TestList testSimpleOps
simpleOps = [
([], [], [])
- , ([CmdOpcode(OP_FALSE)], [], [[0]])
- , ([CmdOpcode(OP_TRUE)], [], [[1]])
- , ([CmdOpcode(OP_0)], [], [[0]])
- , ([CmdOpcode(OP_1)], [], [[1]])
- , ([CmdOpcode(OP_2)], [], [[2]])
- , ([CmdOpcode(OP_3)], [], [[3]])
- , ([CmdOpcode(OP_4)], [], [[4]])
- , ([CmdOpcode(OP_5)], [], [[5]])
- , ([CmdOpcode(OP_6)], [], [[6]])
- , ([CmdOpcode(OP_7)], [], [[7]])
- , ([CmdOpcode(OP_8)], [], [[8]])
- , ([CmdOpcode(OP_9)], [], [[9]])
- , ([CmdOpcode(OP_10)], [], [[10]])
- , ([CmdOpcode(OP_11)], [], [[11]])
- , ([CmdOpcode(OP_12)], [], [[12]])
- , ([CmdOpcode(OP_13)], [], [[13]])
- , ([CmdOpcode(OP_14)], [], [[14]])
- , ([CmdOpcode(OP_15)], [], [[15]])
- , ([CmdOpcode(OP_16)], [], [[16]])
- , ([CmdOpcode(OP_NOP)], [[23]], [[23]])
+ , ([OP_FALSE], [], [[0]])
+ , ([OP_TRUE], [], [[1]])
+ , ([OP_0], [], [[0]])
+ , ([OP_1], [], [[1]])
+ , ([OP_2], [], [[2]])
+ , ([OP_3], [], [[3]])
+ , ([OP_4], [], [[4]])
+ , ([OP_5], [], [[5]])
+ , ([OP_6], [], [[6]])
+ , ([OP_7], [], [[7]])
+ , ([OP_8], [], [[8]])
+ , ([OP_9], [], [[9]])
+ , ([OP_10], [], [[10]])
+ , ([OP_11], [], [[11]])
+ , ([OP_12], [], [[12]])
+ , ([OP_13], [], [[13]])
+ , ([OP_14], [], [[14]])
+ , ([OP_15], [], [[15]])
+ , ([OP_16], [], [[16]])
+ , ([OP_NOP], [[23]], [[23]])
]
testSimpleOps = map runTest simpleOps
where
runTest (script, stack, expected) = TestCase $
- case run_simulator (Machine script stack []) of
- Result (Machine _ stack' _) Success -> expected @=? stack'
- Result (Machine _ stack' _) (Failure _) -> expected @=? stack'
+ case run_simulator' (Machine script stack []) of
+ Result Success (Machine _ stack' _) -> expected @=? stack'
+ Result (Failure _) (Machine _ stack' _) -> expected @=? stack'
result -> assertString $ show result
Please sign in to comment.
Something went wrong with that request. Please try again.