content: {-# LANGUAGE DataKinds #-}
  {-# LANGUAGE NoImplicitPrelude #-}
  {-# LANGUAGE TemplateHaskell #-}
  {-# LANGUAGE TypeApplications #-}
  {-# LANGUAGE TypeFamilies #-}
  
  module Cardano.Benchmarking.PlutusScripts.SupplementalDatum (script) where
  
  import           Cardano.Api (PlutusScript (..), PlutusScriptV3, PlutusScriptVersion (..),
                     Script (..), toScriptInAnyLang)
  
  import           Cardano.Benchmarking.ScriptAPI
  import qualified PlutusLedgerApi.V3 as V3
  import qualified PlutusLedgerApi.V3.Contexts as V3
  
  import           Prelude as Haskell (String, (.), (<$>))
  
  import qualified Data.ByteString.Short as SBS
  
  import           Language.Haskell.TH
  import           Language.Haskell.TH.Syntax
  import           PlutusTx
  import qualified PlutusTx.Builtins as PlutusTx
  import           PlutusTx.Prelude as Tx hiding (Semigroup (..), (.), (<$>))
  import qualified PlutusTx.Prelude as PlutusTx
  
  scriptName :: Haskell.String
  scriptName
    = prepareScriptName $(LitE . StringL . loc_module <$> qLocation)
  
  script :: PlutusBenchScript
  script = mkPlutusBenchScript scriptName (toScriptInAnyLang (PlutusScript PlutusScriptV3 scriptSerialized))
  
  -- | Write to disk with: cabal run plutus-scripts-bench -- print SupplementalDatum -o supplemental-datum.plutus
  {-# INLINABLE typedValidator #-}
  typedValidator :: V3.ScriptContext -> Bool
  typedValidator scriptContext =
      PlutusTx.isJust (V3.findDatum supplementalDatumHash txInfo)
    where
      txInfo = V3.scriptContextTxInfo scriptContext
  
  {- On chain we are dealing with raw bytes. You can generate the datum hash from the cli via:
  > cardano-cli transaction hash-script-data --script-data-value 1
  > ee155ace9c40292074cb6aff8c9ccdd273c81648ff1149ef36bcea6ebb8a3e25
  However this result is hex encoded. Therefore we have to convert to decimal notation and then use `integerToByteString` to convert to bytes.
   -}
  {-# INLINABLE supplementalDatumHash  #-}
  supplementalDatumHash :: V3.DatumHash
  supplementalDatumHash = V3.DatumHash $ PlutusTx.integerToByteString PlutusTx.BigEndian 0 107688188478553082748947992068553556338831975613033640413719911361848497815077
  
  {-# INLINABLE untypedValidator  #-}
  untypedValidator :: BuiltinData -> BuiltinUnit
  untypedValidator ctx =
    PlutusTx.check (typedValidator (PlutusTx.unsafeFromBuiltinData ctx) )
  
  supplementalDatumBs :: SBS.ShortByteString
  supplementalDatumBs = V3.serialiseCompiledCode $$(PlutusTx.compile [|| untypedValidator ||])
  
  scriptSerialized :: PlutusScript PlutusScriptV3
  scriptSerialized = PlutusScriptSerialised supplementalDatumBs
  