{-# LANGUAGE DataKinds           #-}  --Enable datatype promotions
Enable flexible contexts . Implied by 
Do n't load native prelude to avoid conflict with PlutusTx . Prelude
# LANGUAGE ScopedTypeVariables #
# LANGUAGE TemplateHaskell      #
# LANGUAGE TypeApplications     #
# LANGUAGE TypeFamilies         #
{-# LANGUAGE TypeOperators       #-}  --Allow the use and definition of types with operator names

module AlwaysSucceedandFail where

PlutusTx
import           PlutusTx                       (Data (..))
import qualified PlutusTx
import qualified PlutusTx.Builtins              as Builtins
import           PlutusTx.Prelude               hiding (Semigroup(..), unless)
--Contract Monad
import           Plutus.Contract               
--Ledger 
import           Ledger                         hiding (singleton)
import qualified Ledger.Address                 as V1Address
  Same library name , different functions for V1 and V2 in some cases
import qualified Ledger . Scripts                as Scripts               
  New library name for Typed  and some new fuctions
import           Ledger.Ada                     as Ada
Trace Emulator
import           Plutus.Trace
import qualified Plutus.Trace.Emulator          as Emulator
import qualified Wallet.Emulator.Wallet         as Wallet
  ( broken ) 
 import            Playground . Contract             ( printJson , printSchemas , ensureKnownCurrencies , stage ) 
 import            Playground . TH                   ( mkKnownCurrencies , mkSchemaDefinitions ) 
 import            Playground . Types                (  ( .. ) ) 
 --"Normal " Haskell
import           Playground.Contract            (printJson, printSchemas, ensureKnownCurrencies, stage)
import           Playground.TH                  (mkKnownCurrencies, mkSchemaDefinitions)
import           Playground.Types               (KnownCurrency (..))
--"Normal" Haskell -}
import           Control.Monad                  hiding (fmap)
import           Data.Map                       as Map
import           Data.Text                      (Text)
import           Data.Void                      (Void)
import           Prelude                        (IO, Semigroup (..), String, show)
import           Text.Printf                    (printf)
import           Control.Monad.Freer.Extras     as Extras


# OPTIONS_GHC -fno - warn - unused - imports #

--THE ON-CHAIN CODE

# INLINABLE alwaysSucceeds #
alwaysSucceeds :: BuiltinData -> BuiltinData -> BuiltinData -> ()   -- the value of this function is on its sideeffects
alwaysSucceeds _ _ _ = () 

# INLINABLE alwaysFails #
alwaysFails :: BuiltinData -> BuiltinData -> BuiltinData -> ()   
alwaysFails _ _ _ = error () 

validator :: Validator
validator = mkValidatorScript $$(PlutusTx.compile [|| alwaysSucceeds ||])  

valHash :: Ledger.ValidatorHash
valHash = Scripts.validatorHash validator  

scrAddress :: V1Address.Address
  Could n't find a new version of scriptAddress for unTyped Scripts
--replaces
--scrAddress = scriptAddress validator 


--THE OFFCHAIN CODE

type GiftSchema =
            Endpoint "give" Integer  --An Integer Parameter
        .\/ Endpoint "grab" ()

give :: AsContractError e => Integer -> Contract w s e ()
give amount = do
This Tx needs an output , that s its going to be the Script Address , Datum MUST be specified , so is created and the ammount of lovelaces
This line submit the Tx
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx                                                --This line waits for confirmation
    Plutus.Contract.logInfo @String $ printf "made a gift of %d lovelace" amount                                     --This line log info,usable on the PP(Plutus Playground)
    
grab :: forall w s e. AsContractError e => Contract w s e ()                                     
grab = do
    utxos <- utxosAt scrAddress                                                                      -- This will find all UTXOs that sit at the script address
    let orefs   = fst <$> Map.toList utxos                                                           -- This get all the references of the UTXOs
        lookups = Constraints.unspentOutputs utxos      <>                                           -- Tell where to find all the UTXOS
  and inform about the actual validator ( the spending tx needs to provide the actual validator )
        tx :: TxConstraints Void Void                                                            
  Define the TX giving constrains , one for each UTXO sitting on this addrs ,
                                                                                                     -- must provide a redeemer (ignored in this case)
  Allow the wallet to construct the tx with the necesary information
    void $ awaitTxConfirmed $ getCardanoTxId ledgerTx                                                -- Wait for confirmation
    Plutus.Contract.logInfo @String $ "collected gifts"                                                              -- Log information 

endpoints :: Contract () GiftSchema Text ()
endpoints = awaitPromise (give' `select` grab') >> endpoints                                         -- Asynchronously wait for the endpoints interactions from the wallet
  where                                                                                              -- and recursively wait for the endpoints all over again
    give' = endpoint @"give" give                                                                    -- block until give
    grab' = endpoint @"grab" $ const grab                                                            -- block until grab

  Playground broken at the moment - September 2022
  mkSchemaDefinitions '' GiftSchema                                                                      -- Generate the Schema for the playground
-- mkKnownCurrencies [] 

--SIMULATION

test :: IO ()
test = runEmulatorTraceIO $ do
    h1 <- activateContractWallet (Wallet.knownWallet 1) endpoints
    h2 <- activateContractWallet (Wallet.knownWallet 2) endpoints
    callEndpoint @"give" h1 $ 51000000
    void $ Emulator.waitNSlots 11
    callEndpoint @"grab" h2 ()
    s <- Emulator.waitNSlots 11
    Extras.logInfo $ "End of Simulation at slot " ++ show s
# LANGUAGE DataKinds           #
Enable datatype promotions
# LANGUAGE TypeOperators       #
Allow the use and definition of types with operator names
Contract Monad
Ledger 
"Normal " Haskell
"Normal" Haskell -}
THE ON-CHAIN CODE
 the value of this function is on its sideeffects
replaces
scrAddress = scriptAddress validator 
THE OFFCHAIN CODE
An Integer Parameter
This line waits for confirmation
This line log info,usable on the PP(Plutus Playground)
 This will find all UTXOs that sit at the script address
 This get all the references of the UTXOs
 Tell where to find all the UTXOS
 must provide a redeemer (ignored in this case)
 Wait for confirmation
 Log information 
 Asynchronously wait for the endpoints interactions from the wallet
 and recursively wait for the endpoints all over again
 block until give
 block until grab
 Generate the Schema for the playground
 mkKnownCurrencies [] 
SIMULATION
Enable flexible contexts . Implied by 
Do n't load native prelude to avoid conflict with PlutusTx . Prelude
# LANGUAGE ScopedTypeVariables #
# LANGUAGE TemplateHaskell      #
# LANGUAGE TypeApplications     #
# LANGUAGE TypeFamilies         #

module AlwaysSucceedandFail where

PlutusTx
import           PlutusTx                       (Data (..))
import qualified PlutusTx
import qualified PlutusTx.Builtins              as Builtins
import           PlutusTx.Prelude               hiding (Semigroup(..), unless)
import           Plutus.Contract               
import           Ledger                         hiding (singleton)
import qualified Ledger.Address                 as V1Address
  Same library name , different functions for V1 and V2 in some cases
import qualified Ledger . Scripts                as Scripts               
  New library name for Typed  and some new fuctions
import           Ledger.Ada                     as Ada
Trace Emulator
import           Plutus.Trace
import qualified Plutus.Trace.Emulator          as Emulator
import qualified Wallet.Emulator.Wallet         as Wallet
  ( broken ) 
 import            Playground . Contract             ( printJson , printSchemas , ensureKnownCurrencies , stage ) 
 import            Playground . TH                   ( mkKnownCurrencies , mkSchemaDefinitions ) 
 import            Playground . Types                (  ( .. ) ) 
import           Playground.Contract            (printJson, printSchemas, ensureKnownCurrencies, stage)
import           Playground.TH                  (mkKnownCurrencies, mkSchemaDefinitions)
import           Playground.Types               (KnownCurrency (..))
import           Control.Monad                  hiding (fmap)
import           Data.Map                       as Map
import           Data.Text                      (Text)
import           Data.Void                      (Void)
import           Prelude                        (IO, Semigroup (..), String, show)
import           Text.Printf                    (printf)
import           Control.Monad.Freer.Extras     as Extras


# OPTIONS_GHC -fno - warn - unused - imports #


# INLINABLE alwaysSucceeds #
alwaysSucceeds _ _ _ = () 

# INLINABLE alwaysFails #
alwaysFails :: BuiltinData -> BuiltinData -> BuiltinData -> ()   
alwaysFails _ _ _ = error () 

validator :: Validator
validator = mkValidatorScript $$(PlutusTx.compile [|| alwaysSucceeds ||])  

valHash :: Ledger.ValidatorHash
valHash = Scripts.validatorHash validator  

scrAddress :: V1Address.Address
  Could n't find a new version of scriptAddress for unTyped Scripts



type GiftSchema =
        .\/ Endpoint "grab" ()

give :: AsContractError e => Integer -> Contract w s e ()
give amount = do
This Tx needs an output , that s its going to be the Script Address , Datum MUST be specified , so is created and the ammount of lovelaces
This line submit the Tx
    
grab :: forall w s e. AsContractError e => Contract w s e ()                                     
grab = do
  and inform about the actual validator ( the spending tx needs to provide the actual validator )
        tx :: TxConstraints Void Void                                                            
  Define the TX giving constrains , one for each UTXO sitting on this addrs ,
  Allow the wallet to construct the tx with the necesary information

endpoints :: Contract () GiftSchema Text ()

  Playground broken at the moment - September 2022


test :: IO ()
test = runEmulatorTraceIO $ do
    h1 <- activateContractWallet (Wallet.knownWallet 1) endpoints
    h2 <- activateContractWallet (Wallet.knownWallet 2) endpoints
    callEndpoint @"give" h1 $ 51000000
    void $ Emulator.waitNSlots 11
    callEndpoint @"grab" h2 ()
    s <- Emulator.waitNSlots 11
    Extras.logInfo $ "End of Simulation at slot " ++ show s