-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Developer tools for the Michelson Language -- -- A library to make writing smart contracts in Michelson — the smart -- contract language of the Tezos blockchain — pleasant and effective. @package morley @version 0.2.0 module Michelson.Printer.Util -- | Generalize converting a type into a Text.PrettyPrint.Leijen.Text.Doc. -- Used to pretty print Michelson code and define Fmt.Buildable -- instances. class RenderDoc a renderDoc :: RenderDoc a => a -> Doc -- | Whether a value can be represented in Michelson code. Normally either -- all values of some type are renderable or not renderable. However, in -- case of instructions we have extra instructions which should not be -- rendered. Note: it's not suficcient to just return mempty for -- such instructions, because sometimes we want to print lists of -- instructions and we need to ignore them complete (to avoid putting -- redundant separators). isRenderable :: RenderDoc a => a -> Bool -- | Convert Doc to Text with a line width of 80. printDoc :: Doc -> Text -- | Generic way to render the different op types that get passed to a -- contract. renderOps :: RenderDoc op => Bool -> NonEmpty op -> Doc renderOpsList :: RenderDoc op => Bool -> [op] -> Doc -- | Create a specific number of spaces. spaces :: Int -> Doc -- | Wrap documents in parentheses if there are two or more in the list. wrapInParens :: NonEmpty Doc -> Doc -- | Turn something that is instance of RenderDoc into a -- Builder. It's formatted the same way as printDoc formats -- docs. buildRenderDoc :: RenderDoc a => a -> Builder module Morley.Default permute2Def :: (Default a, Default b, Monad f, Alternative f) => f a -> f b -> f (a, b) permute3Def :: (Default a, Default b, Default c, Monad f, Alternative f) => f a -> f b -> f c -> f (a, b, c) -- | A class for types with a default value. class Default a -- | The default value for this type. def :: Default a => a module Morley.Parser.Helpers sepEndBy1 :: MonadPlus m => m a -> m sep -> m (NonEmpty a) -- | Testing utility functions used by testing framework itself or intended -- to be used by test writers. module Morley.Test.Util -- | A Property that always failes with given message. failedProp :: Text -> Property -- | A Property that always succeeds. succeededProp :: Property -- | The Property holds on `Left a`. qcIsLeft :: Show b => Either a b -> Property -- | The Property holds on `Right b`. qcIsRight :: Show a => Either a b -> Property -- | Core primitive Tezos types. module Tezos.Core -- | Mutez is a wrapper over integer data type. 1 mutez is 1 token (μTz). data Mutez -- | Safely create Mutez checking for overflow. mkMutez :: Word64 -> Maybe Mutez -- | Partial function for Mutez creation, it's pre-condition is that -- the argument must not exceed the maximal Mutez value. unsafeMkMutez :: HasCallStack => Word64 -> Mutez -- | Addition of Mutez values. Returns Nothing in case of -- overflow. addMutez :: Mutez -> Mutez -> Maybe Mutez -- | Partial addition of Mutez, should be used only if you're sure -- there'll be no overflow. unsafeAddMutez :: HasCallStack => Mutez -> Mutez -> Mutez -- | Subtraction of Mutez values. Returns Nothing when the -- subtrahend is greater than the minuend, and Just otherwise. subMutez :: Mutez -> Mutez -> Maybe Mutez -- | Partial subtraction of Mutez, should be used only if you're -- sure there'll be no underflow. unsafeSubMutez :: HasCallStack => Mutez -> Mutez -> Mutez -- | Multiplication of Mutez and an integral number. Returns -- Nothing in case of overflow. mulMutez :: Integral a => Mutez -> a -> Maybe Mutez -- | Euclidian division of two Mutez values. divModMutez :: Mutez -> Mutez -> Maybe (Word64, Mutez) -- | Euclidian division of Mutez and a number. divModMutezInt :: Integral a => Mutez -> a -> Maybe (Mutez, Mutez) -- | Time in the real world. Use the functions below to convert it to/from -- Unix time in seconds. newtype Timestamp Timestamp :: POSIXTime -> Timestamp [unTimestamp] :: Timestamp -> POSIXTime timestampToSeconds :: Integral a => Timestamp -> a timestampFromSeconds :: Integral a => a -> Timestamp timestampFromUTCTime :: UTCTime -> Timestamp -- | Add given amount of seconds to a Timestamp. timestampPlusSeconds :: Timestamp -> Integer -> Timestamp -- | Display timestamp in human-readable way as used by Michelson. Uses UTC -- timezone, though maybe we should take it as an argument. formatTimestamp :: Timestamp -> Text -- | Parse textual representation of Timestamp. parseTimestamp :: Text -> Maybe Timestamp -- | Return current time as Timestamp. getCurrentTime :: IO Timestamp instance Data.Aeson.Types.ToJSON.ToJSON Tezos.Core.Timestamp instance Data.Aeson.Types.FromJSON.FromJSON Tezos.Core.Timestamp instance Data.Aeson.Types.ToJSON.ToJSON Tezos.Core.Mutez instance Data.Aeson.Types.FromJSON.FromJSON Tezos.Core.Mutez instance GHC.Generics.Generic Tezos.Core.Timestamp instance Data.Data.Data Tezos.Core.Timestamp instance GHC.Classes.Ord Tezos.Core.Timestamp instance GHC.Classes.Eq Tezos.Core.Timestamp instance GHC.Show.Show Tezos.Core.Timestamp instance Formatting.Buildable.Buildable Tezos.Core.Mutez instance GHC.Enum.Enum Tezos.Core.Mutez instance GHC.Generics.Generic Tezos.Core.Mutez instance Data.Data.Data Tezos.Core.Mutez instance GHC.Classes.Ord Tezos.Core.Mutez instance GHC.Classes.Eq Tezos.Core.Mutez instance GHC.Show.Show Tezos.Core.Mutez instance Formatting.Buildable.Buildable Tezos.Core.Timestamp instance GHC.Enum.Bounded Tezos.Core.Mutez -- | Cryptographic primitives used in Tezos. module Tezos.Crypto -- | ED25519 public cryptographic key. data PublicKey -- | ED25519 secret cryptographic key. data SecretKey -- | ED25519 cryptographic signature. data Signature -- | b58check of a public key. newtype KeyHash KeyHash :: ByteString -> KeyHash [unKeyHash] :: KeyHash -> ByteString -- | Create a public key from a secret key. toPublic :: SecretKey -> PublicKey -- | Error that can happen during parsing of cryptographic primitive types. data CryptoParseError CryptoParseWrongBase58Check :: CryptoParseError CryptoParseWrongTag :: !ByteString -> CryptoParseError CryptoParseCryptoError :: CryptoError -> CryptoParseError formatPublicKey :: PublicKey -> Text parsePublicKey :: Text -> Either CryptoParseError PublicKey formatSecretKey :: SecretKey -> Text parseSecretKey :: Text -> Either CryptoParseError SecretKey formatSignature :: Signature -> Text parseSignature :: Text -> Either CryptoParseError Signature formatKeyHash :: KeyHash -> Text parseKeyHash :: Text -> Either CryptoParseError KeyHash -- | Sign a message using the secret key. sign :: SecretKey -> ByteString -> Signature -- | Check that a sequence of bytes has been signed with a given key. checkSignature :: PublicKey -> Signature -> ByteString -> Bool -- | Compute the b58check of a public key hash. hashKey :: PublicKey -> KeyHash -- | Compute a cryptographic hash of a bytestring using the Blake2b_256 -- cryptographic hash function. It's used by the BLAKE2B instruction in -- Michelson. blake2b :: ByteString -> ByteString -- | Compute a cryptographic hash of a bytestring using the Blake2b_160 -- cryptographic hash function. blake2b160 :: ByteString -> ByteString -- | Compute a cryptographic hash of a bytestring using the Sha256 -- cryptographic hash function. sha256 :: ByteString -> ByteString -- | Compute a cryptographic hash of a bytestring using the Sha512 -- cryptographic hash function. sha512 :: ByteString -> ByteString -- | Encode a bytestring in Base58Check format. encodeBase58Check :: ByteString -> Text -- | Decode a bytestring from Base58Check format. decodeBase58Check :: Text -> Maybe ByteString data B58CheckWithPrefixError B58CheckWithPrefixWrongPrefix :: ByteString -> B58CheckWithPrefixError B58CheckWithPrefixWrongEncoding :: B58CheckWithPrefixError -- | Parse a base58check encoded value expecting some prefix. If the actual -- prefix matches the expected one, it's stripped of and the resulting -- payload is returned. decodeBase58CheckWithPrefix :: ByteString -> Text -> Either B58CheckWithPrefixError ByteString instance GHC.Show.Show Tezos.Crypto.B58CheckWithPrefixError instance GHC.Classes.Eq Tezos.Crypto.CryptoParseError instance GHC.Show.Show Tezos.Crypto.CryptoParseError instance GHC.Classes.Ord Tezos.Crypto.KeyHash instance GHC.Classes.Eq Tezos.Crypto.KeyHash instance GHC.Show.Show Tezos.Crypto.KeyHash instance GHC.Classes.Eq Tezos.Crypto.Signature instance GHC.Show.Show Tezos.Crypto.Signature instance GHC.Classes.Eq Tezos.Crypto.SecretKey instance GHC.Show.Show Tezos.Crypto.SecretKey instance GHC.Classes.Eq Tezos.Crypto.PublicKey instance GHC.Show.Show Tezos.Crypto.PublicKey instance Formatting.Buildable.Buildable Tezos.Crypto.CryptoParseError instance Test.QuickCheck.Arbitrary.Arbitrary Tezos.Crypto.KeyHash instance Formatting.Buildable.Buildable Tezos.Crypto.KeyHash instance Data.Aeson.Types.ToJSON.ToJSON Tezos.Crypto.KeyHash instance Data.Aeson.Types.FromJSON.FromJSON Tezos.Crypto.KeyHash instance Test.QuickCheck.Arbitrary.Arbitrary Tezos.Crypto.Signature instance Formatting.Buildable.Buildable Tezos.Crypto.Signature instance Data.Aeson.Types.ToJSON.ToJSON Tezos.Crypto.Signature instance Data.Aeson.Types.FromJSON.FromJSON Tezos.Crypto.Signature instance Test.QuickCheck.Arbitrary.Arbitrary Tezos.Crypto.SecretKey instance Formatting.Buildable.Buildable Tezos.Crypto.SecretKey instance Test.QuickCheck.Arbitrary.Arbitrary Tezos.Crypto.PublicKey instance Formatting.Buildable.Buildable Tezos.Crypto.PublicKey instance Data.Aeson.Types.ToJSON.ToJSON Tezos.Crypto.PublicKey instance Data.Aeson.Types.FromJSON.FromJSON Tezos.Crypto.PublicKey -- | Address in Tezos. module Tezos.Address -- | Data type corresponding to address structure in Tezos. data Address -- | tz address which is a hash of a public key. KeyAddress :: !KeyHash -> Address -- | KT address which corresponds to a callable contract. It's a -- hash of origination command. TODO: we should probably have a -- Hash type. ContractAddress :: !ByteString -> Address -- | Smart constructor for KeyAddress. mkKeyAddress :: PublicKey -> Address -- | Smart constructor for ContractAddress. Its argument is -- serialized origination operation. -- -- Note: it's quite unsafe to pass ByteString, because we can pass -- some garbage which is not a serialized origination operation, but this -- operation includes contract itself and necessary types are defined in -- *. So we have to serialize this data outside this module and -- pass it here as a ByteString. Alternatively we could add some -- constraint, but it would be almost as unsafe as passing a -- ByteString. For this reason we add Raw suffix to this -- function and provide a safer function in Instr. We may -- reconsider it later. mkContractAddressRaw :: ByteString -> Address formatAddress :: Address -> Text -- | Parse an address from its human-readable textual representation used -- by Tezos (e. g. "tz1faswCTDciRzE4oJ9jn2Vm2dvjeyA9fUzU"). Or fail if -- it's invalid. parseAddress :: Text -> Either ParseAddressError Address -- | Partial version of parseAddress which assumes that the address -- is correct. Can be used in tests. unsafeParseAddress :: HasCallStack => Text -> Address instance GHC.Classes.Eq Tezos.Address.ParseAddressError instance GHC.Show.Show Tezos.Address.ParseAddressError instance GHC.Classes.Eq Tezos.Address.ParseContractAddressError instance GHC.Show.Show Tezos.Address.ParseContractAddressError instance GHC.Classes.Ord Tezos.Address.Address instance GHC.Classes.Eq Tezos.Address.Address instance GHC.Show.Show Tezos.Address.Address instance Formatting.Buildable.Buildable Tezos.Address.ParseAddressError instance Formatting.Buildable.Buildable Tezos.Address.ParseContractAddressError instance Formatting.Buildable.Buildable Tezos.Address.Address instance Data.Aeson.Types.ToJSON.ToJSON Tezos.Address.Address instance Data.Aeson.Types.ToJSON.ToJSONKey Tezos.Address.Address instance Data.Aeson.Types.FromJSON.FromJSON Tezos.Address.Address instance Data.Aeson.Types.FromJSON.FromJSONKey Tezos.Address.Address instance Test.QuickCheck.Arbitrary.Arbitrary Tezos.Address.Address module Michelson.Untyped data Value op ValueInt :: Integer -> Value op ValueString :: Text -> Value op ValueBytes :: InternalByteString -> Value op ValueUnit :: Value op ValueTrue :: Value op ValueFalse :: Value op ValuePair :: Value op -> Value op -> Value op ValueLeft :: Value op -> Value op ValueRight :: Value op -> Value op ValueSome :: Value op -> Value op ValueNone :: Value op ValueNil :: Value op -- | A sequence of elements: can be a list or a set. We can't distinguish -- lists and sets during parsing. ValueSeq :: (NonEmpty $ Value op) -> Value op ValueMap :: (NonEmpty $ Elt op) -> Value op ValueLambda :: NonEmpty op -> Value op data Elt op Elt :: Value op -> Value op -> Elt op -- | ByteString does not have an instance for ToJSON and FromJSON, to avoid -- orphan type class instances, make a new type wrapper around it. newtype InternalByteString InternalByteString :: ByteString -> InternalByteString unInternalByteString :: InternalByteString -> ByteString data Type Type :: T -> TypeAnn -> Type data Comparable Comparable :: CT -> TypeAnn -> Comparable compToType :: Comparable -> Type typeToComp :: Type -> Maybe Comparable data T Tc :: CT -> T TKey :: T TUnit :: T TSignature :: T TOption :: FieldAnn -> Type -> T TList :: Type -> T TSet :: Comparable -> T TOperation :: T TContract :: Type -> T TPair :: FieldAnn -> FieldAnn -> Type -> Type -> T TOr :: FieldAnn -> FieldAnn -> Type -> Type -> T TLambda :: Type -> Type -> T TMap :: Comparable -> Type -> T TBigMap :: Comparable -> Type -> T data CT CInt :: CT CNat :: CT CString :: CT CBytes :: CT CMutez :: CT CBool :: CT CKeyHash :: CT CTimestamp :: CT CAddress :: CT -- | Type function that converts a regular Haskell type into a comparable -- type (which has kind CT) type family ToCT a :: CT pattern Tint :: T pattern Tnat :: T pattern Tstring :: T pattern Tbytes :: T pattern Tmutez :: T pattern Tbool :: T pattern Tkey_hash :: T pattern Ttimestamp :: T pattern Taddress :: T tint :: T tnat :: T tstring :: T tbytes :: T tmutez :: T tbool :: T tkeyHash :: T ttimestamp :: T taddress :: T isAtomicType :: Type -> Bool isKey :: Type -> Bool isSignature :: Type -> Bool isComparable :: Type -> Bool isMutez :: Type -> Bool isKeyHash :: Type -> Bool isBool :: Type -> Bool isString :: Type -> Bool isInteger :: Type -> Bool isTimestamp :: Type -> Bool isNat :: Type -> Bool isInt :: Type -> Bool isBytes :: Type -> Bool -- | Michelson instruction with abstract parameter op. This -- parameter is necessary, because at different stages of our pipeline it -- will be different. Initially it can contain macros and non-flattened -- instructions, but then it contains only vanilla Michelson -- instructions. data InstrAbstract op EXT :: ExtU InstrAbstract op -> InstrAbstract op DROP :: InstrAbstract op DUP :: VarAnn -> InstrAbstract op SWAP :: InstrAbstract op PUSH :: VarAnn -> Type -> Value op -> InstrAbstract op SOME :: TypeAnn -> VarAnn -> FieldAnn -> InstrAbstract op NONE :: TypeAnn -> VarAnn -> FieldAnn -> Type -> InstrAbstract op UNIT :: TypeAnn -> VarAnn -> InstrAbstract op IF_NONE :: [op] -> [op] -> InstrAbstract op PAIR :: TypeAnn -> VarAnn -> FieldAnn -> FieldAnn -> InstrAbstract op CAR :: VarAnn -> FieldAnn -> InstrAbstract op CDR :: VarAnn -> FieldAnn -> InstrAbstract op LEFT :: TypeAnn -> VarAnn -> FieldAnn -> FieldAnn -> Type -> InstrAbstract op RIGHT :: TypeAnn -> VarAnn -> FieldAnn -> FieldAnn -> Type -> InstrAbstract op IF_LEFT :: [op] -> [op] -> InstrAbstract op IF_RIGHT :: [op] -> [op] -> InstrAbstract op NIL :: TypeAnn -> VarAnn -> Type -> InstrAbstract op CONS :: VarAnn -> InstrAbstract op IF_CONS :: [op] -> [op] -> InstrAbstract op SIZE :: VarAnn -> InstrAbstract op EMPTY_SET :: TypeAnn -> VarAnn -> Comparable -> InstrAbstract op EMPTY_MAP :: TypeAnn -> VarAnn -> Comparable -> Type -> InstrAbstract op MAP :: VarAnn -> [op] -> InstrAbstract op ITER :: [op] -> InstrAbstract op MEM :: VarAnn -> InstrAbstract op GET :: VarAnn -> InstrAbstract op UPDATE :: InstrAbstract op IF :: [op] -> [op] -> InstrAbstract op LOOP :: [op] -> InstrAbstract op LOOP_LEFT :: [op] -> InstrAbstract op LAMBDA :: VarAnn -> Type -> Type -> [op] -> InstrAbstract op EXEC :: VarAnn -> InstrAbstract op DIP :: [op] -> InstrAbstract op FAILWITH :: InstrAbstract op CAST :: VarAnn -> Type -> InstrAbstract op RENAME :: VarAnn -> InstrAbstract op PACK :: VarAnn -> InstrAbstract op UNPACK :: VarAnn -> Type -> InstrAbstract op CONCAT :: VarAnn -> InstrAbstract op SLICE :: VarAnn -> InstrAbstract op ISNAT :: VarAnn -> InstrAbstract op ADD :: VarAnn -> InstrAbstract op SUB :: VarAnn -> InstrAbstract op MUL :: VarAnn -> InstrAbstract op EDIV :: VarAnn -> InstrAbstract op ABS :: VarAnn -> InstrAbstract op NEG :: InstrAbstract op LSL :: VarAnn -> InstrAbstract op LSR :: VarAnn -> InstrAbstract op OR :: VarAnn -> InstrAbstract op AND :: VarAnn -> InstrAbstract op XOR :: VarAnn -> InstrAbstract op NOT :: VarAnn -> InstrAbstract op COMPARE :: VarAnn -> InstrAbstract op EQ :: VarAnn -> InstrAbstract op NEQ :: VarAnn -> InstrAbstract op LT :: VarAnn -> InstrAbstract op GT :: VarAnn -> InstrAbstract op LE :: VarAnn -> InstrAbstract op GE :: VarAnn -> InstrAbstract op INT :: VarAnn -> InstrAbstract op SELF :: VarAnn -> InstrAbstract op CONTRACT :: VarAnn -> Type -> InstrAbstract op TRANSFER_TOKENS :: VarAnn -> InstrAbstract op SET_DELEGATE :: VarAnn -> InstrAbstract op CREATE_ACCOUNT :: VarAnn -> VarAnn -> InstrAbstract op CREATE_CONTRACT :: VarAnn -> VarAnn -> InstrAbstract op CREATE_CONTRACT2 :: VarAnn -> VarAnn -> Contract op -> InstrAbstract op IMPLICIT_ACCOUNT :: VarAnn -> InstrAbstract op NOW :: VarAnn -> InstrAbstract op AMOUNT :: VarAnn -> InstrAbstract op BALANCE :: VarAnn -> InstrAbstract op CHECK_SIGNATURE :: VarAnn -> InstrAbstract op SHA256 :: VarAnn -> InstrAbstract op SHA512 :: VarAnn -> InstrAbstract op BLAKE2B :: VarAnn -> InstrAbstract op HASH_KEY :: VarAnn -> InstrAbstract op STEPS_TO_QUOTA :: VarAnn -> InstrAbstract op SOURCE :: VarAnn -> InstrAbstract op SENDER :: VarAnn -> InstrAbstract op ADDRESS :: VarAnn -> InstrAbstract op newtype Op Op :: Instr -> Op [unOp] :: Op -> Instr type Instr = InstrAbstract Op data ExpandedOp PrimEx :: ExpandedInstr -> ExpandedOp SeqEx :: [ExpandedOp] -> ExpandedOp type ExpandedInstr = InstrAbstract ExpandedOp -- | ExtU is extension of InstrAbstract by Morley instructions type family ExtU (instr :: Type -> Type) :: Type -> Type type InstrExtU = ExtU InstrAbstract Op type ExpandedInstrExtU = ExtU InstrAbstract ExpandedOp -- | Data necessary to originate a contract. data OriginationOperation OriginationOperation :: !KeyHash -> !Maybe KeyHash -> !Bool -> !Bool -> !Mutez -> !Value ExpandedOp -> !Contract ExpandedOp -> OriginationOperation -- | Manager of the contract. [ooManager] :: OriginationOperation -> !KeyHash -- | Optional delegate. [ooDelegate] :: OriginationOperation -> !Maybe KeyHash -- | Whether the contract is spendable. [ooSpendable] :: OriginationOperation -> !Bool -- | Whether the contract is delegatable. [ooDelegatable] :: OriginationOperation -> !Bool -- | Initial balance of the contract. [ooBalance] :: OriginationOperation -> !Mutez -- | Initial storage value of the contract. [ooStorage] :: OriginationOperation -> !Value ExpandedOp -- | The contract itself. [ooContract] :: OriginationOperation -> !Contract ExpandedOp -- | Compute address of a contract from its origination operation. -- -- TODO [TM-62] It's certainly imprecise, real Tezos implementation -- doesn't use JSON, but we don't need precise format yet, so we just use -- some serialization format (JSON because we have necessary instances -- already). mkContractAddress :: ToJSON ExpandedInstrExtU => OriginationOperation -> Address type Parameter = Type type Storage = Type data Contract op Contract :: Parameter -> Storage -> [op] -> Contract op [para] :: Contract op -> Parameter [stor] :: Contract op -> Storage [code] :: Contract op -> [op] newtype Annotation tag Annotation :: Text -> Annotation tag pattern WithAnn :: Annotation tag -> Annotation tag type TypeAnn = Annotation TypeTag type FieldAnn = Annotation FieldTag type VarAnn = Annotation VarTag noAnn :: Annotation a ann :: Text -> Annotation a unifyAnn :: Annotation tag -> Annotation tag -> Maybe (Annotation tag) ifAnnUnified :: Annotation tag -> Annotation tag -> Bool disjoinVn :: VarAnn -> (VarAnn, VarAnn) convAnn :: Annotation tag1 -> Annotation tag2 type UntypedContract = Contract ExpandedOp type UntypedValue = Value ExpandedOp module Michelson.Printer -- | Generalize converting a type into a Text.PrettyPrint.Leijen.Text.Doc. -- Used to pretty print Michelson code and define Fmt.Buildable -- instances. class RenderDoc a renderDoc :: RenderDoc a => a -> Doc -- | Whether a value can be represented in Michelson code. Normally either -- all values of some type are renderable or not renderable. However, in -- case of instructions we have extra instructions which should not be -- rendered. Note: it's not suficcient to just return mempty for -- such instructions, because sometimes we want to print lists of -- instructions and we need to ignore them complete (to avoid putting -- redundant separators). isRenderable :: RenderDoc a => a -> Bool -- | Convert Doc to Text with a line width of 80. printDoc :: Doc -> Text -- | Convert an untyped contract into a textual representation which will -- be accepted by the OCaml reference client. printUntypedContract :: RenderDoc op => Contract op -> Text -- | Module, containing data types for Michelson value. module Michelson.Typed.Value -- | Representation of Michelson value. -- -- Type parameter instr stands for Michelson instruction type, -- i.e. data type to represent an instruction of language. data Val instr t [VC] :: CVal t -> Val instr ( 'Tc t) [VKey] :: PublicKey -> Val instr 'TKey [VUnit] :: Val instr 'TUnit [VSignature] :: Signature -> Val instr 'TSignature [VOption] :: Maybe (Val instr t) -> Val instr ( 'TOption t) [VList] :: [Val instr t] -> Val instr ( 'TList t) [VSet] :: Set (CVal t) -> Val instr ( 'TSet t) [VOp] :: Operation instr -> Val instr 'TOperation [VContract] :: Address -> Val instr ( 'TContract p) [VPair] :: (Val instr l, Val instr r) -> Val instr ( 'TPair l r) [VOr] :: Either (Val instr l) (Val instr r) -> Val instr ( 'TOr l r) [VLam] :: (Show (instr '[inp] '[out]), Eq (instr '[inp] '[out])) => instr (inp : '[]) (out : '[]) -> Val instr ( 'TLambda inp out) [VMap] :: Map (CVal k) (Val instr v) -> Val instr ( 'TMap k v) [VBigMap] :: Map (CVal k) (Val instr v) -> Val instr ( 'TBigMap k v) type ContractInp param st = '[ 'TPair param st] type ContractOut st = '[ 'TPair ( 'TList 'TOperation) st] data CreateAccount CreateAccount :: !KeyHash -> !Maybe KeyHash -> !Bool -> !Mutez -> CreateAccount [caManager] :: CreateAccount -> !KeyHash [caDelegate] :: CreateAccount -> !Maybe KeyHash [caSpendable] :: CreateAccount -> !Bool [caBalance] :: CreateAccount -> !Mutez data CreateContract instr t cp st CreateContract :: !KeyHash -> !Maybe KeyHash -> !Bool -> !Bool -> !Mutez -> !Val instr t -> !instr (ContractInp cp st) (ContractOut st) -> CreateContract instr t cp st [ccManager] :: CreateContract instr t cp st -> !KeyHash [ccDelegate] :: CreateContract instr t cp st -> !Maybe KeyHash [ccSpendable] :: CreateContract instr t cp st -> !Bool [ccDelegatable] :: CreateContract instr t cp st -> !Bool [ccBalance] :: CreateContract instr t cp st -> !Mutez [ccStorageVal] :: CreateContract instr t cp st -> !Val instr t [ccContractCode] :: CreateContract instr t cp st -> !instr (ContractInp cp st) (ContractOut st) -- | Representation of comparable value in Michelson language. -- -- By specification, we're allowed to compare only following types: int, -- nat, string, bytes, mutez, bool, key_hash, timestamp, address. -- -- Only these values can be used as map keys or set elements. data CVal t [CvInt] :: Integer -> CVal 'CInt [CvNat] :: Natural -> CVal 'CNat [CvString] :: Text -> CVal 'CString [CvBytes] :: ByteString -> CVal 'CBytes [CvMutez] :: Mutez -> CVal 'CMutez [CvBool] :: Bool -> CVal 'CBool [CvKeyHash] :: KeyHash -> CVal 'CKeyHash [CvTimestamp] :: Timestamp -> CVal 'CTimestamp [CvAddress] :: Address -> CVal 'CAddress -- | Data type, representing operation, list of which is returned by -- Michelson contract (according to calling convention). -- -- These operations are to be further executed against system state after -- the contract execution. data Operation instr [OpTransferTokens] :: Typeable p => TransferTokens instr p -> Operation instr [OpSetDelegate] :: SetDelegate -> Operation instr [OpCreateAccount] :: CreateAccount -> Operation instr [OpCreateContract] :: (Show (instr (ContractInp cp st) (ContractOut st)), SingI cp, SingI st, Typeable t, Typeable cp, Typeable st) => CreateContract instr t cp st -> Operation instr data SetDelegate SetDelegate :: !Maybe KeyHash -> SetDelegate [sdMbKeyHash] :: SetDelegate -> !Maybe KeyHash data TransferTokens instr p TransferTokens :: !Val instr p -> !Mutez -> !Val instr ( 'TContract p) -> TransferTokens instr p [ttContractParameter] :: TransferTokens instr p -> !Val instr p [ttAmount] :: TransferTokens instr p -> !Mutez [ttContract] :: TransferTokens instr p -> !Val instr ( 'TContract p) -- | Converts a complex Haskell structure into Val representation. class ToVal a -- | Converts a Val value into complex Haskell type. class FromVal t toVal :: ToVal a => a -> Val instr (ToT a) fromVal :: FromVal t => Val instr (ToT t) -> t instance GHC.Classes.Eq (Michelson.Typed.Value.TransferTokens instr p) instance GHC.Show.Show (Michelson.Typed.Value.TransferTokens instr p) instance GHC.Classes.Eq Michelson.Typed.Value.CreateAccount instance GHC.Show.Show Michelson.Typed.Value.CreateAccount instance GHC.Classes.Eq Michelson.Typed.Value.SetDelegate instance GHC.Show.Show Michelson.Typed.Value.SetDelegate instance GHC.Show.Show (Michelson.Typed.Value.Operation instr) instance GHC.Show.Show (Michelson.Typed.Value.CreateContract instr t cp st) instance GHC.Classes.Eq (Michelson.Typed.Value.CreateContract instr t cp st) instance GHC.Show.Show (Michelson.Typed.Value.Val instr t) instance GHC.Classes.Eq (Michelson.Typed.Value.Val instr t) instance Michelson.Typed.Value.FromVal GHC.Integer.Type.Integer instance Michelson.Typed.Value.FromVal GHC.Natural.Natural instance Michelson.Typed.Value.FromVal Data.Text.Internal.Text instance Michelson.Typed.Value.FromVal GHC.Types.Bool instance Michelson.Typed.Value.FromVal Data.ByteString.Internal.ByteString instance Michelson.Typed.Value.FromVal Tezos.Core.Mutez instance Michelson.Typed.Value.FromVal Tezos.Crypto.KeyHash instance Michelson.Typed.Value.FromVal Tezos.Core.Timestamp instance Michelson.Typed.Value.FromVal Tezos.Address.Address instance Michelson.Typed.Value.FromVal () instance Michelson.Typed.Value.FromVal a => Michelson.Typed.Value.FromVal [a] instance Michelson.Typed.Value.FromVal a => Michelson.Typed.Value.FromVal (GHC.Maybe.Maybe a) instance (Michelson.Typed.Value.FromVal a, Michelson.Typed.Value.FromVal b) => Michelson.Typed.Value.FromVal (Data.Either.Either a b) instance (Michelson.Typed.Value.FromVal a, Michelson.Typed.Value.FromVal b) => Michelson.Typed.Value.FromVal (a, b) instance (GHC.Classes.Ord k, Michelson.Typed.CValue.FromCVal k) => Michelson.Typed.Value.FromVal (Data.Set.Internal.Set k) instance (GHC.Classes.Ord k, Michelson.Typed.CValue.FromCVal k, Michelson.Typed.Value.FromVal a) => Michelson.Typed.Value.FromVal (Data.Map.Internal.Map k a) instance Michelson.Typed.Value.ToVal () instance Michelson.Typed.Value.ToVal GHC.Integer.Type.Integer instance Michelson.Typed.Value.ToVal GHC.Types.Int instance Michelson.Typed.Value.ToVal GHC.Word.Word64 instance Michelson.Typed.Value.ToVal GHC.Natural.Natural instance Michelson.Typed.Value.ToVal Data.Text.Internal.Text instance Michelson.Typed.Value.ToVal Data.ByteString.Internal.ByteString instance Michelson.Typed.Value.ToVal GHC.Types.Bool instance Michelson.Typed.Value.ToVal Tezos.Core.Mutez instance Michelson.Typed.Value.ToVal Tezos.Crypto.KeyHash instance Michelson.Typed.Value.ToVal Tezos.Core.Timestamp instance Michelson.Typed.Value.ToVal Tezos.Address.Address instance Michelson.Typed.Value.ToVal a => Michelson.Typed.Value.ToVal (GHC.Maybe.Maybe a) instance (Michelson.Typed.Value.ToVal a, Michelson.Typed.Value.ToVal b) => Michelson.Typed.Value.ToVal (Data.Either.Either a b) instance (Michelson.Typed.Value.ToVal a, Michelson.Typed.Value.ToVal b) => Michelson.Typed.Value.ToVal (a, b) instance Michelson.Typed.Value.ToVal x => Michelson.Typed.Value.ToVal [x] instance Michelson.Typed.CValue.ToCVal k => Michelson.Typed.Value.ToVal (Data.Set.Internal.Set k) instance (Michelson.Typed.CValue.ToCVal k, Michelson.Typed.Value.ToVal a) => Michelson.Typed.Value.ToVal (Data.Map.Internal.Map k a) instance Formatting.Buildable.Buildable (Michelson.Typed.Value.Operation instr) instance GHC.Classes.Eq (Michelson.Typed.Value.Operation instr) instance Formatting.Buildable.Buildable (Michelson.Typed.Value.TransferTokens instr p) instance Formatting.Buildable.Buildable (Michelson.Typed.Value.CreateContract instr t cp st) instance Formatting.Buildable.Buildable Michelson.Typed.Value.CreateAccount instance Formatting.Buildable.Buildable Michelson.Typed.Value.SetDelegate module Michelson.Typed data CT CInt :: CT CNat :: CT CString :: CT CBytes :: CT CMutez :: CT CBool :: CT CKeyHash :: CT CTimestamp :: CT CAddress :: CT -- | Michelson language type with annotations stripped off. data T Tc :: CT -> T TKey :: T TUnit :: T TSignature :: T TOption :: T -> T TList :: T -> T TSet :: CT -> T TOperation :: T TContract :: T -> T TPair :: T -> T -> T TOr :: T -> T -> T TLambda :: T -> T -> T TMap :: CT -> T -> T TBigMap :: CT -> T -> T -- | Type function that converts a regular Haskell type into a comparable -- type (which has kind CT) type family ToCT a :: CT -- | Type function that converts a regular Haskell type into a T -- type. TODO: what should be done with TBigMap? type family ToT t :: T -- | The singleton kind-indexed data family. data family Sing (a :: k) :: Type -- | Version of withSomeSing with Typeable constraint -- provided to processing function. -- -- Required for not to erase these useful constraints when doing -- conversion from value of type T to its singleton -- representation. withSomeSingT :: T -> (forall (a :: T). (Typeable a, SingI a) => Sing a -> r) -> r -- | Version of withSomeSing with Typeable constraint -- provided to processing function. -- -- Required for not to erase this useful constraint when doing conversion -- from value of type CT to its singleton representation. withSomeSingCT :: CT -> (forall (a :: CT). (SingI a, Typeable a) => Sing a -> r) -> r -- | Version of fromSing specialized for use with data -- instance Sing :: T -> Type which requires Typeable -- constraint for some of its constructors fromSingT :: Sing (a :: T) -> T fromSingCT :: Sing (a :: CT) -> CT class EDivOp (n :: CT) (m :: CT) where { type family EDivOpRes n m :: CT; type family EModOpRes n m :: CT; } evalEDivOp :: EDivOp n m => CVal n -> CVal m -> Val instr ( 'TOption ( 'TPair ( 'Tc (EDivOpRes n m)) ( 'Tc (EModOpRes n m)))) class MemOp (c :: T) where { type family MemOpKey c :: CT; } evalMem :: MemOp c => CVal (MemOpKey c) -> Val cp c -> Bool class MapOp (c :: T) (b :: T) where { type family MapOpInp c :: T; type family MapOpRes c b :: T; } mapOpToList :: MapOp c b => Val instr c -> [Val instr (MapOpInp c)] mapOpFromList :: MapOp c b => Val instr c -> [Val instr b] -> Val instr (MapOpRes c b) class IterOp (c :: T) where { type family IterOpEl c :: T; } iterOpDetachOne :: IterOp c => Val instr c -> (Maybe (Val instr (IterOpEl c)), Val instr c) class SizeOp (c :: T) evalSize :: SizeOp c => Val cp c -> Int class GetOp (c :: T) where { type family GetOpKey c :: CT; type family GetOpVal c :: T; } evalGet :: GetOp c => CVal (GetOpKey c) -> Val cp c -> Maybe (Val cp (GetOpVal c)) class UpdOp (c :: T) where { type family UpdOpKey c :: CT; type family UpdOpParams c :: T; } evalUpd :: UpdOp c => CVal (UpdOpKey c) -> Val cp (UpdOpParams c) -> Val cp c -> Val cp c class SliceOp (c :: T) evalSlice :: SliceOp c => Natural -> Natural -> Val cp c -> Maybe (Val cp c) class ConcatOp (c :: T) evalConcat :: ConcatOp c => Val cp c -> Val cp c -> Val cp c evalConcat' :: ConcatOp c => [Val cp c] -> Val cp c -- | Representation of Michelson instruction or sequence of instructions. -- -- Each Michelson instruction is represented by exactly one constructor -- of this data type. Sequence of instructions is represented with use of -- Seq constructor in following way: SWAP; DROP ; DUP; -- -> SWAP Instr DROP Instr DUP. Special case -- where there are no instructions is represented by constructor -- Nop, e.g. IF_NONE {} { SWAP; DROP; } -> -- IF_NONE Nop (SWAP Instr DROP). -- -- Type parameter inp states for input stack type. That is, type -- of the stack that is required for operation to execute. -- -- Type parameter out states for output stack type or type of -- stack that will be left after instruction's execution. data Instr (inp :: [T]) (out :: [T]) [Seq] :: Typeable b => Instr a b -> Instr b c -> Instr a c -- | Nop operation. Missing in Michelson spec, added to parse construction -- like `IF {} { SWAP; DROP; }`. [Nop] :: Instr s s [Ext] :: ExtT Instr -> Instr s s -- | Nested wrapper is going to wrap a sequence of instructions with { }. -- It is crucial because serialisation of a contract depends on precise -- structure of its code. [Nested] :: Instr inp out -> Instr inp out [DROP] :: Instr (a : s) s [DUP] :: Instr (a : s) (a : (a : s)) [SWAP] :: Instr (a : (b : s)) (b : (a : s)) [PUSH] :: forall t s. SingI t => Val Instr t -> Instr s (t : s) [SOME] :: Instr (a : s) ( 'TOption a : s) [NONE] :: forall a s. SingI a => Instr s ( 'TOption a : s) [UNIT] :: Instr s ( 'TUnit : s) [IF_NONE] :: (Typeable a, Typeable s) => Instr s s' -> Instr (a : s) s' -> Instr ( 'TOption a : s) s' [PAIR] :: Instr (a : (b : s)) ( 'TPair a b : s) [CAR] :: Instr ( 'TPair a b : s) (a : s) [CDR] :: Instr ( 'TPair a b : s) (b : s) [LEFT] :: forall a b s. SingI b => Instr (a : s) ( 'TOr a b : s) [RIGHT] :: forall a b s. SingI a => Instr (b : s) ( 'TOr a b : s) [IF_LEFT] :: (Typeable s, Typeable a, Typeable b) => Instr (a : s) s' -> Instr (b : s) s' -> Instr ( 'TOr a b : s) s' [IF_RIGHT] :: (Typeable s, Typeable b, Typeable a) => Instr (b : s) s' -> Instr (a : s) s' -> Instr ( 'TOr a b : s) s' [NIL] :: SingI p => Instr s ( 'TList p : s) [CONS] :: Instr (a : ( 'TList a : s)) ( 'TList a : s) [IF_CONS] :: (Typeable s, Typeable a) => Instr (a : ( 'TList a : s)) s' -> Instr s s' -> Instr ( 'TList a : s) s' [SIZE] :: SizeOp c => Instr (c : s) ( 'Tc 'CNat : s) [EMPTY_SET] :: SingI e => Instr s ( 'TSet e : s) [EMPTY_MAP] :: (SingI a, SingI b) => Instr s ( 'TMap a b : s) [MAP] :: (Typeable (MapOpInp c : s), MapOp c b) => Instr (MapOpInp c : s) (b : s) -> Instr (c : s) (MapOpRes c b : s) [ITER] :: (Typeable (IterOpEl c : s), IterOp c) => Instr (IterOpEl c : s) s -> Instr (c : s) s [MEM] :: MemOp c => Instr ( 'Tc (MemOpKey c) : (c : s)) ( 'Tc 'CBool : s) [GET] :: GetOp c => Instr ( 'Tc (GetOpKey c) : (c : s)) ( 'TOption (GetOpVal c) : s) [UPDATE] :: UpdOp c => Instr ( 'Tc (UpdOpKey c) : (UpdOpParams c : (c : s))) (c : s) [IF] :: Typeable s => Instr s s' -> Instr s s' -> Instr ( 'Tc 'CBool : s) s' [LOOP] :: Typeable s => Instr s ( 'Tc 'CBool : s) -> Instr ( 'Tc 'CBool : s) s [LOOP_LEFT] :: (Typeable a, Typeable s) => Instr (a : s) ( 'TOr a b : s) -> Instr ( 'TOr a b : s) (b : s) [LAMBDA] :: forall i o s. (SingI i, SingI o) => Val Instr ( 'TLambda i o) -> Instr s ( 'TLambda i o : s) [EXEC] :: Typeable t1 => Instr (t1 : ( 'TLambda t1 t2 : s)) (t2 : s) [DIP] :: Typeable a => Instr a c -> Instr (b : a) (b : c) [FAILWITH] :: Instr (a : s) t [CAST] :: forall a s. SingI a => Instr (a : s) (a : s) [RENAME] :: Instr (a : s) (a : s) [PACK] :: Instr (a : s) ( 'Tc 'CBytes : s) [UNPACK] :: SingI a => Instr ( 'Tc 'CBytes : s) ( 'TOption a : s) [CONCAT] :: ConcatOp c => Instr (c : (c : s)) (c : s) [CONCAT'] :: ConcatOp c => Instr ( 'TList c : s) (c : s) [SLICE] :: SliceOp c => Instr ( 'Tc 'CNat : ( 'Tc 'CNat : (c : s))) ( 'TOption c : s) [ISNAT] :: Instr ( 'Tc 'CInt : s) ( 'TOption ( 'Tc 'CNat) : s) [ADD] :: ArithOp Add n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes Add n m) : s) [SUB] :: ArithOp Sub n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes Sub n m) : s) [MUL] :: ArithOp Mul n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes Mul n m) : s) [EDIV] :: EDivOp n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'TOption ( 'TPair ( 'Tc (EDivOpRes n m)) ( 'Tc (EModOpRes n m))) : s) [ABS] :: UnaryArithOp Abs n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Abs n) : s) [NEG] :: UnaryArithOp Neg n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Neg n) : s) [LSL] :: ArithOp Lsl n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes Lsl n m) : s) [LSR] :: ArithOp Lsr n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes Lsr n m) : s) [OR] :: ArithOp Or n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes Or n m) : s) [AND] :: ArithOp And n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes And n m) : s) [XOR] :: ArithOp Xor n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes Xor n m) : s) [NOT] :: UnaryArithOp Not n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Not n) : s) [COMPARE] :: ArithOp Compare n m => Instr ( 'Tc n : ( 'Tc m : s)) ( 'Tc (ArithRes Compare n m) : s) [EQ] :: UnaryArithOp Eq' n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Eq' n) : s) [NEQ] :: UnaryArithOp Neq n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Neq n) : s) [LT] :: UnaryArithOp Lt n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Lt n) : s) [GT] :: UnaryArithOp Gt n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Gt n) : s) [LE] :: UnaryArithOp Le n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Le n) : s) [GE] :: UnaryArithOp Ge n => Instr ( 'Tc n : s) ( 'Tc (UnaryArithRes Ge n) : s) [INT] :: Instr ( 'Tc 'CNat : s) ( 'Tc 'CInt : s) [SELF] :: forall (cp :: T) s. Instr s ( 'TContract cp : s) [CONTRACT] :: SingI p => Instr ( 'Tc 'CAddress : s) ( 'TOption ( 'TContract p) : s) [TRANSFER_TOKENS] :: Typeable p => Instr (p : ( 'Tc 'CMutez : ( 'TContract p : s))) ( 'TOperation : s) [SET_DELEGATE] :: Instr ( 'TOption ( 'Tc 'CKeyHash) : s) ( 'TOperation : s) [CREATE_ACCOUNT] :: Instr ( 'Tc 'CKeyHash : ( 'TOption ( 'Tc 'CKeyHash) : ( 'Tc 'CBool : ( 'Tc 'CMutez : s)))) ( 'TOperation : ( 'Tc 'CAddress : s)) [CREATE_CONTRACT] :: (SingI p, SingI g, Typeable p, Typeable g) => Instr ( 'Tc 'CKeyHash : ( 'TOption ( 'Tc 'CKeyHash) : ( 'Tc 'CBool : ( 'Tc 'CBool : ( 'Tc 'CMutez : ( 'TLambda ( 'TPair p g) ( 'TPair ( 'TList 'TOperation) g) : (g : s))))))) ( 'TOperation : ( 'Tc 'CAddress : s)) [CREATE_CONTRACT2] :: (SingI p, SingI g, Typeable p, Typeable g) => Instr '[ 'TPair p g] '[ 'TPair ( 'TList 'TOperation) g] -> Instr ( 'Tc 'CKeyHash : ( 'TOption ( 'Tc 'CKeyHash) : ( 'Tc 'CBool : ( 'Tc 'CBool : ( 'Tc 'CMutez : (g : s)))))) ( 'TOperation : ( 'Tc 'CAddress : s)) [IMPLICIT_ACCOUNT] :: Instr ( 'Tc 'CKeyHash : s) ( 'TContract 'TUnit : s) [NOW] :: Instr s ( 'Tc 'CTimestamp : s) [AMOUNT] :: Instr s ( 'Tc 'CMutez : s) [BALANCE] :: Instr s ( 'Tc 'CMutez : s) [CHECK_SIGNATURE] :: Instr ( 'TKey : ( 'TSignature : ( 'Tc 'CBytes : s))) ( 'Tc 'CBool : s) [SHA256] :: Instr ( 'Tc 'CBytes : s) ( 'Tc 'CBytes : s) [SHA512] :: Instr ( 'Tc 'CBytes : s) ( 'Tc 'CBytes : s) [BLAKE2B] :: Instr ( 'Tc 'CBytes : s) ( 'Tc 'CBytes : s) [HASH_KEY] :: Instr ( 'TKey : s) ( 'Tc 'CKeyHash : s) [STEPS_TO_QUOTA] :: Instr s ( 'Tc 'CNat : s) [SOURCE] :: Instr s ( 'Tc 'CAddress : s) [SENDER] :: Instr s ( 'Tc 'CAddress : s) [ADDRESS] :: Instr ( 'TContract a : s) ( 'Tc 'CAddress : s) -- | Infix version of Seq constructor. -- -- One can represent sequence of Michelson opertaions as follows: -- SWAP; DROP; DUP; -> SWAP DUP. (#) :: Typeable b => Instr a b -> Instr b c -> Instr a c infixl 0 # type Contract cp st = Instr (ContractInp cp st) (ContractOut st) -- | ExtT is extension of Instr by Morley instructions type family ExtT (instr :: [T] -> [T] -> Type) :: Type type InstrExtT = ExtT Instr -- | Extracts Notes t type from Type and corresponding -- singleton. extractNotes :: Type -> Sing t -> Either Text (Notes t) -- | Extracts T type from Type. fromUType :: Type -> T mkUType :: Sing x -> Notes x -> Type -- | Converts from T to Type. toUType :: T -> Type -- | Representation of comparable value in Michelson language. -- -- By specification, we're allowed to compare only following types: int, -- nat, string, bytes, mutez, bool, key_hash, timestamp, address. -- -- Only these values can be used as map keys or set elements. data CVal t [CvInt] :: Integer -> CVal 'CInt [CvNat] :: Natural -> CVal 'CNat [CvString] :: Text -> CVal 'CString [CvBytes] :: ByteString -> CVal 'CBytes [CvMutez] :: Mutez -> CVal 'CMutez [CvBool] :: Bool -> CVal 'CBool [CvKeyHash] :: KeyHash -> CVal 'CKeyHash [CvTimestamp] :: Timestamp -> CVal 'CTimestamp [CvAddress] :: Address -> CVal 'CAddress -- | Converts a single Haskell value into CVal representation. class ToCVal a -- | Converts a CVal value into a single Haskell value. class FromCVal t toCVal :: ToCVal a => a -> CVal (ToCT a) fromCVal :: FromCVal t => CVal (ToCT t) -> t convertContract :: forall param store. (SingI param, SingI store, ConversibleExt) => Contract param store -> UntypedContract instrToOps :: ConversibleExt => Instr inp out -> [ExpandedOp] -- | Function unsafeValToValue converts typed Val to -- untyped Value from Michelson.Untyped.Value module -- -- VOp cannot be represented in Value from untyped types, so -- calling this function on it will cause an error unsafeValToValue :: (ConversibleExt, HasCallStack) => Val Instr t -> UntypedValue -- | Convert a typed Val to an untyped Value, or fail if it -- contains operations which are unrepresentable there. valToOpOrValue :: forall t. ConversibleExt => Val Instr t -> Maybe UntypedValue class Conversible ext1 ext2 convert :: Conversible ext1 ext2 => ext1 -> ext2 type ConversibleExt = Conversible (ExtT Instr) (ExtU InstrAbstract ExpandedOp) -- | Class for binary arithmetic operation. -- -- Takes binary operation marker as op parameter, types of left -- operand n and right operand m. class ArithOp aop (n :: CT) (m :: CT) where { -- | Type family ArithRes denotes the type resulting from -- computing operation op from operands of types n and -- m. -- -- For instance, adding integer to natural produces integer, which is -- reflected in following instance of type family: ArithRes Add CNat -- CInt = CInt. type family ArithRes aop n m :: CT; } -- | Evaluate arithmetic operation on given operands. evalOp :: ArithOp aop n m => proxy aop -> CVal n -> CVal m -> Either (ArithError (CVal n) (CVal m)) (CVal (ArithRes aop n m)) -- | Marker data type for add operation. class UnaryArithOp aop (n :: CT) where { type family UnaryArithRes aop n :: CT; } evalUnaryArithOp :: UnaryArithOp aop n => proxy aop -> CVal n -> CVal (UnaryArithRes aop n) -- | Represents an arithmetic error of the operation. data ArithError n m MutezArithError :: ArithErrorType -> n -> m -> ArithError n m -- | Denotes the error type occured in the arithmetic operation. data ArithErrorType AddOverflow :: ArithErrorType MulOverflow :: ArithErrorType SubUnderflow :: ArithErrorType data Add data Sub data Mul data Abs data Neg data Or data And data Xor data Not data Lsl data Lsr data Compare data Eq' data Neq data Lt data Gt data Le data Ge -- | Data type, holding annotation data for a given Michelson type -- t or * in case no data is provided for the tree. -- -- There is a little semantical duplication between data type -- constructors. Semantics behind NStar constructor are exactly -- same as semantics behind N constructor with relevant -- Notes' constructor be given all default values (which means all -- annotations are empty). -- -- Constructor NStar is given as a tiny optimization to allow -- handling no-annotation case completely for free (see converge -- and mkNotes functions). data Notes t N :: Notes' t -> Notes t NStar :: Notes t -- | Data type, holding annotation data for a given Michelson type -- t. -- -- Each constructor corresponds to exactly one constructor of T -- and holds all type and field annotations that can be attributed to a -- Michelson type corrspoding to t. data Notes' t [NTc] :: TypeAnn -> Notes' ( 'Tc ct) [NTKey] :: TypeAnn -> Notes' 'TKey [NTUnit] :: TypeAnn -> Notes' 'TUnit [NTSignature] :: TypeAnn -> Notes' 'TSignature [NTOption] :: TypeAnn -> FieldAnn -> Notes t -> Notes' ( 'TOption t) [NTList] :: TypeAnn -> Notes t -> Notes' ( 'TList t) [NTSet] :: TypeAnn -> TypeAnn -> Notes' ( 'TSet ct) [NTOperation] :: TypeAnn -> Notes' 'TOperation [NTContract] :: TypeAnn -> Notes t -> Notes' ( 'TContract t) [NTPair] :: TypeAnn -> FieldAnn -> FieldAnn -> Notes p -> Notes q -> Notes' ( 'TPair p q) [NTOr] :: TypeAnn -> FieldAnn -> FieldAnn -> Notes p -> Notes q -> Notes' ( 'TOr p q) [NTLambda] :: TypeAnn -> Notes p -> Notes q -> Notes' ( 'TLambda p q) [NTMap] :: TypeAnn -> TypeAnn -> Notes v -> Notes' ( 'TMap k v) [NTBigMap] :: TypeAnn -> TypeAnn -> Notes v -> Notes' ( 'TBigMap k v) -- | Same as converge' but works with Notes data type. converge :: Notes t -> Notes t -> Either Text (Notes t) -- | Converge two type or field notes (which may be wildcards). convergeAnns :: Show (Annotation tag) => Annotation tag -> Annotation tag -> Either Text (Annotation tag) -- | Helper function for work with Notes data type. -- --
-- notesCase f g notes ---- -- is equivalent to -- --
-- case notes of -- NStar -> f -- N v -> g v --notesCase :: r -> (Notes' t -> r) -> Notes t -> r -- | Check whether given annotations object is *. isStar :: Notes t -> Bool -- | Checks whether given notes n can be immediately converted to -- star and returns either NStar or N n. -- -- Given n :: Notes' t can be immediately converted to star iff -- all nested (sn :: Notes t) == NStar and for each annotation -- an: an == def. mkNotes :: Notes' t -> Notes t orAnn :: Annotation t -> Annotation t -> Annotation t module Morley.Types type Parameter = Type type Storage = Type data Contract op Contract :: Parameter -> Storage -> [op] -> Contract op [para] :: Contract op -> Parameter [stor] :: Contract op -> Storage [code] :: Contract op -> [op] data Value op ValueInt :: Integer -> Value op ValueString :: Text -> Value op ValueBytes :: InternalByteString -> Value op ValueUnit :: Value op ValueTrue :: Value op ValueFalse :: Value op ValuePair :: Value op -> Value op -> Value op ValueLeft :: Value op -> Value op ValueRight :: Value op -> Value op ValueSome :: Value op -> Value op ValueNone :: Value op ValueNil :: Value op -- | A sequence of elements: can be a list or a set. We can't distinguish -- lists and sets during parsing. ValueSeq :: (NonEmpty $ Value op) -> Value op ValueMap :: (NonEmpty $ Elt op) -> Value op ValueLambda :: NonEmpty op -> Value op data Elt op Elt :: Value op -> Value op -> Elt op -- | Michelson instruction with abstract parameter op. This -- parameter is necessary, because at different stages of our pipeline it -- will be different. Initially it can contain macros and non-flattened -- instructions, but then it contains only vanilla Michelson -- instructions. data InstrAbstract op EXT :: ExtU InstrAbstract op -> InstrAbstract op DROP :: InstrAbstract op DUP :: VarAnn -> InstrAbstract op SWAP :: InstrAbstract op PUSH :: VarAnn -> Type -> Value op -> InstrAbstract op SOME :: TypeAnn -> VarAnn -> FieldAnn -> InstrAbstract op NONE :: TypeAnn -> VarAnn -> FieldAnn -> Type -> InstrAbstract op UNIT :: TypeAnn -> VarAnn -> InstrAbstract op IF_NONE :: [op] -> [op] -> InstrAbstract op PAIR :: TypeAnn -> VarAnn -> FieldAnn -> FieldAnn -> InstrAbstract op CAR :: VarAnn -> FieldAnn -> InstrAbstract op CDR :: VarAnn -> FieldAnn -> InstrAbstract op LEFT :: TypeAnn -> VarAnn -> FieldAnn -> FieldAnn -> Type -> InstrAbstract op RIGHT :: TypeAnn -> VarAnn -> FieldAnn -> FieldAnn -> Type -> InstrAbstract op IF_LEFT :: [op] -> [op] -> InstrAbstract op IF_RIGHT :: [op] -> [op] -> InstrAbstract op NIL :: TypeAnn -> VarAnn -> Type -> InstrAbstract op CONS :: VarAnn -> InstrAbstract op IF_CONS :: [op] -> [op] -> InstrAbstract op SIZE :: VarAnn -> InstrAbstract op EMPTY_SET :: TypeAnn -> VarAnn -> Comparable -> InstrAbstract op EMPTY_MAP :: TypeAnn -> VarAnn -> Comparable -> Type -> InstrAbstract op MAP :: VarAnn -> [op] -> InstrAbstract op ITER :: [op] -> InstrAbstract op MEM :: VarAnn -> InstrAbstract op GET :: VarAnn -> InstrAbstract op UPDATE :: InstrAbstract op IF :: [op] -> [op] -> InstrAbstract op LOOP :: [op] -> InstrAbstract op LOOP_LEFT :: [op] -> InstrAbstract op LAMBDA :: VarAnn -> Type -> Type -> [op] -> InstrAbstract op EXEC :: VarAnn -> InstrAbstract op DIP :: [op] -> InstrAbstract op FAILWITH :: InstrAbstract op CAST :: VarAnn -> Type -> InstrAbstract op RENAME :: VarAnn -> InstrAbstract op PACK :: VarAnn -> InstrAbstract op UNPACK :: VarAnn -> Type -> InstrAbstract op CONCAT :: VarAnn -> InstrAbstract op SLICE :: VarAnn -> InstrAbstract op ISNAT :: VarAnn -> InstrAbstract op ADD :: VarAnn -> InstrAbstract op SUB :: VarAnn -> InstrAbstract op MUL :: VarAnn -> InstrAbstract op EDIV :: VarAnn -> InstrAbstract op ABS :: VarAnn -> InstrAbstract op NEG :: InstrAbstract op LSL :: VarAnn -> InstrAbstract op LSR :: VarAnn -> InstrAbstract op OR :: VarAnn -> InstrAbstract op AND :: VarAnn -> InstrAbstract op XOR :: VarAnn -> InstrAbstract op NOT :: VarAnn -> InstrAbstract op COMPARE :: VarAnn -> InstrAbstract op EQ :: VarAnn -> InstrAbstract op NEQ :: VarAnn -> InstrAbstract op LT :: VarAnn -> InstrAbstract op GT :: VarAnn -> InstrAbstract op LE :: VarAnn -> InstrAbstract op GE :: VarAnn -> InstrAbstract op INT :: VarAnn -> InstrAbstract op SELF :: VarAnn -> InstrAbstract op CONTRACT :: VarAnn -> Type -> InstrAbstract op TRANSFER_TOKENS :: VarAnn -> InstrAbstract op SET_DELEGATE :: VarAnn -> InstrAbstract op CREATE_ACCOUNT :: VarAnn -> VarAnn -> InstrAbstract op CREATE_CONTRACT :: VarAnn -> VarAnn -> InstrAbstract op CREATE_CONTRACT2 :: VarAnn -> VarAnn -> Contract op -> InstrAbstract op IMPLICIT_ACCOUNT :: VarAnn -> InstrAbstract op NOW :: VarAnn -> InstrAbstract op AMOUNT :: VarAnn -> InstrAbstract op BALANCE :: VarAnn -> InstrAbstract op CHECK_SIGNATURE :: VarAnn -> InstrAbstract op SHA256 :: VarAnn -> InstrAbstract op SHA512 :: VarAnn -> InstrAbstract op BLAKE2B :: VarAnn -> InstrAbstract op HASH_KEY :: VarAnn -> InstrAbstract op STEPS_TO_QUOTA :: VarAnn -> InstrAbstract op SOURCE :: VarAnn -> InstrAbstract op SENDER :: VarAnn -> InstrAbstract op ADDRESS :: VarAnn -> InstrAbstract op type Instr = InstrAbstract Op newtype Op Op :: Instr -> Op [unOp] :: Op -> Instr type TypeAnn = Annotation TypeTag type FieldAnn = Annotation FieldTag type VarAnn = Annotation VarTag ann :: Text -> Annotation a noAnn :: Annotation a data Type Type :: T -> TypeAnn -> Type data Comparable Comparable :: CT -> TypeAnn -> Comparable data T Tc :: CT -> T TKey :: T TUnit :: T TSignature :: T TOption :: FieldAnn -> Type -> T TList :: Type -> T TSet :: Comparable -> T TOperation :: T TContract :: Type -> T TPair :: FieldAnn -> FieldAnn -> Type -> Type -> T TOr :: FieldAnn -> FieldAnn -> Type -> Type -> T TLambda :: Type -> Type -> T TMap :: Comparable -> Type -> T TBigMap :: Comparable -> Type -> T data CT CInt :: CT CNat :: CT CString :: CT CBytes :: CT CMutez :: CT CBool :: CT CKeyHash :: CT CTimestamp :: CT CAddress :: CT newtype Annotation tag Annotation :: Text -> Annotation tag -- | ByteString does not have an instance for ToJSON and FromJSON, to avoid -- orphan type class instances, make a new type wrapper around it. newtype InternalByteString InternalByteString :: ByteString -> InternalByteString unInternalByteString :: InternalByteString -> ByteString data CustomParserException UnknownTypeException :: CustomParserException OddNumberBytesException :: CustomParserException UnexpectedLineBreak :: CustomParserException type Parser = ReaderT LetEnv (Parsec CustomParserException Text) -- | Parsec is a non-transformer variant of the more general -- ParsecT monad transformer. type Parsec e s = ParsecT e s Identity -- | A non-empty collection of ParseErrors equipped with -- PosState that allows to pretty-print the errors efficiently and -- correctly. data ParseErrorBundle s e data ParserException ParserException :: ParseErrorBundle Text CustomParserException -> ParserException -- | The environment containing lets from the let-block data LetEnv LetEnv :: Map Text LetMacro -> Map Text LetValue -> Map Text LetType -> LetEnv [letMacros] :: LetEnv -> Map Text LetMacro [letValues] :: LetEnv -> Map Text LetValue [letTypes] :: LetEnv -> Map Text LetType noLetEnv :: LetEnv -- | Implementation-specific instructions embedded in a NOP -- primitive, which mark a specific point during a contract's -- typechecking or execution. -- -- These instructions are not allowed to modify the contract's stack, but -- may impose additional constraints that can cause a contract to report -- errors in type-checking or testing. -- -- Additionaly, some implementation-specific language features such as -- type-checking of LetMacros are implemented using this -- mechanism (specifically FN and FN_END). data UExtInstrAbstract op -- | Matches current stack against a type-pattern STACKTYPE :: StackTypePattern -> UExtInstrAbstract op -- | Begin a typed stack function (push a TcExtFrame) FN :: Text -> StackFn -> UExtInstrAbstract op -- | End a stack function (pop a TcExtFrame) FN_END :: UExtInstrAbstract op -- | Copy the current stack and run an inline assertion on it UTEST_ASSERT :: UTestAssert op -> UExtInstrAbstract op -- | Print a comment with optional embedded StackRefs UPRINT :: PrintComment -> UExtInstrAbstract op type ParsedInstr = InstrAbstract ParsedOp -- | Unexpanded instructions produced directly by the ops parser, -- which contains primitive Michelson Instructions, inline-able macros -- and sequences data ParsedOp -- | Primitive Michelson instruction Prim :: ParsedInstr -> ParsedOp -- | Built-in Michelson macro defined by the specification Mac :: Macro -> ParsedOp -- | User-defined macro with instructions to be inlined LMac :: LetMacro -> ParsedOp -- | A sequence of instructions Seq :: [ParsedOp] -> ParsedOp type ParsedUTestAssert = UTestAssert ParsedOp type ParsedUExtInstr = UExtInstrAbstract ParsedOp type ExpandedInstr = InstrAbstract ExpandedOp data ExpandedOp PrimEx :: ExpandedInstr -> ExpandedOp SeqEx :: [ExpandedOp] -> ExpandedOp type ExpandedUExtInstr = UExtInstrAbstract ExpandedOp data PairStruct F :: (VarAnn, FieldAnn) -> PairStruct P :: PairStruct -> PairStruct -> PairStruct data CadrStruct A :: CadrStruct D :: CadrStruct -- | Built-in Michelson Macros defined by the specification data Macro CMP :: ParsedInstr -> VarAnn -> Macro IFX :: ParsedInstr -> [ParsedOp] -> [ParsedOp] -> Macro IFCMP :: ParsedInstr -> VarAnn -> [ParsedOp] -> [ParsedOp] -> Macro FAIL :: Macro PAPAIR :: PairStruct -> TypeAnn -> VarAnn -> Macro UNPAIR :: PairStruct -> Macro CADR :: [CadrStruct] -> VarAnn -> FieldAnn -> Macro SET_CADR :: [CadrStruct] -> VarAnn -> FieldAnn -> Macro MAP_CADR :: [CadrStruct] -> VarAnn -> FieldAnn -> [ParsedOp] -> Macro DIIP :: Integer -> [ParsedOp] -> Macro DUUP :: Integer -> VarAnn -> Macro ASSERT :: Macro ASSERTX :: ParsedInstr -> Macro ASSERT_CMP :: ParsedInstr -> Macro ASSERT_NONE :: Macro ASSERT_SOME :: Macro ASSERT_LEFT :: Macro ASSERT_RIGHT :: Macro IF_SOME :: [ParsedOp] -> [ParsedOp] -> Macro data ExtInstr TEST_ASSERT :: TestAssert -> ExtInstr PRINT :: PrintComment -> ExtInstr data TestAssert [TestAssert] :: (Typeable inp, Typeable out) => Text -> PrintComment -> Instr inp ( 'Tc 'CBool : out) -> TestAssert data UTestAssert op UTestAssert :: Text -> PrintComment -> [op] -> UTestAssert op [tassName] :: UTestAssert op -> Text [tassComment] :: UTestAssert op -> PrintComment [tassInstrs] :: UTestAssert op -> [op] newtype PrintComment PrintComment :: [Either Text StackRef] -> PrintComment [unPrintComment] :: PrintComment -> [Either Text StackRef] -- | A stack pattern-match data StackTypePattern StkEmpty :: StackTypePattern StkRest :: StackTypePattern StkCons :: TyVar -> StackTypePattern -> StackTypePattern -- | A reference into the stack newtype StackRef StackRef :: Integer -> StackRef -- | Morley interpreter state newtype MorleyLogs MorleyLogs :: [Text] -> MorleyLogs [unMorleyLogs] :: MorleyLogs -> [Text] noMorleyLogs :: MorleyLogs -- | A stack function that expresses the type signature of a -- LetMacro data StackFn StackFn :: Maybe (Set Var) -> StackTypePattern -> StackTypePattern -> StackFn [quantifiedVars] :: StackFn -> Maybe (Set Var) [inPattern] :: StackFn -> StackTypePattern [outPattern] :: StackFn -> StackTypePattern newtype Var Var :: Text -> Var -- | A type-variable or a type-constant data TyVar VarID :: Var -> TyVar TyCon :: Type -> TyVar -- | Get the set of variables in a stack pattern varSet :: StackTypePattern -> Set Var -- | A programmer-defined macro data LetMacro LetMacro :: Text -> StackFn -> [ParsedOp] -> LetMacro [lmName] :: LetMacro -> Text [lmSig] :: LetMacro -> StackFn [lmExpr] :: LetMacro -> [ParsedOp] -- | A programmer-defined constant data LetValue LetValue :: Text -> Type -> Value ParsedOp -> LetValue [lvName] :: LetValue -> Text [lvSig] :: LetValue -> Type [lvVal] :: LetValue -> Value ParsedOp -- | A programmer-defined type-synonym data LetType LetType :: Text -> Type -> LetType [ltName] :: LetType -> Text [ltSig] :: LetType -> Type instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.Macro instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.Macro instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.CadrStruct instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.CadrStruct instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.PairStruct instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.PairStruct instance Data.Aeson.Types.ToJSON.ToJSON op => Data.Aeson.Types.ToJSON.ToJSON (Morley.Types.UTestAssert op) instance Data.Aeson.Types.FromJSON.FromJSON op => Data.Aeson.Types.FromJSON.FromJSON (Morley.Types.UTestAssert op) instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.LetType instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.LetType instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.LetValue instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.LetValue instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.LetMacro instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.LetMacro instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.TyVar instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.TyVar instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.Var instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.Var instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.StackFn instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.StackFn instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.StackRef instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.StackRef instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.StackTypePattern instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.StackTypePattern instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.PrintComment instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.PrintComment instance Data.Aeson.Types.ToJSON.ToJSON op => Data.Aeson.Types.ToJSON.ToJSON (Morley.Types.UExtInstrAbstract op) instance Data.Aeson.Types.FromJSON.FromJSON op => Data.Aeson.Types.FromJSON.FromJSON (Morley.Types.UExtInstrAbstract op) instance Data.Aeson.Types.ToJSON.ToJSON Morley.Types.ParsedOp instance Data.Aeson.Types.FromJSON.FromJSON Morley.Types.ParsedOp instance GHC.Base.Functor Morley.Types.UExtInstrAbstract instance GHC.Generics.Generic (Morley.Types.UExtInstrAbstract op) instance Data.Data.Data op => Data.Data.Data (Morley.Types.UExtInstrAbstract op) instance GHC.Show.Show op => GHC.Show.Show (Morley.Types.UExtInstrAbstract op) instance GHC.Classes.Eq op => GHC.Classes.Eq (Morley.Types.UExtInstrAbstract op) instance GHC.Generics.Generic (Morley.Types.UTestAssert op) instance Data.Data.Data op => Data.Data.Data (Morley.Types.UTestAssert op) instance GHC.Base.Functor Morley.Types.UTestAssert instance GHC.Show.Show op => GHC.Show.Show (Morley.Types.UTestAssert op) instance GHC.Classes.Eq op => GHC.Classes.Eq (Morley.Types.UTestAssert op) instance GHC.Classes.Eq Morley.Types.ExtInstr instance GHC.Show.Show Morley.Types.ExtInstr instance GHC.Generics.Generic Morley.Types.PrintComment instance Data.Data.Data Morley.Types.PrintComment instance GHC.Show.Show Morley.Types.PrintComment instance GHC.Classes.Eq Morley.Types.PrintComment instance GHC.Classes.Eq Morley.Types.LetEnv instance GHC.Show.Show Morley.Types.LetEnv instance GHC.Show.Show Morley.Types.LetType instance GHC.Classes.Eq Morley.Types.LetType instance GHC.Show.Show Morley.Types.LetValue instance GHC.Classes.Eq Morley.Types.LetValue instance GHC.Generics.Generic Morley.Types.Macro instance Data.Data.Data Morley.Types.Macro instance GHC.Show.Show Morley.Types.Macro instance GHC.Classes.Eq Morley.Types.Macro instance GHC.Generics.Generic Morley.Types.ParsedOp instance Data.Data.Data Morley.Types.ParsedOp instance GHC.Show.Show Morley.Types.ParsedOp instance GHC.Classes.Eq Morley.Types.ParsedOp instance GHC.Generics.Generic Morley.Types.LetMacro instance Data.Data.Data Morley.Types.LetMacro instance GHC.Show.Show Morley.Types.LetMacro instance GHC.Classes.Eq Morley.Types.LetMacro instance GHC.Generics.Generic Morley.Types.StackFn instance Data.Data.Data Morley.Types.StackFn instance GHC.Show.Show Morley.Types.StackFn instance GHC.Classes.Eq Morley.Types.StackFn instance GHC.Generics.Generic Morley.Types.StackTypePattern instance Data.Data.Data Morley.Types.StackTypePattern instance GHC.Show.Show Morley.Types.StackTypePattern instance GHC.Classes.Eq Morley.Types.StackTypePattern instance GHC.Generics.Generic Morley.Types.TyVar instance Data.Data.Data Morley.Types.TyVar instance GHC.Show.Show Morley.Types.TyVar instance GHC.Classes.Eq Morley.Types.TyVar instance GHC.Generics.Generic Morley.Types.Var instance Data.Data.Data Morley.Types.Var instance GHC.Classes.Ord Morley.Types.Var instance GHC.Show.Show Morley.Types.Var instance GHC.Classes.Eq Morley.Types.Var instance GHC.Generics.Generic Morley.Types.StackRef instance Data.Data.Data Morley.Types.StackRef instance GHC.Show.Show Morley.Types.StackRef instance GHC.Classes.Eq Morley.Types.StackRef instance GHC.Generics.Generic Morley.Types.CadrStruct instance Data.Data.Data Morley.Types.CadrStruct instance GHC.Show.Show Morley.Types.CadrStruct instance GHC.Classes.Eq Morley.Types.CadrStruct instance GHC.Generics.Generic Morley.Types.PairStruct instance Data.Data.Data Morley.Types.PairStruct instance GHC.Show.Show Morley.Types.PairStruct instance GHC.Classes.Eq Morley.Types.PairStruct instance Formatting.Buildable.Buildable Morley.Types.MorleyLogs instance Data.Default.Class.Default Morley.Types.MorleyLogs instance GHC.Show.Show Morley.Types.MorleyLogs instance GHC.Classes.Eq Morley.Types.MorleyLogs instance GHC.Show.Show Morley.Types.CustomParserException instance GHC.Classes.Ord Morley.Types.CustomParserException instance Data.Data.Data Morley.Types.CustomParserException instance GHC.Classes.Eq Morley.Types.CustomParserException instance GHC.Show.Show Morley.Types.TestAssert instance Formatting.Buildable.Buildable op => Formatting.Buildable.Buildable (Morley.Types.UExtInstrAbstract op) instance Michelson.Typed.Convert.Conversible Morley.Types.ExtInstr (Morley.Types.UExtInstrAbstract Michelson.Untyped.Instr.ExpandedOp) instance Formatting.Buildable.Buildable code => Formatting.Buildable.Buildable (Morley.Types.UTestAssert code) instance GHC.Classes.Eq Morley.Types.TestAssert instance Formatting.Buildable.Buildable Morley.Types.PrintComment instance Data.Default.Class.Default a => Data.Default.Class.Default (Morley.Types.Parser a) instance Michelson.Printer.Util.RenderDoc Morley.Types.ParsedOp instance Formatting.Buildable.Buildable Morley.Types.ParsedOp instance Formatting.Buildable.Buildable Morley.Types.Macro instance Formatting.Buildable.Buildable Morley.Types.LetMacro instance Formatting.Buildable.Buildable Morley.Types.StackFn instance Formatting.Buildable.Buildable Morley.Types.StackTypePattern instance Formatting.Buildable.Buildable Morley.Types.TyVar instance Formatting.Buildable.Buildable Morley.Types.Var instance Formatting.Buildable.Buildable Morley.Types.StackRef instance Formatting.Buildable.Buildable Morley.Types.CadrStruct instance Formatting.Buildable.Buildable Morley.Types.PairStruct instance GHC.Show.Show Morley.Types.ParserException instance GHC.Exception.Type.Exception Morley.Types.ParserException instance Formatting.Buildable.Buildable Morley.Types.ParserException instance Text.Megaparsec.Error.ShowErrorComponent Morley.Types.CustomParserException -- | TxData type and associated functionality. module Morley.Runtime.TxData -- | Data associated with a particular transaction. data TxData TxData :: !Address -> !UntypedValue -> !Mutez -> TxData [tdSenderAddress] :: TxData -> !Address [tdParameter] :: TxData -> !UntypedValue [tdAmount] :: TxData -> !Mutez instance GHC.Show.Show Morley.Types.ExpandedUExtInstr => GHC.Show.Show Morley.Runtime.TxData.TxData -- | Global blockchain state (emulated). module Morley.Runtime.GState -- | State of a contract with code. data ContractState ContractState :: !Mutez -> !UntypedValue -> !UntypedContract -> ContractState -- | Amount of mutez owned by this contract. [csBalance] :: ContractState -> !Mutez -- | Storage value associated with this contract. [csStorage] :: ContractState -> !UntypedValue -- | Contract itself (untyped). [csContract] :: ContractState -> !UntypedContract -- | State of an arbitrary address. data AddressState -- | For contracts without code we store only its balance. ASSimple :: !Mutez -> AddressState -- | For contracts with code we store more state represented by -- ContractState. ASContract :: !ContractState -> AddressState -- | Extract balance from AddressState. asBalance :: AddressState -> Mutez -- | Persistent data passed to Morley contracts which can be updated as -- result of contract execution. data GState GState :: Map Address AddressState -> GState -- | All known addresses and their state. [gsAddresses] :: GState -> Map Address AddressState -- | Initially this address has a lot of money. genesisAddress :: Address -- | Initially this address has a lot of money. genesisAddressText :: Text -- | KeyHash of genesis address. genesisKeyHash :: KeyHash -- | Initial GState. It's supposed to be used if no GState is -- provided. For now it's empty, but we can hardcode some dummy data in -- the future. initGState :: GState -- | Read GState from a file. readGState :: FilePath -> IO GState -- | Write GState to a file. writeGState :: FilePath -> GState -> IO () -- | Updates that can be applied to GState. data GStateUpdate GSAddAddress :: !Address -> !AddressState -> GStateUpdate GSSetStorageValue :: !Address -> !UntypedValue -> GStateUpdate GSSetBalance :: !Address -> !Mutez -> GStateUpdate data GStateUpdateError GStateAddressExists :: !Address -> GStateUpdateError GStateUnknownAddress :: !Address -> GStateUpdateError GStateNotContract :: !Address -> GStateUpdateError -- | Apply GStateUpdate to GState. applyUpdate :: GStateUpdate -> GState -> Either GStateUpdateError GState -- | Apply a list of GStateUpdates to GState. applyUpdates :: [GStateUpdate] -> GState -> Either GStateUpdateError GState instance GHC.Show.Show Morley.Runtime.GState.GStateUpdateError instance GHC.Classes.Eq Morley.Runtime.GState.GStateUpdate instance GHC.Show.Show Morley.Runtime.GState.GStateUpdate instance GHC.Show.Show Morley.Runtime.GState.GStateParseError instance Formatting.Buildable.Buildable Morley.Runtime.GState.GStateUpdateError instance Formatting.Buildable.Buildable Morley.Runtime.GState.GStateUpdate instance GHC.Exception.Type.Exception Morley.Runtime.GState.GStateParseError instance Data.Aeson.Types.ToJSON.ToJSON Morley.Runtime.GState.GState instance Data.Aeson.Types.FromJSON.FromJSON Morley.Runtime.GState.GState instance GHC.Show.Show Morley.Runtime.GState.GState instance Data.Aeson.Types.ToJSON.ToJSON Morley.Runtime.GState.AddressState instance Data.Aeson.Types.FromJSON.FromJSON Morley.Runtime.GState.AddressState instance GHC.Classes.Eq Morley.Runtime.GState.AddressState instance GHC.Generics.Generic Morley.Runtime.GState.AddressState instance GHC.Show.Show Morley.Runtime.GState.AddressState instance Formatting.Buildable.Buildable Morley.Runtime.GState.AddressState instance Data.Aeson.Types.ToJSON.ToJSON Morley.Runtime.GState.ContractState instance Data.Aeson.Types.FromJSON.FromJSON Morley.Runtime.GState.ContractState instance GHC.Classes.Eq Morley.Runtime.GState.ContractState instance GHC.Generics.Generic Morley.Runtime.GState.ContractState instance GHC.Show.Show Morley.Runtime.GState.ContractState instance Formatting.Buildable.Buildable Morley.Runtime.GState.ContractState module Morley.Macro -- | Expand all macros in parsed contract. expandContract :: Contract ParsedOp -> UntypedContract expandValue :: Value ParsedOp -> UntypedValue mapLeaves :: [(VarAnn, FieldAnn)] -> PairStruct -> PairStruct expand :: ParsedOp -> ExpandedOp expandList :: [ParsedOp] -> [ExpandedOp] expandPapair :: PairStruct -> TypeAnn -> VarAnn -> [ParsedOp] expandUnpapair :: PairStruct -> [ParsedOp] expandCadr :: [CadrStruct] -> VarAnn -> FieldAnn -> [ParsedOp] expandSetCadr :: [CadrStruct] -> VarAnn -> FieldAnn -> [ParsedOp] expandMapCadr :: [CadrStruct] -> VarAnn -> FieldAnn -> [ParsedOp] -> [ParsedOp] module Morley.Lexer lexeme :: Parser a -> Parser a mSpace :: Parser () symbol :: Tokens Text -> Parser (Tokens Text) symbol' :: Text -> Parser (Tokens Text) string' :: (MonadParsec e s f, Tokens s ~ Text) => Text -> f Text parens :: Parser a -> Parser a braces :: Parser a -> Parser a brackets :: Parser a -> Parser a brackets' :: Parser a -> Parser a semicolon :: Parser (Tokens Text) comma :: Parser (Tokens Text) module Morley.Parser.Annotations note :: Text -> Parser Text noteT :: Parser TypeAnn noteV :: Parser VarAnn noteF :: Parser FieldAnn noteF2 :: Parser (FieldAnn, FieldAnn) noteTDef :: Parser TypeAnn noteVDef :: Parser VarAnn _noteFDef :: Parser FieldAnn notesTVF :: Parser (TypeAnn, VarAnn, FieldAnn) notesTVF2 :: Parser (TypeAnn, VarAnn, (FieldAnn, FieldAnn)) notesTV :: Parser (TypeAnn, VarAnn) notesVF :: Parser (VarAnn, FieldAnn) fieldType :: Default a => Parser a -> Parser (a, TypeAnn) permute2Def :: (Default a, Default b, Monad f, Alternative f) => f a -> f b -> f (a, b) permute3Def :: (Default a, Default b, Default c, Monad f, Alternative f) => f a -> f b -> f c -> f (a, b, c) module Morley.Parser -- | Michelson contract with let definitions program :: Parsec CustomParserException Text (Contract ParsedOp) -- | Parse with empty environment parseNoEnv :: Parser a -> String -> Text -> Either (ParseErrorBundle Text CustomParserException) a ops :: Parser [ParsedOp] data ParserException ParserException :: ParseErrorBundle Text CustomParserException -> ParserException stringLiteral :: Parser (Value ParsedOp) type_ :: Parser Type value :: Parser (Value ParsedOp) stackType :: Parser StackTypePattern printComment :: Parser PrintComment bytesLiteral :: Parser (Value a) pushOp :: Parser ParsedInstr intLiteral :: Parser (Value a) -- | Utilities for arbitrary data generation in property tests. module Morley.Test.Gen -- | Minimal (earliest) timestamp used for Arbitrary (CVal -- 'CTimestamp) minTimestamp :: Timestamp -- | Maximal (latest) timestamp used for Arbitrary (CVal -- 'CTimestamp) maxTimestamp :: Timestamp -- | Median of minTimestamp and maxTimestamp. Useful for -- testing (exactly half of generated dates will be before and after this -- date). midTimestamp :: Timestamp instance Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.CValue.CVal 'Michelson.Untyped.Type.CKeyHash) instance Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.CValue.CVal 'Michelson.Untyped.Type.CMutez) instance Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.CValue.CVal 'Michelson.Untyped.Type.CInt) instance Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.CValue.CVal a) => Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.Value.Val instr ('Michelson.Typed.T.Tc a)) instance Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.Value.Val instr a) => Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.Value.Val instr ('Michelson.Typed.T.TList a)) instance Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.Value.Val instr 'Michelson.Typed.T.TUnit) instance (Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.Value.Val instr a), Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.Value.Val instr b)) => Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.Value.Val instr ('Michelson.Typed.T.TPair a b)) instance Test.QuickCheck.Arbitrary.Arbitrary (Michelson.Typed.CValue.CVal 'Michelson.Untyped.Type.CTimestamp) instance Test.QuickCheck.Arbitrary.Arbitrary Tezos.Core.Mutez instance Test.QuickCheck.Arbitrary.Arbitrary Tezos.Core.Timestamp module Michelson.TypeCheck typeCheckContract :: ExtC => TcExtHandler -> UntypedContract -> Either TCError SomeContract -- | Function typeCheckVal converts a single Michelson value given -- in representation from Michelson.Type module to -- representation in strictly typed GADT. -- -- As a second argument, typeCheckVal accepts expected type of -- value. -- -- Type checking algorithm pattern-matches on parse value representation, -- expected type t and constructs Val t value. -- -- If there was no match on a given pair of value and expected type, that -- is interpreted as input of wrong type and type check finishes with -- error. typeCheckVal :: ExtC => UntypedValue -> T -> TypeCheckT SomeVal -- | Function typeCheckList converts list of Michelson -- instructions given in representation from Michelson.Type -- module to representation in strictly typed GADT. -- -- Types are checked along the way which is neccessary to construct a -- strictly typed value. -- -- As a second argument, typeCheckList accepts input stack type -- representation. typeCheckList :: ExtC => [ExpandedOp] -> SomeHST -> TypeCheckT SomeInstr typeCheckCVal :: Value op -> CT -> Maybe SomeValC -- | Data type holding type information for stack (Heterogeneous Stack -- Type). -- -- This data type is used along with instruction data type Instr -- to carry information about its input and output stack types. -- -- That is, if there is value instr :: Instr inp out, along with -- this instr one may carry inpHST :: HST inp and -- outHST :: HST out which will contain whole information about -- input and output stack types for instr. -- -- Data type HST is very similar to Data.Vinyl.Rec, but -- is specialized for a particular purpose. In particular, definition of -- HST (t1 ': t2 ': ... tn ': '[]) requires constraints -- (Typeable t1, Typeable t2, ..., Typeable tn) as well as -- constraints (Typeable '[ t1 ], Typeable '[ t1, t2 ], ...). -- These applications of Typeable class are required for -- convenient usage of type encoded by HST ts with some -- functions from Data.Typeable. -- -- Data type HST (Heterogeneous Stack Type) is a heterogenuous -- list of triples. First element of triple is a type singleton which is -- due to main motivation behind HST, namely for it to be used -- as representation of Instr type data for pattern-matching. -- Second element of triple is a structure, holding field and type -- annotations for a given type. Third element of triple is an optional -- variable annotation for the stack element. data HST (ts :: [T]) [SNil] :: HST '[] [::&] :: (Typeable xs, Typeable x, SingI x) => (Sing x, Notes x, VarAnn) -> HST xs -> HST (x : xs) infixr 7 ::& -- | No-argument type wrapper for HST data type. data SomeHST [SomeHST] :: Typeable ts => HST ts -> SomeHST -- | Data type holding both instruction and type representations of -- instruction's input and output. -- -- Intput and output stack types are wrapped inside the type and -- Typeable constraints are provided to allow convenient -- unwrapping. data SomeInstr [:::] :: (Typeable inp, Typeable out) => Instr inp out -> (HST inp, HST out) -> SomeInstr [SiFail] :: SomeInstr -- | Data type, holding strictly-typed Michelson value along with its type -- singleton. data SomeVal [::::] :: (SingI t, Typeable t) => Val Instr t -> (Sing t, Notes t) -> SomeVal data SomeContract [SomeContract] :: (Typeable st, SingI st, SingI cp, Typeable cp) => Contract cp st -> HST (ContractInp cp st) -> HST (ContractOut st) -> SomeContract -- | Data type, holding strictly-typed Michelson value along with its type -- singleton. data SomeValC [:--:] :: (SingI t, Typeable t) => CVal t -> Sing t -> SomeValC -- | Type check error data TCError TCFailedOnInstr :: ExpandedInstr -> SomeHST -> Text -> TCError TCFailedOnValue :: UntypedValue -> T -> Text -> TCError TCOtherError :: Text -> TCError -- | Constraints on InstrExtT and untyped Instr which are required for type -- checking type ExtC = (Show InstrExtT, Eq ExpandedInstrExtU, Typeable InstrExtT, Buildable ExpandedInstr, ConversibleExt) type TcInstrHandler = ExpandedInstr -> SomeHST -> TypeCheckT SomeInstr -- | Function for typeChecking a nop and updating state TypeCheckT -- is used because inside inside of TEST_ASSERT could be -- PRINTSTACKTYPEetc extended instructions. type TcExtHandler = ExpandedInstrExtU -> TcExtFrames -> SomeHST -> TypeCheckT (TcExtFrames, Maybe InstrExtT) -- | State for type checking nop type TcExtFrames = [(ExpandedInstrExtU, SomeHST)] type TcResult = Either TCError SomeInstr -- | The typechecking state data TypeCheckEnv TypeCheckEnv :: TcExtHandler -> TcExtFrames -> Type -> TypeCheckEnv [tcExtHandler] :: TypeCheckEnv -> TcExtHandler [tcExtFrames] :: TypeCheckEnv -> TcExtFrames [tcContractParam] :: TypeCheckEnv -> Type type TypeCheckT a = ExceptT TCError (State TypeCheckEnv) a runTypeCheckT :: TcExtHandler -> Type -> TypeCheckT a -> Either TCError a -- | Function eqT' is a simple wrapper around -- Data.Typeable.eqT suited for use within Either Text -- a applicative. eqT' :: forall a b. (Typeable a, Typeable b) => Either Text (a :~: b) -- | Module, containing function to interpret Michelson instructions -- against given context and input stack. module Michelson.Interpret -- | Environment for contract execution. data ContractEnv ContractEnv :: !Timestamp -> !RemainingSteps -> !Mutez -> Map Address UntypedContract -> !Address -> !Address -> !Address -> !Mutez -> ContractEnv -- | Timestamp of the block whose validation triggered this execution. [ceNow] :: ContractEnv -> !Timestamp -- | Number of steps after which execution unconditionally terminates. [ceMaxSteps] :: ContractEnv -> !RemainingSteps -- | Current amount of mutez of the current contract. [ceBalance] :: ContractEnv -> !Mutez -- | Mapping from existing contracts' addresses to their executable -- representation. [ceContracts] :: ContractEnv -> Map Address UntypedContract -- | Address of the interpreted contract. [ceSelf] :: ContractEnv -> !Address -- | The contract that initiated the current transaction. [ceSource] :: ContractEnv -> !Address -- | The contract that initiated the current internal transaction. [ceSender] :: ContractEnv -> !Address -- | Amount of the current transaction. [ceAmount] :: ContractEnv -> !Mutez data InterpreterEnv s InterpreterEnv :: ContractEnv -> ((InstrExtT, SomeItStack) -> EvalOp s ()) -> InterpreterEnv s [ieContractEnv] :: InterpreterEnv s -> ContractEnv [ieItHandler] :: InterpreterEnv s -> (InstrExtT, SomeItStack) -> EvalOp s () data InterpreterState s InterpreterState :: s -> RemainingSteps -> InterpreterState s [isExtState] :: InterpreterState s -> s [isRemainingSteps] :: InterpreterState s -> RemainingSteps -- | Represents `[FAILED]` state of a Michelson program. Contains value -- that was on top of the stack when FAILWITH was called. data MichelsonFailed [MichelsonFailedWith] :: Val Instr t -> MichelsonFailed [MichelsonArithError] :: ArithError (CVal n) (CVal m) -> MichelsonFailed [MichelsonGasExhaustion] :: MichelsonFailed [MichelsonFailedOther] :: Text -> MichelsonFailed newtype RemainingSteps RemainingSteps :: Word64 -> RemainingSteps data SomeItStack [SomeItStack] :: Typeable inp => Rec (Val Instr) inp -> SomeItStack type EvalOp s a = ExceptT MichelsonFailed (ReaderT (InterpreterEnv s) (State (InterpreterState s))) a interpret :: (ExtC, ToJSON ExpandedInstrExtU, Typeable cp, Typeable st) => Contract cp st -> Val Instr cp -> Val Instr st -> InterpreterEnv s -> s -> ContractReturn s st type ContractReturn s st = (Either MichelsonFailed ([Operation Instr], Val Instr st), InterpreterState s) -- | Interpret a contract without performing any side effects. interpretUntyped :: forall s. (ExtC, ToJSON ExpandedInstrExtU) => TcExtHandler -> UntypedContract -> UntypedValue -> UntypedValue -> InterpreterEnv s -> s -> Either (InterpretUntypedError s) (InterpretUntypedResult s) data InterpretUntypedError s RuntimeFailure :: (MichelsonFailed, s) -> InterpretUntypedError s IllTypedContract :: TCError -> InterpretUntypedError s IllTypedParam :: TCError -> InterpretUntypedError s IllTypedStorage :: TCError -> InterpretUntypedError s UnexpectedParamType :: Text -> InterpretUntypedError s UnexpectedStorageType :: Text -> InterpretUntypedError s data InterpretUntypedResult s [InterpretUntypedResult] :: (Typeable st, SingI st) => {iurOps :: [Operation Instr], iurNewStorage :: Val Instr st, iurNewState :: InterpreterState s} -> InterpretUntypedResult s -- | Function to change amount of remaining steps stored in State monad runInstr :: (ExtC, ToJSON ExpandedInstrExtU, Typeable inp) => Instr inp out -> Rec (Val Instr) inp -> EvalOp state (Rec (Val Instr) out) runInstrNoGas :: forall a b state. (ExtC, ToJSON ExpandedInstrExtU, Typeable a) => Instr a b -> Rec (Val Instr) a -> EvalOp state (Rec (Val Instr) b) instance GHC.Show.Show s => GHC.Show.Show (Michelson.Interpret.InterpreterState s) instance GHC.Num.Num Michelson.Interpret.RemainingSteps instance Formatting.Buildable.Buildable Michelson.Interpret.RemainingSteps instance GHC.Classes.Ord Michelson.Interpret.RemainingSteps instance GHC.Classes.Eq Michelson.Interpret.RemainingSteps instance GHC.Show.Show Michelson.Interpret.RemainingSteps instance GHC.Generics.Generic (Michelson.Interpret.InterpretUntypedError s) instance GHC.Show.Show Michelson.Interpret.MichelsonFailed instance (Formatting.Buildable.Buildable Michelson.Untyped.Instr.ExpandedInstr, GHC.Show.Show s) => GHC.Show.Show (Michelson.Interpret.InterpretUntypedError s) instance GHC.Show.Show s => GHC.Show.Show (Michelson.Interpret.InterpretUntypedResult s) instance (Michelson.Typed.Convert.ConversibleExt, Formatting.Buildable.Buildable s) => Formatting.Buildable.Buildable (Michelson.Interpret.InterpretUntypedError s) instance Michelson.Typed.Convert.ConversibleExt => Formatting.Buildable.Buildable Michelson.Interpret.MichelsonFailed -- | Dummy data to be used in tests where it's not essential. module Morley.Test.Dummy -- | Dummy timestamp, can be used to specify current NOW value or -- maybe something else. dummyNow :: Timestamp -- | Dummy value for maximal number of steps a contract can make. -- Intentionally quite large, because most likely if you use dummy value -- you don't want the interpreter to stop due to gas exhaustion. On the -- other hand, it probably still prevents the interpreter from working -- for eternity. dummyMaxSteps :: RemainingSteps -- | Dummy ContractEnv with some reasonable hardcoded values. You -- can override values you are interested in using record update syntax. dummyContractEnv :: ContractEnv -- | OriginationOperation with most data hardcoded to some -- reasonable values. Contract and initial values must be passed -- explicitly, because otherwise it hardly makes sense. dummyOrigination :: UntypedValue -> UntypedContract -> OriginationOperation module Morley.Ext interpretMorleyUntyped :: UntypedContract -> UntypedValue -> UntypedValue -> ContractEnv -> Either (InterpretUntypedError MorleyLogs) (InterpretUntypedResult MorleyLogs) interpretMorley :: (Typeable cp, Typeable st) => Contract cp st -> Val Instr cp -> Val Instr st -> ContractEnv -> ContractReturn MorleyLogs st typeCheckMorleyContract :: UntypedContract -> Either TCError SomeContract typeCheckHandler :: ExpandedUExtInstr -> TcExtFrames -> SomeHST -> TypeCheckT (TcExtFrames, Maybe ExtInstr) interpretHandler :: (ExtInstr, SomeItStack) -> EvalOp MorleyLogs () -- | Utility functions for unit testing. module Morley.Test.Unit type ContractReturn s st = (Either MichelsonFailed ([Operation Instr], Val Instr st), InterpreterState s) -- | Type for contract execution validation. -- -- It's a function which is supplied with contract execution output -- (failure or new storage with operation list). -- -- Function returns a property which type is designated by type variable -- prop and might be Property or Expectation or -- anything else relevant. type ContractPropValidator st prop = ContractReturn MorleyLogs st -> prop -- | Contract's property tester against given input. Takes contract -- environment, initial storage and parameter, interprets contract on -- this input and invokes validation function. contractProp :: (ToVal param, ToVal storage, ToT param ~ cp, ToT storage ~ st, Typeable cp, Typeable st) => Contract cp st -> ContractPropValidator st prop -> ContractEnv -> param -> storage -> prop -- | Version of contractProp which takes Val as arguments -- instead of regular Haskell values. contractPropVal :: (Typeable cp, Typeable st) => Contract cp st -> ContractPropValidator st prop -> ContractEnv -> Val Instr cp -> Val Instr st -> prop -- | Interpreter of a contract in Morley language. module Morley.Runtime -- | Originate a contract. Returns the address of the originated contract. originateContract :: FilePath -> OriginationOperation -> ("verbose" :! Bool) -> IO Address -- | Run a contract. The contract is originated first (if it's not already) -- and then we pretend that we send a transaction to it. runContract :: Maybe Timestamp -> Word64 -> Mutez -> FilePath -> UntypedValue -> UntypedContract -> TxData -> ("verbose" :! Bool) -> ("dryRun" :! Bool) -> IO () -- | Send a transaction to given address with given parameters. transfer :: Maybe Timestamp -> Word64 -> FilePath -> Address -> TxData -> ("verbose" :! Bool) -> ("dryRun" :? Bool) -> IO () -- | Parse a contract from Text. parseContract :: Maybe FilePath -> Text -> Either ParserException (Contract ParsedOp) -- | Parse a contract from Text and expand macros. parseExpandContract :: Maybe FilePath -> Text -> Either ParserException UntypedContract -- | Read and parse a contract from give path or stdin (if the -- argument is Nothing). The contract is not expanded. readAndParseContract :: Maybe FilePath -> IO (Contract ParsedOp) -- | Read a contract using readAndParseContract, expand and flatten. -- The contract is not type checked. prepareContract :: Maybe FilePath -> IO UntypedContract -- | State of a contract with code. data ContractState ContractState :: !Mutez -> !UntypedValue -> !UntypedContract -> ContractState -- | Amount of mutez owned by this contract. [csBalance] :: ContractState -> !Mutez -- | Storage value associated with this contract. [csStorage] :: ContractState -> !UntypedValue -- | Contract itself (untyped). [csContract] :: ContractState -> !UntypedContract -- | State of an arbitrary address. data AddressState -- | For contracts without code we store only its balance. ASSimple :: !Mutez -> AddressState -- | For contracts with code we store more state represented by -- ContractState. ASContract :: !ContractState -> AddressState -- | Data associated with a particular transaction. data TxData TxData :: !Address -> !UntypedValue -> !Mutez -> TxData [tdSenderAddress] :: TxData -> !Address [tdParameter] :: TxData -> !UntypedValue [tdAmount] :: TxData -> !Mutez -- | Operations executed by interpreter. In our model one Michelson's -- operation (operation type in Michelson) corresponds to 0 or 1 -- interpreter operation. -- -- Note: Address is not part of TxData, because -- TxData is supposed to be provided by the user, while -- Address can be computed by our code. data InterpreterOp -- | Originate a contract. OriginateOp :: !OriginationOperation -> InterpreterOp -- | Send a transaction to given address which is assumed to be the address -- of an originated contract. TransferOp :: Address -> TxData -> InterpreterOp -- | Result of a single execution of interpreter. data InterpreterRes InterpreterRes :: !GState -> [InterpreterOp] -> ![GStateUpdate] -> [(Address, InterpretUntypedResult MorleyLogs)] -> !Maybe Address -> !RemainingSteps -> InterpreterRes -- | New GState. [_irGState] :: InterpreterRes -> !GState -- | List of operations to be added to the operations queue. [_irOperations] :: InterpreterRes -> [InterpreterOp] -- | Updates applied to GState. [_irUpdates] :: InterpreterRes -> ![GStateUpdate] -- | During execution a contract can print logs and in the end it returns a -- pair. All logs and returned values are kept until all called contracts -- are executed. In the end they are printed. [_irInterpretResults] :: InterpreterRes -> [(Address, InterpretUntypedResult MorleyLogs)] -- | As soon as transfer operation is encountered, this address is set to -- its input. [_irSourceAddress] :: InterpreterRes -> !Maybe Address -- | Now much gas all remaining executions can consume. [_irRemainingSteps] :: InterpreterRes -> !RemainingSteps -- | Errors that can happen during contract interpreting. data InterpreterError -- | The interpreted contract hasn't been originated. IEUnknownContract :: !Address -> InterpreterError -- | Interpretation of Michelson contract failed. IEInterpreterFailed :: !Address -> !InterpretUntypedError MorleyLogs -> InterpreterError -- | A contract is already originated. IEAlreadyOriginated :: !Address -> !ContractState -> InterpreterError -- | Sender address is unknown. IEUnknownSender :: !Address -> InterpreterError -- | Manager address is unknown. IEUnknownManager :: !Address -> InterpreterError -- | Sender doesn't have enough funds. IENotEnoughFunds :: !Address -> !Mutez -> InterpreterError -- | Failed to apply updates to GState. IEFailedToApplyUpdates :: !GStateUpdateError -> InterpreterError -- | A contract is ill-typed. IEIllTypedContract :: !TCError -> InterpreterError -- | Implementation of interpreter outside IO. It reads operations, -- interprets them one by one and updates state accordingly. interpreterPure :: Timestamp -> RemainingSteps -> GState -> [InterpreterOp] -> Either InterpreterError InterpreterRes instance GHC.Show.Show Morley.Runtime.InterpreterError instance Formatting.Buildable.Buildable Morley.Runtime.InterpreterError instance GHC.Exception.Type.Exception Morley.Runtime.InterpreterError instance GHC.Show.Show Morley.Runtime.InterpreterRes instance GHC.Show.Show Morley.Runtime.InterpreterOp -- | Utilities for integrational testing. Example tests can be found in the -- 'morley-test' test suite. module Morley.Test.Integrational -- | Data associated with a particular transaction. data TxData TxData :: !Address -> !UntypedValue -> !Mutez -> TxData [tdSenderAddress] :: TxData -> !Address [tdParameter] :: TxData -> !UntypedValue [tdAmount] :: TxData -> !Mutez -- | Initially this address has a lot of money. genesisAddress :: Address -- | Validator for integrational testing. If an error is expected, it -- should be Left with validator for errors. Otherwise it should -- check final global state and its updates. type IntegrationalValidator = Either (InterpreterError -> Bool) SuccessValidator -- | Validator for integrational testing that expects successful execution. type SuccessValidator = (GState -> [GStateUpdate] -> Either Text ()) type IntegrationalScenario = IntegrationalScenarioM Validated -- | Integrational test that executes given operations and validates them -- using given validator. It can fail using Expectation -- capability. It starts with initGState and some reasonable dummy -- values for gas limit and current timestamp. You can update blockchain -- state by performing some operations. integrationalTestExpectation :: IntegrationalScenario -> Expectation -- | Integrational test similar to integrationalTestExpectation. It -- can fail using Property capability. It can be used with -- QuickCheck's forAll to make a property-based test with -- arbitrary data. integrationalTestProperty :: IntegrationalScenario -> Property -- | Originate a contract with given initial storage and balance. Its -- address is returned. originate :: UntypedContract -> UntypedValue -> Mutez -> IntegrationalScenarioM Address -- | Transfer tokens to given address. transfer :: TxData -> Address -> IntegrationalScenarioM () -- | Execute all operations that were added to the scenarion since last -- validate call. If validator fails, the execution will be -- aborted. validate :: IntegrationalValidator -> IntegrationalScenario -- | Make all further interpreter calls (which are triggered by the -- validate function) use given gas limit. setMaxSteps :: RemainingSteps -> IntegrationalScenarioM () -- | Make all further interpreter calls (which are triggered by the -- validate function) use given timestamp as the current one. setNow :: Timestamp -> IntegrationalScenarioM () -- | Compose two success validators. -- -- For example: -- -- expectBalance bal addr composeValidators -- expectStorageUpdateConst addr2 ValueUnit composeValidators :: SuccessValidator -> SuccessValidator -> SuccessValidator -- | Compose a list of success validators. composeValidatorsList :: [SuccessValidator] -> SuccessValidator -- | SuccessValidator that always passes. expectAnySuccess :: SuccessValidator -- | Check that storage value is updated for given address. Takes a -- predicate that is used to check the value. -- -- It works even if updates are not filtered (i. e. a value can be -- updated more than once). expectStorageUpdate :: Address -> (UntypedValue -> Either Text ()) -> SuccessValidator -- | Like expectStorageUpdate, but expects a constant. expectStorageUpdateConst :: Address -> UntypedValue -> SuccessValidator -- | Check that eventually address has some particular balance. expectBalance :: Address -> Mutez -> SuccessValidator -- | Check that eventually address has some particular storage value. expectStorageConst :: Address -> UntypedValue -> SuccessValidator -- | Check that interpreter failed due to gas exhaustion. expectGasExhaustion :: InterpreterError -> Bool -- | Expect that interpretation of contract with given address ended with -- [FAILED]. expectMichelsonFailed :: Address -> InterpreterError -> Bool -- | Functions to import contracts to be used in tests. module Morley.Test.Import readContract :: forall cp st. (Typeable cp, Typeable st) => FilePath -> Text -> Either ImportContractError (UntypedContract, Contract cp st) -- | Import contract and use it in the spec. Both versions of contract are -- passed to the callback function (untyped and typed). -- -- If contract's import failed, a spec with single failing expectation -- will be generated (so tests will run unexceptionally, but a failing -- result will notify about problem). specWithContract :: (Typeable cp, Typeable st) => FilePath -> ((UntypedContract, Contract cp st) -> Spec) -> Spec -- | A version of specWithContract which passes only the typed -- representation of the contract. specWithTypedContract :: (Typeable cp, Typeable st) => FilePath -> (Contract cp st -> Spec) -> Spec specWithUntypedContract :: FilePath -> (UntypedContract -> Spec) -> Spec -- | Import contract from a given file path. -- -- This function reads file, parses and type checks contract. -- -- This function may throw IOException and -- ImportContractError. importContract :: forall cp st. (Typeable cp, Typeable st) => FilePath -> IO (UntypedContract, Contract cp st) importUntypedContract :: FilePath -> IO UntypedContract -- | Error type for importContract function. data ImportContractError ICEUnexpectedParamType :: !Type -> !TypeRep -> ImportContractError ICEUnexpectedStorageType :: !Type -> !TypeRep -> ImportContractError ICEParse :: !ParserException -> ImportContractError ICETypeCheck :: !TCError -> ImportContractError instance GHC.Show.Show Morley.Test.Import.ImportContractError instance Formatting.Buildable.Buildable Morley.Test.Import.ImportContractError instance GHC.Exception.Type.Exception Morley.Test.Import.ImportContractError -- | Module containing some utilities for testing Michelson contracts using -- Haskell testing frameworks (hspec and QuickCheck in particular). It's -- Morley testing EDSL. module Morley.Test -- | Import contract and use it in the spec. Both versions of contract are -- passed to the callback function (untyped and typed). -- -- If contract's import failed, a spec with single failing expectation -- will be generated (so tests will run unexceptionally, but a failing -- result will notify about problem). specWithContract :: (Typeable cp, Typeable st) => FilePath -> ((UntypedContract, Contract cp st) -> Spec) -> Spec -- | A version of specWithContract which passes only the typed -- representation of the contract. specWithTypedContract :: (Typeable cp, Typeable st) => FilePath -> (Contract cp st -> Spec) -> Spec specWithUntypedContract :: FilePath -> (UntypedContract -> Spec) -> Spec type ContractReturn s st = (Either MichelsonFailed ([Operation Instr], Val Instr st), InterpreterState s) -- | Type for contract execution validation. -- -- It's a function which is supplied with contract execution output -- (failure or new storage with operation list). -- -- Function returns a property which type is designated by type variable -- prop and might be Property or Expectation or -- anything else relevant. type ContractPropValidator st prop = ContractReturn MorleyLogs st -> prop -- | Contract's property tester against given input. Takes contract -- environment, initial storage and parameter, interprets contract on -- this input and invokes validation function. contractProp :: (ToVal param, ToVal storage, ToT param ~ cp, ToT storage ~ st, Typeable cp, Typeable st) => Contract cp st -> ContractPropValidator st prop -> ContractEnv -> param -> storage -> prop -- | Version of contractProp which takes Val as arguments -- instead of regular Haskell values. contractPropVal :: (Typeable cp, Typeable st) => Contract cp st -> ContractPropValidator st prop -> ContractEnv -> Val Instr cp -> Val Instr st -> prop -- | Validator for integrational testing. If an error is expected, it -- should be Left with validator for errors. Otherwise it should -- check final global state and its updates. type IntegrationalValidator = Either (InterpreterError -> Bool) SuccessValidator -- | Validator for integrational testing that expects successful execution. type SuccessValidator = (GState -> [GStateUpdate] -> Either Text ()) type IntegrationalScenario = IntegrationalScenarioM Validated -- | Integrational test that executes given operations and validates them -- using given validator. It can fail using Expectation -- capability. It starts with initGState and some reasonable dummy -- values for gas limit and current timestamp. You can update blockchain -- state by performing some operations. integrationalTestExpectation :: IntegrationalScenario -> Expectation -- | Integrational test similar to integrationalTestExpectation. It -- can fail using Property capability. It can be used with -- QuickCheck's forAll to make a property-based test with -- arbitrary data. integrationalTestProperty :: IntegrationalScenario -> Property -- | Originate a contract with given initial storage and balance. Its -- address is returned. originate :: UntypedContract -> UntypedValue -> Mutez -> IntegrationalScenarioM Address -- | Transfer tokens to given address. transfer :: TxData -> Address -> IntegrationalScenarioM () -- | Execute all operations that were added to the scenarion since last -- validate call. If validator fails, the execution will be -- aborted. validate :: IntegrationalValidator -> IntegrationalScenario -- | Make all further interpreter calls (which are triggered by the -- validate function) use given gas limit. setMaxSteps :: RemainingSteps -> IntegrationalScenarioM () -- | Make all further interpreter calls (which are triggered by the -- validate function) use given timestamp as the current one. setNow :: Timestamp -> IntegrationalScenarioM () -- | Compose two success validators. -- -- For example: -- -- expectBalance bal addr composeValidators -- expectStorageUpdateConst addr2 ValueUnit composeValidators :: SuccessValidator -> SuccessValidator -> SuccessValidator -- | Compose a list of success validators. composeValidatorsList :: [SuccessValidator] -> SuccessValidator -- | SuccessValidator that always passes. expectAnySuccess :: SuccessValidator -- | Check that storage value is updated for given address. Takes a -- predicate that is used to check the value. -- -- It works even if updates are not filtered (i. e. a value can be -- updated more than once). expectStorageUpdate :: Address -> (UntypedValue -> Either Text ()) -> SuccessValidator -- | Like expectStorageUpdate, but expects a constant. expectStorageUpdateConst :: Address -> UntypedValue -> SuccessValidator -- | Check that eventually address has some particular balance. expectBalance :: Address -> Mutez -> SuccessValidator -- | Check that eventually address has some particular storage value. expectStorageConst :: Address -> UntypedValue -> SuccessValidator -- | Check that interpreter failed due to gas exhaustion. expectGasExhaustion :: InterpreterError -> Bool -- | Expect that interpretation of contract with given address ended with -- [FAILED]. expectMichelsonFailed :: Address -> InterpreterError -> Bool -- | Data associated with a particular transaction. data TxData TxData :: !Address -> !UntypedValue -> !Mutez -> TxData [tdSenderAddress] :: TxData -> !Address [tdParameter] :: TxData -> !UntypedValue [tdAmount] :: TxData -> !Mutez -- | Initially this address has a lot of money. genesisAddress :: Address -- | A Property that always failes with given message. failedProp :: Text -> Property -- | A Property that always succeeds. succeededProp :: Property -- | The Property holds on `Left a`. qcIsLeft :: Show b => Either a b -> Property -- | The Property holds on `Right b`. qcIsRight :: Show a => Either a b -> Property -- | Dummy ContractEnv with some reasonable hardcoded values. You -- can override values you are interested in using record update syntax. dummyContractEnv :: ContractEnv -- | Minimal (earliest) timestamp used for Arbitrary (CVal -- 'CTimestamp) minTimestamp :: Timestamp -- | Maximal (latest) timestamp used for Arbitrary (CVal -- 'CTimestamp) maxTimestamp :: Timestamp -- | Median of minTimestamp and maxTimestamp. Useful for -- testing (exactly half of generated dates will be before and after this -- date). midTimestamp :: Timestamp