{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE TypeApplications  #-}
{-# LANGUAGE TypeFamilies      #-}


module PlutusExample.PlutusVersion2.RedeemerContextEquivalence
  ( PV2CustomRedeemer (..)
  , v2ScriptContextEquivalenceScript
  , v2ScriptContextEquivalenceSbs
  , v2mintEquivScript
  , v2mintEquivScriptShortBs
  ) where

import Prelude hiding (($))

import Cardano.Api.Shelley
import Prelude hiding (($), (&&))

import Codec.Serialise
import Data.ByteString.Lazy qualified as LBS
import Data.ByteString.Short qualified as SBS


import Plutus.Script.Utils.Typed as Scripts
import Plutus.V2.Ledger.Api qualified as V2
import Plutus.V2.Ledger.Contexts as V2
import PlutusTx qualified
import PlutusTx.Prelude as PlutusPrelude hiding (Semigroup (..), unless, (.))

newtype MyCustomDatumV2 = MyCustomDatumV2 Integer

data PV2CustomRedeemer
  = PV2CustomRedeemer
      { PV2CustomRedeemer -> [TxInInfo]
pv2Inputs        :: [V2.TxInInfo]
      , PV2CustomRedeemer -> [TxInInfo]
pv2RefInputs     :: [V2.TxInInfo]
      , PV2CustomRedeemer -> [TxOut]
pv2Outputs       :: [V2.TxOut]
      , PV2CustomRedeemer -> Value
pv2Fee           :: V2.Value
      , PV2CustomRedeemer -> Value
pv2Mint          :: V2.Value
      , PV2CustomRedeemer -> [DCert]
pv2DCert         :: [V2.DCert]
      , PV2CustomRedeemer -> Map StakingCredential Integer
pv2Wdrl          :: V2.Map V2.StakingCredential Integer
      , PV2CustomRedeemer -> POSIXTimeRange
pv2ValidRange    :: V2.POSIXTimeRange
      , PV2CustomRedeemer -> [PubKeyHash]
pv2Signatories   :: [V2.PubKeyHash]
      , PV2CustomRedeemer -> Map ScriptPurpose Redeemer
pv2Redeemers     :: V2.Map ScriptPurpose V2.Redeemer
      , PV2CustomRedeemer -> Map DatumHash Datum
pv2Data          :: V2.Map V2.DatumHash V2.Datum
      , PV2CustomRedeemer -> Maybe ScriptPurpose
pv2ScriptPurpose :: Maybe V2.ScriptPurpose
      } deriving (PV2CustomRedeemer -> PV2CustomRedeemer -> Bool
(PV2CustomRedeemer -> PV2CustomRedeemer -> Bool)
-> (PV2CustomRedeemer -> PV2CustomRedeemer -> Bool)
-> Eq PV2CustomRedeemer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PV2CustomRedeemer -> PV2CustomRedeemer -> Bool
$c/= :: PV2CustomRedeemer -> PV2CustomRedeemer -> Bool
== :: PV2CustomRedeemer -> PV2CustomRedeemer -> Bool
$c== :: PV2CustomRedeemer -> PV2CustomRedeemer -> Bool
Prelude.Eq, Int -> PV2CustomRedeemer -> ShowS
[PV2CustomRedeemer] -> ShowS
PV2CustomRedeemer -> String
(Int -> PV2CustomRedeemer -> ShowS)
-> (PV2CustomRedeemer -> String)
-> ([PV2CustomRedeemer] -> ShowS)
-> Show PV2CustomRedeemer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PV2CustomRedeemer] -> ShowS
$cshowList :: [PV2CustomRedeemer] -> ShowS
show :: PV2CustomRedeemer -> String
$cshow :: PV2CustomRedeemer -> String
showsPrec :: Int -> PV2CustomRedeemer -> ShowS
$cshowsPrec :: Int -> PV2CustomRedeemer -> ShowS
Show)

PlutusTx.unstableMakeIsData ''MyCustomDatumV2
PlutusTx.unstableMakeIsData ''PV2CustomRedeemer

-- @(PV2CustomRedeemer inputs refInputs outputs fee mint dCert wdrl validRange signatories redeemers data)

{-# INLINABLE mkValidator #-}
mkValidator :: MyCustomDatumV2 -> PV2CustomRedeemer -> V2.ScriptContext -> Bool
mkValidator :: MyCustomDatumV2 -> PV2CustomRedeemer -> ScriptContext -> Bool
mkValidator MyCustomDatumV2
_ PV2CustomRedeemer
redeemer ScriptContext
scriptContext =
  -- These all work fine
  PV2CustomRedeemer -> TxInfo -> Bool
inputsAreEquivalent PV2CustomRedeemer
redeemer TxInfo
txInfo Bool -> Bool -> Bool
PlutusPrelude.&&
  PV2CustomRedeemer -> TxInfo -> Bool
referenceInputsAreEquivalent PV2CustomRedeemer
redeemer TxInfo
txInfo Bool -> Bool -> Bool
PlutusPrelude.&&
  PV2CustomRedeemer -> TxInfo -> Bool
certsAreEquivalent PV2CustomRedeemer
redeemer TxInfo
txInfo Bool -> Bool -> Bool
PlutusPrelude.&&
  PV2CustomRedeemer -> TxInfo -> Bool
reqSignersAreEquivalent PV2CustomRedeemer
redeemer TxInfo
txInfo Bool -> Bool -> Bool
PlutusPrelude.&&
  PV2CustomRedeemer -> TxInfo -> Bool
datumHashMapsAreEquivalent PV2CustomRedeemer
redeemer TxInfo
txInfo Bool -> Bool -> Bool
PlutusPrelude.&&
  PV2CustomRedeemer -> TxInfo -> Bool
outputsAreEquivalent PV2CustomRedeemer
redeemer TxInfo
txInfo Bool -> Bool -> Bool
PlutusPrelude.&&
  PV2CustomRedeemer -> TxInfo -> Bool
correctNumberOfRedeemers PV2CustomRedeemer
redeemer TxInfo
txInfo
  -- These below are failing
  -- validtyIntervalsAreEquivalent redeemer txInfo
  -- Inequality for validity interval doesnt work. Also the interval reported by the script context is a little ahead of
  -- what is in the transaction
  -- TODO: You can't check the fee with the build command due to how it's constructed
  -- These below have not been tested
  -- withdrawalsAreEquivalent redeemer txInfo
 where
  txInfo :: V2.TxInfo
  txInfo :: TxInfo
txInfo = ScriptContext -> TxInfo
V2.scriptContextTxInfo ScriptContext
scriptContext

  inputsAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  inputsAreEquivalent :: PV2CustomRedeemer -> TxInfo -> Bool
inputsAreEquivalent (PV2CustomRedeemer [TxInInfo]
inputs [TxInInfo]
_ [TxOut]
_ Value
_ Value
_ [DCert]
_ Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
_ Map ScriptPurpose Redeemer
_ Map DatumHash Datum
_ Maybe ScriptPurpose
_) TxInfo
tInfo =
    ((TxInInfo -> TxOut) -> [TxInInfo] -> [TxOut]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxInInfo -> TxOut
txInInfoResolved ([TxInInfo] -> [TxOut]) -> [TxInInfo] -> [TxOut]
forall a b. (a -> b) -> a -> b
$ TxInfo -> [TxInInfo]
V2.txInfoInputs TxInfo
tInfo) [TxOut] -> [TxOut] -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.==
    (TxInInfo -> TxOut) -> [TxInInfo] -> [TxOut]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxInInfo -> TxOut
txInInfoResolved [TxInInfo]
inputs

  referenceInputsAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  referenceInputsAreEquivalent :: PV2CustomRedeemer -> TxInfo -> Bool
referenceInputsAreEquivalent (PV2CustomRedeemer [TxInInfo]
_ [TxInInfo]
refInputs [TxOut]
_ Value
_ Value
_ [DCert]
_ Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
_ Map ScriptPurpose Redeemer
_ Map DatumHash Datum
_ Maybe ScriptPurpose
_) TxInfo
tInfo =
    ((TxInInfo -> TxOut) -> [TxInInfo] -> [TxOut]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxInInfo -> TxOut
txInInfoResolved ([TxInInfo] -> [TxOut]) -> [TxInInfo] -> [TxOut]
forall a b. (a -> b) -> a -> b
$ TxInfo -> [TxInInfo]
V2.txInfoReferenceInputs TxInfo
tInfo) [TxOut] -> [TxOut] -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.==
    (TxInInfo -> TxOut) -> [TxInInfo] -> [TxOut]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxInInfo -> TxOut
txInInfoResolved [TxInInfo]
refInputs

  outputsAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  outputsAreEquivalent :: PV2CustomRedeemer -> TxInfo -> Bool
outputsAreEquivalent (PV2CustomRedeemer [TxInInfo]
_ [TxInInfo]
_ [TxOut]
outputs Value
_ Value
_ [DCert]
_ Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
_ Map ScriptPurpose Redeemer
_ Map DatumHash Datum
_ Maybe ScriptPurpose
_) TxInfo
tInfo =
    let scOuts :: [TxOut]
scOuts = TxInfo -> [TxOut]
V2.txInfoOutputs TxInfo
tInfo
        scOutAddrs :: [Address]
scOutAddrs = (TxOut -> Address) -> [TxOut] -> [Address]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxOut -> Address
V2.txOutAddress [TxOut]
scOuts
        scOutValue :: [Value]
scOutValue = (TxOut -> Value) -> [TxOut] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxOut -> Value
V2.txOutValue [TxOut]
scOuts
        scOutDatums :: [OutputDatum]
scOutDatums = (TxOut -> OutputDatum) -> [TxOut] -> [OutputDatum]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxOut -> OutputDatum
V2.txOutDatum [TxOut]
scOuts
        scOutReferenceScripts :: [Maybe ScriptHash]
scOutReferenceScripts = (TxOut -> Maybe ScriptHash) -> [TxOut] -> [Maybe ScriptHash]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxOut -> Maybe ScriptHash
V2.txOutReferenceScript [TxOut]
scOuts

        redeemerOutAddrs :: [Address]
redeemerOutAddrs = (TxOut -> Address) -> [TxOut] -> [Address]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxOut -> Address
V2.txOutAddress [TxOut]
outputs
        redeemerOutValue :: [Value]
redeemerOutValue = (TxOut -> Value) -> [TxOut] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxOut -> Value
V2.txOutValue [TxOut]
outputs
        redeemerOutDatums :: [OutputDatum]
redeemerOutDatums = (TxOut -> OutputDatum) -> [TxOut] -> [OutputDatum]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxOut -> OutputDatum
V2.txOutDatum [TxOut]
outputs
        redeemerOutReferenceScripts :: [Maybe ScriptHash]
redeemerOutReferenceScripts = (TxOut -> Maybe ScriptHash) -> [TxOut] -> [Maybe ScriptHash]
forall a b. (a -> b) -> [a] -> [b]
PlutusPrelude.map TxOut -> Maybe ScriptHash
V2.txOutReferenceScript [TxOut]
outputs
    in ([Address]
scOutAddrs [Address] -> [Address] -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== [Address]
redeemerOutAddrs) Bool -> Bool -> Bool
PlutusPrelude.&&
       ([OutputDatum]
scOutDatums [OutputDatum] -> [OutputDatum] -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== [OutputDatum]
redeemerOutDatums) Bool -> Bool -> Bool
PlutusPrelude.&&
       ([Maybe ScriptHash]
scOutReferenceScripts [Maybe ScriptHash] -> [Maybe ScriptHash] -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== [Maybe ScriptHash]
redeemerOutReferenceScripts) Bool -> Bool -> Bool
PlutusPrelude.&&
       -- We want to see if out tx out specified in our tx is equal to one of the txouts in the
       -- script context. So we have a total of 4 outputs when we combine the outputs in the script
       -- context and the redeemer. This would be the two "normal" outputs and the two "change outputs"
       ([Value] -> Integer
forall (t :: * -> *) a. Foldable t => t a -> Integer
PlutusPrelude.length ([Value]
scOutValue [Value] -> [Value] -> [Value]
forall a. [a] -> [a] -> [a]
PlutusPrelude.++ [Value]
redeemerOutValue) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== Integer
4) Bool -> Bool -> Bool
PlutusPrelude.&&
       -- You would expect calling nub on the combined values, we should expect a length of 2. However
       -- the change outputs will be different because of how we construct the redeemer. Essentially we
       -- use an idential tx to generate our redeemer (and the redeemer in this tx is a default redeemer with nothing in it)
       -- and then we add that redeemer to a new transaction built with the `build` command. The problem is
       -- the fee and the change outputs created from the initial tx will be different because the size of
       -- the total tx is now different. Therefore we expect the length to be 3 since only the "normal"
       -- txouts are equivalent but the change outputs are different!
       ([Value] -> Integer
forall (t :: * -> *) a. Foldable t => t a -> Integer
PlutusPrelude.length ([Value] -> [Value]
forall a. Eq a => [a] -> [a]
nub ([Value] -> [Value]) -> [Value] -> [Value]
forall a b. (a -> b) -> a -> b
$ [Value]
scOutValue [Value] -> [Value] -> [Value]
forall a. [a] -> [a] -> [a]
PlutusPrelude.++ [Value]
redeemerOutValue) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== Integer
3)

  certsAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  certsAreEquivalent :: PV2CustomRedeemer -> TxInfo -> Bool
certsAreEquivalent (PV2CustomRedeemer [TxInInfo]
_ [TxInInfo]
_ [TxOut]
_ Value
_ Value
_ [DCert]
certs Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
_ Map ScriptPurpose Redeemer
_ Map DatumHash Datum
_ Maybe ScriptPurpose
_) TxInfo
tInfo =
    TxInfo -> [DCert]
V2.txInfoDCert TxInfo
tInfo [DCert] -> [DCert] -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== [DCert]
certs

  --validtyIntervalsAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  --validtyIntervalsAreEquivalent (PV2CustomRedeemer _ _ _ _ _ _ _ validInterval _ _ _) tInfo =
  --   (V2.txInfoValidRange tInfo) PlutusPrelude./= validInterval
    -- V2.ivFrom (V2.txInfoValidRange tInfo) PlutusPrelude.== V2.ivFrom validInterval Fails

  reqSignersAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  reqSignersAreEquivalent :: PV2CustomRedeemer -> TxInfo -> Bool
reqSignersAreEquivalent (PV2CustomRedeemer [TxInInfo]
_ [TxInInfo]
_ [TxOut]
_ Value
_ Value
_ [DCert]
_ Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
reqSigners Map ScriptPurpose Redeemer
_ Map DatumHash Datum
_ Maybe ScriptPurpose
_) TxInfo
tInfo =
    TxInfo -> [PubKeyHash]
V2.txInfoSignatories TxInfo
tInfo [PubKeyHash] -> [PubKeyHash] -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== [PubKeyHash]
reqSigners

  datumHashMapsAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  datumHashMapsAreEquivalent :: PV2CustomRedeemer -> TxInfo -> Bool
datumHashMapsAreEquivalent (PV2CustomRedeemer [TxInInfo]
_ [TxInInfo]
_ [TxOut]
_ Value
_ Value
_ [DCert]
_ Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
_ Map ScriptPurpose Redeemer
_ Map DatumHash Datum
datumHashMap Maybe ScriptPurpose
_) TxInfo
tInfo =
    TxInfo -> Map DatumHash Datum
V2.txInfoData TxInfo
tInfo Map DatumHash Datum -> Map DatumHash Datum -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== Map DatumHash Datum
datumHashMap

  correctNumberOfRedeemers :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  correctNumberOfRedeemers :: PV2CustomRedeemer -> TxInfo -> Bool
correctNumberOfRedeemers (PV2CustomRedeemer [TxInInfo]
_ [TxInInfo]
_ [TxOut]
_ Value
_ Value
_ [DCert]
_ Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
_ Map ScriptPurpose Redeemer
redeemers Map DatumHash Datum
_ Maybe ScriptPurpose
_) TxInfo
tInfo =
    Map ScriptPurpose Redeemer -> Integer
forall (t :: * -> *) a. Foldable t => t a -> Integer
PlutusPrelude.length (TxInfo -> Map ScriptPurpose Redeemer
V2.txInfoRedeemers TxInfo
tInfo) Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== Map ScriptPurpose Redeemer -> Integer
forall (t :: * -> *) a. Foldable t => t a -> Integer
PlutusPrelude.length Map ScriptPurpose Redeemer
redeemers

  -- TODO: not done yet
  --withdrawalsAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
  --withdrawalsAreEquivalent (PV2CustomRedeemer _ _ _ _ _ _ wdrwls _ _ _ _) tInfo =
  -- V2.txInfoWdrl tInfo PlutusPrelude.== wdrwls
  -- TODO: Also need to do separate minting script

validator :: V2.Validator
validator :: Validator
validator = CompiledCode (BuiltinData -> BuiltinData -> BuiltinData -> ())
-> Validator
V2.mkValidatorScript
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap :: BuiltinData -> BuiltinData -> BuiltinData -> ()
wrap = (MyCustomDatumV2 -> PV2CustomRedeemer -> ScriptContext -> Bool)
-> BuiltinData -> BuiltinData -> BuiltinData -> ()
forall sc d r.
(IsScriptContext sc, UnsafeFromData d, UnsafeFromData r) =>
(d -> r -> sc -> Bool)
-> BuiltinData -> BuiltinData -> BuiltinData -> ()
Scripts.mkUntypedValidator MyCustomDatumV2 -> PV2CustomRedeemer -> ScriptContext -> Bool
mkValidator

v2ScriptContextEquivalencePlutusScript :: V2.Script
v2ScriptContextEquivalencePlutusScript :: Script
v2ScriptContextEquivalencePlutusScript = Validator -> Script
V2.unValidatorScript Validator
validator

v2ScriptContextEquivalenceSbs :: SBS.ShortByteString
v2ScriptContextEquivalenceSbs :: ShortByteString
v2ScriptContextEquivalenceSbs =
  ByteString -> ShortByteString
SBS.toShort (ByteString -> ShortByteString)
-> (ByteString -> ByteString) -> ByteString -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
LBS.toStrict (ByteString -> ShortByteString) -> ByteString -> ShortByteString
forall a b. (a -> b) -> a -> b
$ Script -> ByteString
forall a. Serialise a => a -> ByteString
serialise Script
v2ScriptContextEquivalencePlutusScript

v2ScriptContextEquivalenceScript :: PlutusScript PlutusScriptV2
v2ScriptContextEquivalenceScript :: PlutusScript PlutusScriptV2
v2ScriptContextEquivalenceScript = ShortByteString -> PlutusScript PlutusScriptV2
forall lang. ShortByteString -> PlutusScript lang
PlutusScriptSerialised ShortByteString
v2ScriptContextEquivalenceSbs

-- Mint field and script purpose equivalence equivalence

{-# INLINABLE mkMintEquivalenceValidator #-}
mkMintEquivalenceValidator :: PV2CustomRedeemer -> V2.ScriptContext -> Bool
mkMintEquivalenceValidator :: PV2CustomRedeemer -> ScriptContext -> Bool
mkMintEquivalenceValidator PV2CustomRedeemer
redeemer ScriptContext
scriptContext =
  -- Minted value is equivalent
  PV2CustomRedeemer -> TxInfo -> Bool
mintingFieldsAreEquivalent PV2CustomRedeemer
redeemer TxInfo
txInfo Bool -> Bool -> Bool
PlutusPrelude.&&
  -- Script purpose is equivalent
  ScriptContext -> PV2CustomRedeemer -> Bool
scriptPurposeIsEquivalent ScriptContext
scriptContext PV2CustomRedeemer
redeemer
 where
   txInfo :: V2.TxInfo
   txInfo :: TxInfo
txInfo = ScriptContext -> TxInfo
V2.scriptContextTxInfo ScriptContext
scriptContext

   mintingFieldsAreEquivalent :: PV2CustomRedeemer -> V2.TxInfo -> Bool
   mintingFieldsAreEquivalent :: PV2CustomRedeemer -> TxInfo -> Bool
mintingFieldsAreEquivalent (PV2CustomRedeemer [TxInInfo]
_ [TxInInfo]
_ [TxOut]
_ Value
_ Value
mint [DCert]
_ Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
_ Map ScriptPurpose Redeemer
_ Map DatumHash Datum
_ Maybe ScriptPurpose
_) TxInfo
tInfo =
    TxInfo -> Value
V2.txInfoMint TxInfo
tInfo  Value -> Value -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== Value
mint

   scriptPurposeIsEquivalent :: V2.ScriptContext -> PV2CustomRedeemer -> Bool
   scriptPurposeIsEquivalent :: ScriptContext -> PV2CustomRedeemer -> Bool
scriptPurposeIsEquivalent ScriptContext
sc (PV2CustomRedeemer [TxInInfo]
_ [TxInInfo]
_ [TxOut]
_ Value
_ Value
_ [DCert]
_ Map StakingCredential Integer
_ POSIXTimeRange
_ [PubKeyHash]
_ Map ScriptPurpose Redeemer
_ Map DatumHash Datum
_ Maybe ScriptPurpose
mScPurpose) =
    case Maybe ScriptPurpose
mScPurpose of
      Just ScriptPurpose
sPurp -> ScriptContext -> ScriptPurpose
V2.scriptContextPurpose ScriptContext
sc ScriptPurpose -> ScriptPurpose -> Bool
forall a. Eq a => a -> a -> Bool
PlutusPrelude.== ScriptPurpose
sPurp
      Maybe ScriptPurpose
Nothing    -> () -> Bool
forall a. () -> a
PlutusPrelude.error ()

policy :: V2.MintingPolicy
policy :: MintingPolicy
policy = CompiledCode (BuiltinData -> BuiltinData -> ()) -> MintingPolicy
V2.mkMintingPolicyScript $$(PlutusTx.compile [|| wrap ||])
 where
  wrap :: BuiltinData -> BuiltinData -> ()
wrap = (PV2CustomRedeemer -> ScriptContext -> Bool)
-> BuiltinData -> BuiltinData -> ()
forall sc r.
(IsScriptContext sc, UnsafeFromData r) =>
(r -> sc -> Bool) -> BuiltinData -> BuiltinData -> ()
Scripts.mkUntypedMintingPolicy PV2CustomRedeemer -> ScriptContext -> Bool
mkMintEquivalenceValidator

plutusMintEquivScript :: V2.Script
plutusMintEquivScript :: Script
plutusMintEquivScript =
  MintingPolicy -> Script
V2.unMintingPolicyScript MintingPolicy
policy

mintEquivValidator :: V2.Validator
mintEquivValidator :: Validator
mintEquivValidator = Script -> Validator
V2.Validator Script
plutusMintEquivScript

scriptAsCbor :: LBS.ByteString
scriptAsCbor :: ByteString
scriptAsCbor = Validator -> ByteString
forall a. Serialise a => a -> ByteString
serialise Validator
mintEquivValidator

v2mintEquivScript :: PlutusScript PlutusScriptV2
v2mintEquivScript :: PlutusScript PlutusScriptV2
v2mintEquivScript = ShortByteString -> PlutusScript PlutusScriptV2
forall lang. ShortByteString -> PlutusScript lang
PlutusScriptSerialised (ShortByteString -> PlutusScript PlutusScriptV2)
-> (ByteString -> ShortByteString)
-> ByteString
-> PlutusScript PlutusScriptV2
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ShortByteString
SBS.toShort (ByteString -> PlutusScript PlutusScriptV2)
-> ByteString -> PlutusScript PlutusScriptV2
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
LBS.toStrict ByteString
scriptAsCbor

v2mintEquivScriptShortBs :: SBS.ShortByteString
v2mintEquivScriptShortBs :: ShortByteString
v2mintEquivScriptShortBs = ByteString -> ShortByteString
SBS.toShort (ByteString -> ShortByteString)
-> (ByteString -> ByteString) -> ByteString -> ShortByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> ByteString
LBS.toStrict (ByteString -> ShortByteString) -> ByteString -> ShortByteString
forall a b. (a -> b) -> a -> b
$ ByteString
scriptAsCbor