{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Haskoin.Script.Common
(
ScriptOp(..)
, Script(..)
, PushDataType(..)
, isPushOp
, opPushData
, intToScriptOp
, scriptOpToInt
) where
import Control.DeepSeq
import Control.Monad
import Data.Binary (Binary (..))
import Data.ByteString (ByteString)
import qualified Data.ByteString as B
import Data.Bytes.Get
import Data.Bytes.Put
import Data.Bytes.Serial
import Data.Hashable
import Data.Serialize (Serialize (..))
import Data.Word (Word8)
import GHC.Generics (Generic)
newtype Script =
Script {
Script -> [ScriptOp]
scriptOps :: [ScriptOp]
}
deriving (Script -> Script -> Bool
(Script -> Script -> Bool)
-> (Script -> Script -> Bool) -> Eq Script
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Script -> Script -> Bool
$c/= :: Script -> Script -> Bool
== :: Script -> Script -> Bool
$c== :: Script -> Script -> Bool
Eq, Int -> Script -> ShowS
[Script] -> ShowS
Script -> String
(Int -> Script -> ShowS)
-> (Script -> String) -> ([Script] -> ShowS) -> Show Script
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Script] -> ShowS
$cshowList :: [Script] -> ShowS
show :: Script -> String
$cshow :: Script -> String
showsPrec :: Int -> Script -> ShowS
$cshowsPrec :: Int -> Script -> ShowS
Show, ReadPrec [Script]
ReadPrec Script
Int -> ReadS Script
ReadS [Script]
(Int -> ReadS Script)
-> ReadS [Script]
-> ReadPrec Script
-> ReadPrec [Script]
-> Read Script
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [Script]
$creadListPrec :: ReadPrec [Script]
readPrec :: ReadPrec Script
$creadPrec :: ReadPrec Script
readList :: ReadS [Script]
$creadList :: ReadS [Script]
readsPrec :: Int -> ReadS Script
$creadsPrec :: Int -> ReadS Script
Read, (forall x. Script -> Rep Script x)
-> (forall x. Rep Script x -> Script) -> Generic Script
forall x. Rep Script x -> Script
forall x. Script -> Rep Script x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Script x -> Script
$cfrom :: forall x. Script -> Rep Script x
Generic, Int -> Script -> Int
Script -> Int
(Int -> Script -> Int) -> (Script -> Int) -> Hashable Script
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Script -> Int
$chash :: Script -> Int
hashWithSalt :: Int -> Script -> Int
$chashWithSalt :: Int -> Script -> Int
Hashable, Script -> ()
(Script -> ()) -> NFData Script
forall a. (a -> ()) -> NFData a
rnf :: Script -> ()
$crnf :: Script -> ()
NFData)
instance Serial Script where
deserialize :: m Script
deserialize =
[ScriptOp] -> Script
Script ([ScriptOp] -> Script) -> m [ScriptOp] -> m Script
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m [ScriptOp]
getScriptOps
where
getScriptOps :: m [ScriptOp]
getScriptOps = do
Bool
empty <- m Bool
forall (m :: * -> *). MonadGet m => m Bool
isEmpty
if Bool
empty
then [ScriptOp] -> m [ScriptOp]
forall (m :: * -> *) a. Monad m => a -> m a
return []
else (:) (ScriptOp -> [ScriptOp] -> [ScriptOp])
-> m ScriptOp -> m ([ScriptOp] -> [ScriptOp])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m ScriptOp
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize m ([ScriptOp] -> [ScriptOp]) -> m [ScriptOp] -> m [ScriptOp]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> m [ScriptOp]
getScriptOps
serialize :: Script -> m ()
serialize (Script ops :: [ScriptOp]
ops) = [ScriptOp] -> (ScriptOp -> m ()) -> m ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [ScriptOp]
ops ScriptOp -> m ()
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
instance Binary Script where
put :: Script -> Put
put = Script -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
get :: Get Script
get = Get Script
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
instance Serialize Script where
put :: Putter Script
put = Putter Script
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
get :: Get Script
get = Get Script
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
data PushDataType
=
OPCODE
| OPDATA1
| OPDATA2
| OPDATA4
deriving (Int -> PushDataType -> ShowS
[PushDataType] -> ShowS
PushDataType -> String
(Int -> PushDataType -> ShowS)
-> (PushDataType -> String)
-> ([PushDataType] -> ShowS)
-> Show PushDataType
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PushDataType] -> ShowS
$cshowList :: [PushDataType] -> ShowS
show :: PushDataType -> String
$cshow :: PushDataType -> String
showsPrec :: Int -> PushDataType -> ShowS
$cshowsPrec :: Int -> PushDataType -> ShowS
Show, ReadPrec [PushDataType]
ReadPrec PushDataType
Int -> ReadS PushDataType
ReadS [PushDataType]
(Int -> ReadS PushDataType)
-> ReadS [PushDataType]
-> ReadPrec PushDataType
-> ReadPrec [PushDataType]
-> Read PushDataType
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PushDataType]
$creadListPrec :: ReadPrec [PushDataType]
readPrec :: ReadPrec PushDataType
$creadPrec :: ReadPrec PushDataType
readList :: ReadS [PushDataType]
$creadList :: ReadS [PushDataType]
readsPrec :: Int -> ReadS PushDataType
$creadsPrec :: Int -> ReadS PushDataType
Read, PushDataType -> PushDataType -> Bool
(PushDataType -> PushDataType -> Bool)
-> (PushDataType -> PushDataType -> Bool) -> Eq PushDataType
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PushDataType -> PushDataType -> Bool
$c/= :: PushDataType -> PushDataType -> Bool
== :: PushDataType -> PushDataType -> Bool
$c== :: PushDataType -> PushDataType -> Bool
Eq, (forall x. PushDataType -> Rep PushDataType x)
-> (forall x. Rep PushDataType x -> PushDataType)
-> Generic PushDataType
forall x. Rep PushDataType x -> PushDataType
forall x. PushDataType -> Rep PushDataType x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PushDataType x -> PushDataType
$cfrom :: forall x. PushDataType -> Rep PushDataType x
Generic, Int -> PushDataType -> Int
PushDataType -> Int
(Int -> PushDataType -> Int)
-> (PushDataType -> Int) -> Hashable PushDataType
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: PushDataType -> Int
$chash :: PushDataType -> Int
hashWithSalt :: Int -> PushDataType -> Int
$chashWithSalt :: Int -> PushDataType -> Int
Hashable, PushDataType -> ()
(PushDataType -> ()) -> NFData PushDataType
forall a. (a -> ()) -> NFData a
rnf :: PushDataType -> ()
$crnf :: PushDataType -> ()
NFData)
data ScriptOp
= OP_PUSHDATA !ByteString
!PushDataType
| OP_0
| OP_1NEGATE
| OP_RESERVED
| OP_1
| 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
| OP_NOP
| OP_VER
| OP_IF
| OP_NOTIF
| OP_VERIF
| OP_VERNOTIF
| OP_ELSE
| OP_ENDIF
| OP_VERIFY
| OP_RETURN
| 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
| OP_CAT
| OP_SUBSTR
| OP_LEFT
| OP_RIGHT
| OP_SIZE
| OP_INVERT
| OP_AND
| OP_OR
| OP_XOR
| OP_EQUAL
| OP_EQUALVERIFY
| OP_RESERVED1
| OP_RESERVED2
| 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
| OP_RIPEMD160
| OP_SHA1
| OP_SHA256
| OP_HASH160
| OP_HASH256
| OP_CODESEPARATOR
| OP_CHECKSIG
| OP_CHECKSIGVERIFY
| OP_CHECKMULTISIG
| OP_CHECKMULTISIGVERIFY
| OP_NOP1
| OP_CHECKLOCKTIMEVERIFY
| OP_CHECKSEQUENCEVERIFY
| OP_NOP4
| OP_NOP5
| OP_NOP6
| OP_NOP7
| OP_NOP8
| OP_NOP9
| OP_NOP10
| OP_CHECKDATASIG
| OP_CHECKDATASIGVERIFY
| OP_REVERSEBYTES
| OP_PUBKEYHASH
| OP_PUBKEY
| OP_INVALIDOPCODE !Word8
deriving (Int -> ScriptOp -> ShowS
[ScriptOp] -> ShowS
ScriptOp -> String
(Int -> ScriptOp -> ShowS)
-> (ScriptOp -> String) -> ([ScriptOp] -> ShowS) -> Show ScriptOp
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ScriptOp] -> ShowS
$cshowList :: [ScriptOp] -> ShowS
show :: ScriptOp -> String
$cshow :: ScriptOp -> String
showsPrec :: Int -> ScriptOp -> ShowS
$cshowsPrec :: Int -> ScriptOp -> ShowS
Show, ReadPrec [ScriptOp]
ReadPrec ScriptOp
Int -> ReadS ScriptOp
ReadS [ScriptOp]
(Int -> ReadS ScriptOp)
-> ReadS [ScriptOp]
-> ReadPrec ScriptOp
-> ReadPrec [ScriptOp]
-> Read ScriptOp
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [ScriptOp]
$creadListPrec :: ReadPrec [ScriptOp]
readPrec :: ReadPrec ScriptOp
$creadPrec :: ReadPrec ScriptOp
readList :: ReadS [ScriptOp]
$creadList :: ReadS [ScriptOp]
readsPrec :: Int -> ReadS ScriptOp
$creadsPrec :: Int -> ReadS ScriptOp
Read, ScriptOp -> ScriptOp -> Bool
(ScriptOp -> ScriptOp -> Bool)
-> (ScriptOp -> ScriptOp -> Bool) -> Eq ScriptOp
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ScriptOp -> ScriptOp -> Bool
$c/= :: ScriptOp -> ScriptOp -> Bool
== :: ScriptOp -> ScriptOp -> Bool
$c== :: ScriptOp -> ScriptOp -> Bool
Eq, (forall x. ScriptOp -> Rep ScriptOp x)
-> (forall x. Rep ScriptOp x -> ScriptOp) -> Generic ScriptOp
forall x. Rep ScriptOp x -> ScriptOp
forall x. ScriptOp -> Rep ScriptOp x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ScriptOp x -> ScriptOp
$cfrom :: forall x. ScriptOp -> Rep ScriptOp x
Generic, Int -> ScriptOp -> Int
ScriptOp -> Int
(Int -> ScriptOp -> Int) -> (ScriptOp -> Int) -> Hashable ScriptOp
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: ScriptOp -> Int
$chash :: ScriptOp -> Int
hashWithSalt :: Int -> ScriptOp -> Int
$chashWithSalt :: Int -> ScriptOp -> Int
Hashable, ScriptOp -> ()
(ScriptOp -> ()) -> NFData ScriptOp
forall a. (a -> ()) -> NFData a
rnf :: ScriptOp -> ()
$crnf :: ScriptOp -> ()
NFData)
instance Serial ScriptOp where
deserialize :: m ScriptOp
deserialize = Word8 -> m ScriptOp
forall (m :: * -> *). MonadGet m => Word8 -> m ScriptOp
go (Word8 -> m ScriptOp) -> m Word8 -> m ScriptOp
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< (Word8 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8 -> Word8) -> m Word8 -> m Word8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8)
where
go :: Word8 -> m ScriptOp
go op :: Word8
op
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x00 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_0
| Word8
op Word8 -> Word8 -> Bool
forall a. Ord a => a -> a -> Bool
<= 0x4b = do
ByteString
payload <- Int -> m ByteString
forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
op)
ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return (ScriptOp -> m ScriptOp) -> ScriptOp -> m ScriptOp
forall a b. (a -> b) -> a -> b
$ ByteString -> PushDataType -> ScriptOp
OP_PUSHDATA ByteString
payload PushDataType
OPCODE
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x4c = do
Word8
len <- m Word8
forall (m :: * -> *). MonadGet m => m Word8
getWord8
ByteString
payload <- Int -> m ByteString
forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString (Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word8
len)
ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return (ScriptOp -> m ScriptOp) -> ScriptOp -> m ScriptOp
forall a b. (a -> b) -> a -> b
$ ByteString -> PushDataType -> ScriptOp
OP_PUSHDATA ByteString
payload PushDataType
OPDATA1
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x4d = do
Word16
len <- m Word16
forall (m :: * -> *). MonadGet m => m Word16
getWord16le
ByteString
payload <- Int -> m ByteString
forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString (Word16 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word16
len)
ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return (ScriptOp -> m ScriptOp) -> ScriptOp -> m ScriptOp
forall a b. (a -> b) -> a -> b
$ ByteString -> PushDataType -> ScriptOp
OP_PUSHDATA ByteString
payload PushDataType
OPDATA2
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x4e = do
Word32
len <- m Word32
forall (m :: * -> *). MonadGet m => m Word32
getWord32le
ByteString
payload <- Int -> m ByteString
forall (m :: * -> *). MonadGet m => Int -> m ByteString
getByteString (Word32 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
len)
ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return (ScriptOp -> m ScriptOp) -> ScriptOp -> m ScriptOp
forall a b. (a -> b) -> a -> b
$ ByteString -> PushDataType -> ScriptOp
OP_PUSHDATA ByteString
payload PushDataType
OPDATA4
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x4f = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_1NEGATE
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x50 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_RESERVED
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x51 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_1
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x52 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_2
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x53 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_3
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x54 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_4
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x55 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_5
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x56 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_6
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x57 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_7
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x58 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_8
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x59 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_9
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x5a = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_10
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x5b = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_11
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x5c = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_12
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x5d = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_13
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x5e = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_14
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x5f = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_15
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x60 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_16
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x61 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x62 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_VER
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x63 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_IF
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x64 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOTIF
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x65 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_VERIF
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x66 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_VERNOTIF
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x67 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_ELSE
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x68 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_ENDIF
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x69 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_VERIFY
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x6a = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_RETURN
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x6b = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_TOALTSTACK
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x6c = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_FROMALTSTACK
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x6d = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_2DROP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x6e = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_2DUP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x6f = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_3DUP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x70 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_2OVER
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x71 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_2ROT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x72 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_2SWAP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x73 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_IFDUP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x74 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_DEPTH
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x75 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_DROP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x76 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_DUP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x77 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NIP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x78 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_OVER
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x79 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_PICK
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x7a = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_ROLL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x7b = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_ROT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x7c = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_SWAP
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x7d = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_TUCK
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x7e = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CAT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x7f = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_SUBSTR
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x80 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_LEFT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x81 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_RIGHT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x82 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_SIZE
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x83 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_INVERT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x84 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_AND
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x85 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_OR
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x86 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_XOR
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x87 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_EQUAL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x88 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_EQUALVERIFY
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x89 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_RESERVED1
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x8a = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_RESERVED2
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x8b = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_1ADD
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x8c = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_1SUB
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x8d = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_2MUL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x8e = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_2DIV
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x8f = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NEGATE
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x90 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_ABS
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x91 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x92 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_0NOTEQUAL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x93 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_ADD
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x94 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_SUB
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x95 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_MUL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x96 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_DIV
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x97 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_MOD
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x98 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_LSHIFT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x99 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_RSHIFT
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x9a = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_BOOLAND
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x9b = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_BOOLOR
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x9c = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NUMEQUAL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x9d = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NUMEQUALVERIFY
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x9e = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NUMNOTEQUAL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0x9f = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_LESSTHAN
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa0 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_GREATERTHAN
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa1 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_LESSTHANOREQUAL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa2 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_GREATERTHANOREQUAL
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa3 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_MIN
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa4 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_MAX
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa5 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_WITHIN
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa6 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_RIPEMD160
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa7 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_SHA1
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa8 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_SHA256
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xa9 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_HASH160
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xaa = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_HASH256
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xab = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CODESEPARATOR
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xac = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CHECKSIG
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xad = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CHECKSIGVERIFY
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xae = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CHECKMULTISIG
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xaf = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CHECKMULTISIGVERIFY
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb0 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP1
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb1 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CHECKLOCKTIMEVERIFY
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb2 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CHECKSEQUENCEVERIFY
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb3 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP4
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb4 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP5
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb5 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP6
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb6 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP7
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb7 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP8
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb8 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP9
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xb9 = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_NOP10
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xba = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CHECKDATASIG
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xbb = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_CHECKDATASIGVERIFY
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xbc = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_REVERSEBYTES
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xfd = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_PUBKEYHASH
| Word8
op Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== 0xfe = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return ScriptOp
OP_PUBKEY
| Bool
otherwise = ScriptOp -> m ScriptOp
forall (m :: * -> *) a. Monad m => a -> m a
return (ScriptOp -> m ScriptOp) -> ScriptOp -> m ScriptOp
forall a b. (a -> b) -> a -> b
$ Word8 -> ScriptOp
OP_INVALIDOPCODE Word8
op
serialize :: ScriptOp -> m ()
serialize op :: ScriptOp
op = case ScriptOp
op of
(OP_PUSHDATA payload :: ByteString
payload optype :: PushDataType
optype)-> do
let len :: Int
len = ByteString -> Int
B.length ByteString
payload
case PushDataType
optype of
OPCODE -> do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0x4b) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
String -> m ()
forall a. HasCallStack => String -> a
error "OP_PUSHDATA OPCODE: Payload size too big"
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 (Word8 -> m ()) -> Word8 -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
OPDATA1 -> do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0xff) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
String -> m ()
forall a. HasCallStack => String -> a
error "OP_PUSHDATA OPDATA1: Payload size too big"
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x4c
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 (Word8 -> m ()) -> Word8 -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
OPDATA2 -> do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0xffff) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
String -> m ()
forall a. HasCallStack => String -> a
error "OP_PUSHDATA OPDATA2: Payload size too big"
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x4d
Word16 -> m ()
forall (m :: * -> *). MonadPut m => Word16 -> m ()
putWord16le (Word16 -> m ()) -> Word16 -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> Word16
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
OPDATA4 -> do
Bool -> m () -> m ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0x7fffffff) (m () -> m ()) -> m () -> m ()
forall a b. (a -> b) -> a -> b
$
String -> m ()
forall a. HasCallStack => String -> a
error "OP_PUSHDATA OPDATA4: Payload size too big"
Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x4e
Word32 -> m ()
forall (m :: * -> *). MonadPut m => Word32 -> m ()
putWord32le (Word32 -> m ()) -> Word32 -> m ()
forall a b. (a -> b) -> a -> b
$ Int -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len
ByteString -> m ()
forall (m :: * -> *). MonadPut m => ByteString -> m ()
putByteString ByteString
payload
OP_0 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x00
OP_1NEGATE -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x4f
OP_RESERVED -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x50
OP_1 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x51
OP_2 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x52
OP_3 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x53
OP_4 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x54
OP_5 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x55
OP_6 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x56
OP_7 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x57
OP_8 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x58
OP_9 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x59
OP_10 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x5a
OP_11 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x5b
OP_12 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x5c
OP_13 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x5d
OP_14 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x5e
OP_15 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x5f
OP_16 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x60
OP_PUBKEY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xfe
OP_PUBKEYHASH -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xfd
(OP_INVALIDOPCODE x :: Word8
x) -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 Word8
x
OP_NOP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x61
OP_VER -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x62
OP_IF -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x63
OP_NOTIF -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x64
OP_VERIF -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x65
OP_VERNOTIF -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x66
OP_ELSE -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x67
OP_ENDIF -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x68
OP_VERIFY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x69
OP_RETURN -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x6a
OP_TOALTSTACK -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x6b
OP_FROMALTSTACK -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x6c
OP_2DROP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x6d
OP_2DUP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x6e
OP_3DUP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x6f
OP_2OVER -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x70
OP_2ROT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x71
OP_2SWAP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x72
OP_IFDUP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x73
OP_DEPTH -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x74
OP_DROP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x75
OP_DUP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x76
OP_NIP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x77
OP_OVER -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x78
OP_PICK -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x79
OP_ROLL -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x7a
OP_ROT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x7b
OP_SWAP -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x7c
OP_TUCK -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x7d
OP_CAT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x7e
OP_SUBSTR -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x7f
OP_LEFT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x80
OP_RIGHT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x81
OP_SIZE -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x82
OP_INVERT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x83
OP_AND -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x84
OP_OR -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x85
OP_XOR -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x86
OP_EQUAL -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x87
OP_EQUALVERIFY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x88
OP_RESERVED1 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x89
OP_RESERVED2 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x8a
OP_1ADD -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x8b
OP_1SUB -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x8c
OP_2MUL -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x8d
OP_2DIV -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x8e
OP_NEGATE -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x8f
OP_ABS -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x90
OP_NOT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x91
OP_0NOTEQUAL -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x92
OP_ADD -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x93
OP_SUB -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x94
OP_MUL -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x95
OP_DIV -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x96
OP_MOD -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x97
OP_LSHIFT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x98
OP_RSHIFT -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x99
OP_BOOLAND -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x9a
OP_BOOLOR -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x9b
OP_NUMEQUAL -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x9c
OP_NUMEQUALVERIFY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x9d
OP_NUMNOTEQUAL -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x9e
OP_LESSTHAN -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0x9f
OP_GREATERTHAN -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa0
OP_LESSTHANOREQUAL -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa1
OP_GREATERTHANOREQUAL-> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa2
OP_MIN -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa3
OP_MAX -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa4
OP_WITHIN -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa5
OP_RIPEMD160 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa6
OP_SHA1 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa7
OP_SHA256 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa8
OP_HASH160 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xa9
OP_HASH256 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xaa
OP_CODESEPARATOR -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xab
OP_CHECKSIG -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xac
OP_CHECKSIGVERIFY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xad
OP_CHECKMULTISIG -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xae
OP_CHECKMULTISIGVERIFY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xaf
OP_NOP1 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb0
OP_CHECKLOCKTIMEVERIFY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb1
OP_CHECKSEQUENCEVERIFY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb2
OP_NOP4 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb3
OP_NOP5 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb4
OP_NOP6 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb5
OP_NOP7 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb6
OP_NOP8 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb7
OP_NOP9 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb8
OP_NOP10 -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xb9
OP_CHECKDATASIG -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xba
OP_CHECKDATASIGVERIFY -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xbb
OP_REVERSEBYTES -> Word8 -> m ()
forall (m :: * -> *). MonadPut m => Word8 -> m ()
putWord8 0xbc
instance Binary ScriptOp where
put :: ScriptOp -> Put
put = ScriptOp -> Put
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
get :: Get ScriptOp
get = Get ScriptOp
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
instance Serialize ScriptOp where
put :: Putter ScriptOp
put = Putter ScriptOp
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize
get :: Get ScriptOp
get = Get ScriptOp
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize
isPushOp :: ScriptOp -> Bool
isPushOp :: ScriptOp -> Bool
isPushOp op :: ScriptOp
op = case ScriptOp
op of
OP_PUSHDATA _ _ -> Bool
True
OP_0 -> Bool
True
OP_1NEGATE -> Bool
True
OP_1 -> Bool
True
OP_2 -> Bool
True
OP_3 -> Bool
True
OP_4 -> Bool
True
OP_5 -> Bool
True
OP_6 -> Bool
True
OP_7 -> Bool
True
OP_8 -> Bool
True
OP_9 -> Bool
True
OP_10 -> Bool
True
OP_11 -> Bool
True
OP_12 -> Bool
True
OP_13 -> Bool
True
OP_14 -> Bool
True
OP_15 -> Bool
True
OP_16 -> Bool
True
_ -> Bool
False
opPushData :: ByteString -> ScriptOp
opPushData :: ByteString -> ScriptOp
opPushData bs :: ByteString
bs
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0x4b = ByteString -> PushDataType -> ScriptOp
OP_PUSHDATA ByteString
bs PushDataType
OPCODE
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0xff = ByteString -> PushDataType -> ScriptOp
OP_PUSHDATA ByteString
bs PushDataType
OPDATA1
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0xffff = ByteString -> PushDataType -> ScriptOp
OP_PUSHDATA ByteString
bs PushDataType
OPDATA2
| Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 0xffffffff = ByteString -> PushDataType -> ScriptOp
OP_PUSHDATA ByteString
bs PushDataType
OPDATA4
| Bool
otherwise = String -> ScriptOp
forall a. HasCallStack => String -> a
error "opPushData: payload size too big"
where
len :: Int
len = ByteString -> Int
B.length ByteString
bs
intToScriptOp :: Int -> ScriptOp
intToScriptOp :: Int -> ScriptOp
intToScriptOp i :: Int
i
| Int
i Int -> [Int] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [1 .. 16] = ScriptOp
op
| Bool
otherwise = ScriptOp
forall a. a
err
where
op :: ScriptOp
op = (String -> ScriptOp)
-> (ScriptOp -> ScriptOp) -> Either String ScriptOp -> ScriptOp
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either
(ScriptOp -> String -> ScriptOp
forall a b. a -> b -> a
const ScriptOp
forall a. a
err)
ScriptOp -> ScriptOp
forall a. a -> a
id (Either String ScriptOp -> ScriptOp)
-> (Int -> Either String ScriptOp) -> Int -> ScriptOp
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Get ScriptOp -> ByteString -> Either String ScriptOp
forall a. Get a -> ByteString -> Either String a
runGetS Get ScriptOp
forall a (m :: * -> *). (Serial a, MonadGet m) => m a
deserialize (ByteString -> Either String ScriptOp)
-> (Int -> ByteString) -> Int -> Either String ScriptOp
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Word8 -> ByteString
B.singleton (Word8 -> ByteString) -> (Int -> Word8) -> Int -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
Int -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> ScriptOp) -> Int -> ScriptOp
forall a b. (a -> b) -> a -> b
$
Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 0x50
err :: a
err = String -> a
forall a. HasCallStack => String -> a
error (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ "intToScriptOp: Invalid integer " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i
scriptOpToInt :: ScriptOp -> Either String Int
scriptOpToInt :: ScriptOp -> Either String Int
scriptOpToInt s :: ScriptOp
s
| Int
res Int -> [Int] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [1..16] = Int -> Either String Int
forall (m :: * -> *) a. Monad m => a -> m a
return Int
res
| Bool
otherwise = String -> Either String Int
forall a b. a -> Either a b
Left (String -> Either String Int) -> String -> Either String Int
forall a b. (a -> b) -> a -> b
$ "scriptOpToInt: invalid opcode " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ScriptOp -> String
forall a. Show a => a -> String
show ScriptOp
s
where
res :: Int
res = Word8 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (ByteString -> Word8
B.head (ByteString -> Word8) -> ByteString -> Word8
forall a b. (a -> b) -> a -> b
$ Put -> ByteString
runPutS (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ Putter ScriptOp
forall a (m :: * -> *). (Serial a, MonadPut m) => a -> m ()
serialize ScriptOp
s) Int -> Int -> Int
forall a. Num a => a -> a -> a
- 0x50