# Plutus.V1.Ledger.Scripts

* 1\. 📜 Overview
* 2\. 🔧 LANGUAGE PRAGMAS AND IMPORTS
* 3\. 🗄️ Core Types
  * 3.1 🖥️ Script
  * 3.2 📐 Validator, MintingPolicy, StakeValidator
  * 3.3 📊 Datum, Redeemer, Context
  * 3.4 🔑 Hash Types
  * 3.5 ⚙️ ScriptError
* 4\. ⚙️ Key Functions
  * 4.1 📏 scriptSize
  * 4.2 🔄 fromCompiledCode
  * 4.3 🏗️ applyArguments
  * 4.4 🚀 evaluateScript
  * 4.5 🎬 runScript / runMintingPolicyScript / runStakeValidatorScript
  * 4.6 🔗 applyValidator / applyMintingPolicyScript / applyStakeValidatorScript
  * 4.7 📚 unitDatum, unitRedeemer
* 5\. 🤝 Typeclass Instances
* 6\. 🏭 On-Chain Derivations
* 7\. 📚 Glossary

***

### 1 📜 Overview

The `Plutus.V1.Ledger.Scripts` module provides the core abstractions and utilities for working with on-chain scripts in Plutus:

* **`Script`**: opaque representation of a UPLC program.
* **Wrappers**: `Validator`, `MintingPolicy`, and `StakeValidator` for specific script roles.
* **Data wrappers**: `Datum`, `Redeemer`, and `Context` for script inputs.
* **Hash types**: `ScriptHash`, `ValidatorHash`, `DatumHash`, etc., for script identification.
* **Evaluation**: functions to apply and run scripts, extracting budgets and logs.
* **Utilities**: `scriptSize`, `fromCompiledCode`, `applyArguments`, and example `unitDatum`/`unitRedeemer`.

***

### 2 🔧 LANGUAGE PRAGMAS AND IMPORTS

```haskell
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE DerivingVia         #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE FlexibleInstances   #-}
{-# LANGUAGE LambdaCase          #-}
{-# LANGUAGE NoImplicitPrelude   #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE PatternSynonyms     #-}
{-# LANGUAGE RankNTypes          #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeOperators       #-}
{-# LANGUAGE ViewPatterns        #-}

{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_GHC -fno-specialise     #-}
{-# OPTIONS_GHC -fno-warn-name-shadowing #-}

module Plutus.V1.Ledger.Scripts where

import qualified Prelude                as Haskell
import Codec.Serialise        (Serialise, serialise)
import Codec.CBOR.Extras      (SerialiseViaFlat(..))
import Control.DeepSeq        (NFData)
import Control.Lens           (over)
import Control.Monad.Except   (MonadError, throwError)
import Data.ByteString.Lazy   qualified as BSL
import Data.String            (IsString)
import Data.Text              (Text)
import GHC.Generics           (Generic)
import Plutus.V1.Ledger.Bytes (LedgerBytes(..))
import PlutusTx               (CompiledCode, ToData, FromData, UnsafeFromData, getPlc, makeLift)
import PlutusTx.Builtins      as Builtins
import PlutusTx.Prelude
import Prettyprinter
import Prettyprinter.Extras   (PrettyShow(..))
import PlutusCore             qualified as PLC
import PlutusCore.Data        qualified as PLC
import PlutusCore.MkPlc       qualified as PLC
import UntypedPlutusCore      qualified as UPLC
import UntypedPlutusCore.Check.Scope qualified as UPLC
import UntypedPlutusCore.Evaluation.Machine.Cek qualified as UPLC
```

* Extensive pragmas for generics, template Haskell, and disabling warnings for orphans and name shadowing.
* Imports for serialization, ByteString, builtins, and untpye UPLC modules.

***

### 3 🗄️ Core Types

#### 3.1 🖥️ Script

```haskell
newtype Script = Script { unScript :: UPLC.Program UPLC.DeBruijn PLC.DefaultUni PLC.DefaultFun () }
```

* Opaque wrapper around UPLC `Program`.
* **Instances:** `Generic`, `NFData`, `Serialise` via Flat.

#### 3.2 📐 Validator, MintingPolicy, StakeValidator

```haskell
newtype Validator = Validator { getValidator :: Script }
newtype MintingPolicy = MintingPolicy { getMintingPolicy :: Script }
newtype StakeValidator = StakeValidator { getStakeValidator :: Script }
```

* Role-specific wrappers adding `Eq`, `Ord`, `Serialise`, `Pretty` via `LedgerBytes`.

#### 3.3 📊 Datum, Redeemer, Context

```haskell
newtype Datum = Datum { getDatum :: BuiltinData }
newtype Redeemer = Redeemer { getRedeemer :: BuiltinData }
newtype Context = Context BuiltinData
```

* Wrap `BuiltinData` for script inputs and blockchain context.

#### 3.4 🔑 Hash Types

```haskell
newtype ScriptHash = ScriptHash Builtins.BuiltinByteString    deriving via LedgerBytes
newtype ValidatorHash = ValidatorHash Builtins.BuiltinByteString deriving via LedgerBytes
-- similarly: DatumHash, RedeemerHash, MintingPolicyHash, StakeValidatorHash
```

* String literals via `IsString`, `Eq`, `Ord`, `ToData`, `FromData`, `UnsafeFromData`, `Pretty` via `LedgerBytes`.

#### 3.5 ⚙️ ScriptError

```haskell
data ScriptError = EvaluationError [Text] String | EvaluationException String String
```

* Captures expected user errors vs internal evaluation exceptions.

***

### 4 ⚙️ Key Functions

#### 4.1 📏 scriptSize

```haskell
scriptSize :: Script -> Integer
scriptSize (Script s) = UPLC.programSize s
```

* Returns serialized program size.

#### 4.2 🔄 fromCompiledCode

```haskell
fromCompiledCode :: CompiledCode a -> Script
```

* Converts GHC-compiled Plutus Tx code into nameless `Script`.

#### 4.3 🏗️ applyArguments

```haskell
applyArguments :: Script -> [PLC.Data] -> Script
```

* Applies a list of `Data` arguments to a UPLC program.

#### 4.4 🚀 evaluateScript

```haskell
evaluateScript :: MonadError ScriptError m => Script -> m (PLC.ExBudget, [Text])
```

* Runs the CEK evaluator, returning resource budget and log, or throws `ScriptError`.

#### 4.5 🎬 runScript / runMintingPolicyScript / runStakeValidatorScript

```haskell
runScript :: Context -> Validator -> Datum -> Redeemer -> m (PLC.ExBudget,[Text])
runMintingPolicyScript :: Context -> MintingPolicy -> Redeemer -> m (...)
runStakeValidatorScript :: Context -> StakeValidator -> Redeemer -> m (...)
```

* Helper functions combining application and evaluation.

#### 4.6 🔗 applyValidator / applyMintingPolicyScript / applyStakeValidatorScript

```haskell
applyValidator :: Context -> Validator -> Datum -> Redeemer -> Script
```

* Applies wrapper types to produce a `Script` with applied arguments.

#### 4.7 📚 unitDatum, unitRedeemer

```haskell
unitDatum :: Datum
unitRedeemer :: Redeemer
```

* Convenience values for `()` data.

***

### 5 🤝 Typeclass Instances

* **`Eq Script`, `Ord Script`**: based on serialized bytes for alpha-equivalence.
* **`Show Script`**: prints `<Script>` placeholder.
* **`Pretty`** via `PrettyShow` for wrappers.
* **`Functor`** for `applyArguments` uses `PLC.mkIterApp`.

***

### 6 🏭 On-Chain Derivations

```haskell
makeLift ''ScriptHash
makeLift ''ValidatorHash
makeLift ''DatumHash
makeLift ''RedeemerHash
makeLift ''MintingPolicyHash
makeLift ''StakeValidatorHash
makeLift ''Datum
makeLift ''Redeemer
```

* Enables embedding these types in PlutusTx code.

***

### 7 📚 Glossary

* **UPLC**: Untyped Plutus Core.
* **CEK**: evaluation machine for Plutus Core.
* **BuiltinData**: on-chain data type.
* **Script**: on-chain program encoded as UPLC.
* **Validator/MintingPolicy/StakeValidator**: typed script roles.
* **Datum/Redeemer/Context**: inputs to validators.
* **ScriptHash/ValidatorHash/etc.**: hashed identifiers for scripts.
* **CompiledCode**: code produced by PlutusTx compiler plugin.
* **SerialiseViaFlat**: CBOR using Flat serialization for programs.
* **ProgramSize**: approximate resource usage metric.
* **Alpha-equivalence**: program equality modulo renaming.
