diff --git a/doc/plutus-doc.cabal b/doc/plutus-doc.cabal index eb7add55c2..017e414804 100644 --- a/doc/plutus-doc.cabal +++ b/doc/plutus-doc.cabal @@ -61,6 +61,7 @@ executable doc-doctests template-haskell >=2.13.0.0, bytestring -any, cardano-api -any, + data-default -any, flat -any, plutus-core -any, plutus-chain-index-core -any, diff --git a/doc/plutus/tutorials/GameModel.hs b/doc/plutus/tutorials/GameModel.hs index fb551658fd..3fcbda1635 100644 --- a/doc/plutus/tutorials/GameModel.hs +++ b/doc/plutus/tutorials/GameModel.hs @@ -58,6 +58,18 @@ import Plutus.Trace.Emulator as Trace import Plutus.Contract.Secrets -- END import Contract.Security +-- START import TimeSlot +import Ledger.TimeSlot qualified as TimeSlot +-- END import TimeSlot + +-- START import Data.Default +import Data.Default (Default (def)) +-- END import Data.Default + +-- START gameParam +gameParam :: G.GameParam +gameParam = G.GameParam (mockWalletPaymentPubKeyHash w1) (TimeSlot.scSlotZeroTime def) +-- END gameParam -- * QuickCheck model @@ -108,18 +120,21 @@ instance ContractModel GameModel where perform handle _ s cmd = case cmd of Lock w new val -> do callEndpoint @"lock" (handle $ WalletKey w) - LockArgs{ lockArgsSecret = secretArg new - , lockArgsValue = Ada.lovelaceValueOf val } + LockArgs { lockArgsGameParam = gameParam + , lockArgsSecret = secretArg new + , lockArgsValue = Ada.lovelaceValueOf val + } delay 2 Guess w old new val -> do callEndpoint @"guess" (handle $ WalletKey w) - GuessArgs{ guessArgsOldSecret = old + GuessArgs{ guessArgsGameParam = gameParam + , guessArgsOldSecret = old , guessArgsNewSecret = secretArg new , guessArgsValueTakenOut = Ada.lovelaceValueOf val } delay 1 GiveToken w' -> do let w = fromJust (s ^. contractState . hasToken) - payToWallet w w' gameTokenVal + payToWallet w w' guessTokenVal delay 1 -- END perform @@ -130,8 +145,8 @@ instance ContractModel GameModel where hasToken $= Just w currentSecret $= secret gameValue $= val - mint gameTokenVal - deposit w gameTokenVal + mint guessTokenVal + deposit w guessTokenVal withdraw w $ Ada.lovelaceValueOf val wait 2 @@ -149,7 +164,7 @@ instance ContractModel GameModel where nextState (GiveToken w) = do w0 <- fromJust <$> viewContractState hasToken - transfer w0 w gameTokenVal + transfer w0 w guessTokenVal hasToken $= Just w wait 1 @@ -168,9 +183,9 @@ instance ContractModel GameModel where -- START precondition precondition s cmd = case cmd of - Lock _ _ v -> tok == Nothing + Lock _ _ v -> isNothing tok Guess w _ _ v -> tok == Just w && v <= val - GiveToken w -> tok /= Nothing + GiveToken w -> isJust tok where tok = s ^. contractState . hasToken val = s ^. contractState . gameValue @@ -296,12 +311,12 @@ wallets :: [Wallet] wallets = [w1, w2, w3] -- END wallets --- START gameTokenVal -gameTokenVal :: Value -gameTokenVal = - let sym = Scripts.forwardingMintingPolicyHash G.typedValidator +-- START guessTokenVal +guessTokenVal :: Value +guessTokenVal = + let sym = Scripts.forwardingMintingPolicyHash $ G.typedValidator gameParam in G.token sym "guess" --- END gameTokenVal +-- END guessTokenVal -- START testLock v1 testLock :: Property @@ -353,8 +368,8 @@ v1_model = () hasToken $= Just w currentSecret $= secret gameValue $= val - mint gameTokenVal - deposit w gameTokenVal + mint guessTokenVal + deposit w guessTokenVal withdraw w $ Ada.lovelaceValueOf val -- END nextState Lock v1 -- START nextState Guess v1 @@ -370,13 +385,13 @@ v1_model = () -- START nextState GiveToken v1 nextState (GiveToken w) = do w0 <- fromJust <$> viewContractState hasToken - transfer w0 w gameTokenVal + transfer w0 w guessTokenVal hasToken $= Just w -- END nextState GiveToken v1 precondition :: ModelState GameModel -> Action GameModel -> Bool -- START precondition v1 - precondition s (GiveToken _) = tok /= Nothing + precondition s (GiveToken _) = isJust tok where tok = s ^. contractState . hasToken precondition s _ = True @@ -387,16 +402,18 @@ v1_model = () perform handle _ s cmd = case cmd of Lock w new val -> do callEndpoint @"lock" (handle $ WalletKey w) - LockArgs{ lockArgsSecret = secretArg new + LockArgs{ lockArgsGameParam = gameParam + , lockArgsSecret = secretArg new , lockArgsValue = Ada.lovelaceValueOf val} Guess w old new val -> do callEndpoint @"guess" (handle $ WalletKey w) - GuessArgs{ guessArgsOldSecret = old + GuessArgs{ guessArgsGameParam = gameParam + , guessArgsOldSecret = old , guessArgsNewSecret = secretArg new , guessArgsValueTakenOut = Ada.lovelaceValueOf val} GiveToken w' -> do let w = fromJust (s ^. contractState . hasToken) - payToWallet w w' gameTokenVal + payToWallet w w' guessTokenVal return () -- END perform v1 @@ -409,8 +426,8 @@ v2_model = () hasToken $= Just w currentSecret $= secret gameValue $= val - mint gameTokenVal - deposit w gameTokenVal + mint guessTokenVal + deposit w guessTokenVal withdraw w $ Ada.lovelaceValueOf val wait 2 -- END nextState Lock v2 @@ -425,9 +442,9 @@ v2_model = () precondition :: ModelState GameModel -> Action GameModel -> Bool -- START precondition v2 precondition s cmd = case cmd of - Lock _ _ _ -> tok == Nothing - Guess _ _ _ _ -> True - GiveToken _ -> tok /= Nothing + Lock {} -> isNothing tok + Guess {} -> True + GiveToken _ -> isJust tok where tok = s ^. contractState . hasToken -- END precondition v2 @@ -450,9 +467,9 @@ v3_model = () precondition :: ModelState GameModel -> Action GameModel -> Bool -- START precondition v3 precondition s cmd = case cmd of - Lock _ _ _ -> tok == Nothing + Lock {} -> isNothing tok Guess w _ _ _ -> tok == Just w - GiveToken _ -> tok /= Nothing + GiveToken _ -> isJust tok where tok = s ^. contractState . hasToken -- END precondition v3 diff --git a/doc/plutus/tutorials/contract-testing.rst b/doc/plutus/tutorials/contract-testing.rst index 1a60ef5388..f8ef88ae8b 100644 --- a/doc/plutus/tutorials/contract-testing.rst +++ b/doc/plutus/tutorials/contract-testing.rst @@ -92,23 +92,33 @@ we can define it as follows, applying a minting policy defined in the code under .. literalinclude:: GameModel.hs :start-after: START import Game :end-before: END import Game +.. literalinclude:: GameModel.hs + :start-after: START import TimeSlot + :end-before: END import TimeSlot +.. literalinclude:: GameModel.hs + :start-after: START import Data.Default + :end-before: END import Data.Default + +.. literalinclude:: GameModel.hs + :start-after: START gameParam + :end-before: END gameParam .. literalinclude:: GameModel.hs - :start-after: START gameTokenVal - :end-before: END gameTokenVal + :start-after: START guessTokenVal + :end-before: END guessTokenVal The value of the :term:`token` is (with long hash values abbreviated): .. code-block:: text - > gameTokenVal + > guessTokenVal Value (Map [(f687...,Map [(guess,1)])]) We can even construct a ``Value`` containing an Ada and a game :term:`token`: .. code-block:: text - > Ada.lovelaceValueOf 1 <> gameTokenVal + > Ada.lovelaceValueOf 1 <> guessTokenVal Value (Map [(,Map [(,1)]),(f687...,Map [(guess,1)])]) If you inspect the output closely, you will see that a ``Value`` @@ -513,6 +523,9 @@ contract end-points, using the API defined in the code under test, and transfer the game :term:`token` from one wallet to another as specified by ``GiveToken`` actions. +.. literalinclude:: GameModel.hs + :start-after: START gameParam + :end-before: END gameParam .. literalinclude:: GameModel.hs :start-after: START perform v1 :end-before: END perform v1 @@ -676,6 +689,10 @@ later via failed tests). We add a call to ``delay`` in each branch of :hsobj:`Plutus.Contract.Test.ContractModel.perform`: +.. literalinclude:: GameModel.hs + :start-after: START gameParam + :end-before: END gameParam + .. literalinclude:: GameModel.hs :start-after: START perform :end-before: END perform diff --git a/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-doc.nix b/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-doc.nix index 175c0fb1b9..8a952e2a88 100644 --- a/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-doc.nix +++ b/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-doc.nix @@ -38,6 +38,7 @@ (hsPkgs."template-haskell" or (errorHandler.buildDepError "template-haskell")) (hsPkgs."bytestring" or (errorHandler.buildDepError "bytestring")) (hsPkgs."cardano-api" or (errorHandler.buildDepError "cardano-api")) + (hsPkgs."data-default" or (errorHandler.buildDepError "data-default")) (hsPkgs."flat" or (errorHandler.buildDepError "flat")) (hsPkgs."plutus-core" or (errorHandler.buildDepError "plutus-core")) (hsPkgs."plutus-chain-index-core" or (errorHandler.buildDepError "plutus-chain-index-core")) diff --git a/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-use-cases.nix b/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-use-cases.nix index b3d57dc83a..0e6768b9ca 100644 --- a/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-use-cases.nix +++ b/nix/pkgs/haskell/materialized-darwin/.plan.nix/plutus-use-cases.nix @@ -67,6 +67,7 @@ "Plutus/Contracts/Escrow" "Plutus/Contracts/SimpleEscrow" "Plutus/Contracts/Future" + "Plutus/Contracts/Game" "Plutus/Contracts/GameStateMachine" "Plutus/Contracts/Governance" "Plutus/Contracts/MultiSig" @@ -143,6 +144,7 @@ "Spec/Escrow" "Spec/SimpleEscrow" "Spec/Future" + "Spec/Game" "Spec/GameStateMachine" "Spec/Governance" "Spec/MultiSig" @@ -199,6 +201,7 @@ "Spec/Escrow" "Spec/SimpleEscrow" "Spec/Future" + "Spec/Game" "Spec/GameStateMachine" "Spec/Governance" "Spec/MultiSig" diff --git a/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-doc.nix b/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-doc.nix index 175c0fb1b9..8a952e2a88 100644 --- a/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-doc.nix +++ b/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-doc.nix @@ -38,6 +38,7 @@ (hsPkgs."template-haskell" or (errorHandler.buildDepError "template-haskell")) (hsPkgs."bytestring" or (errorHandler.buildDepError "bytestring")) (hsPkgs."cardano-api" or (errorHandler.buildDepError "cardano-api")) + (hsPkgs."data-default" or (errorHandler.buildDepError "data-default")) (hsPkgs."flat" or (errorHandler.buildDepError "flat")) (hsPkgs."plutus-core" or (errorHandler.buildDepError "plutus-core")) (hsPkgs."plutus-chain-index-core" or (errorHandler.buildDepError "plutus-chain-index-core")) diff --git a/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-use-cases.nix b/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-use-cases.nix index b3d57dc83a..0e6768b9ca 100644 --- a/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-use-cases.nix +++ b/nix/pkgs/haskell/materialized-linux/.plan.nix/plutus-use-cases.nix @@ -67,6 +67,7 @@ "Plutus/Contracts/Escrow" "Plutus/Contracts/SimpleEscrow" "Plutus/Contracts/Future" + "Plutus/Contracts/Game" "Plutus/Contracts/GameStateMachine" "Plutus/Contracts/Governance" "Plutus/Contracts/MultiSig" @@ -143,6 +144,7 @@ "Spec/Escrow" "Spec/SimpleEscrow" "Spec/Future" + "Spec/Game" "Spec/GameStateMachine" "Spec/Governance" "Spec/MultiSig" @@ -199,6 +201,7 @@ "Spec/Escrow" "Spec/SimpleEscrow" "Spec/Future" + "Spec/Game" "Spec/GameStateMachine" "Spec/Governance" "Spec/MultiSig" diff --git a/nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-doc.nix b/nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-doc.nix index 175c0fb1b9..8a952e2a88 100644 --- a/nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-doc.nix +++ b/nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-doc.nix @@ -38,6 +38,7 @@ (hsPkgs."template-haskell" or (errorHandler.buildDepError "template-haskell")) (hsPkgs."bytestring" or (errorHandler.buildDepError "bytestring")) (hsPkgs."cardano-api" or (errorHandler.buildDepError "cardano-api")) + (hsPkgs."data-default" or (errorHandler.buildDepError "data-default")) (hsPkgs."flat" or (errorHandler.buildDepError "flat")) (hsPkgs."plutus-core" or (errorHandler.buildDepError "plutus-core")) (hsPkgs."plutus-chain-index-core" or (errorHandler.buildDepError "plutus-chain-index-core")) diff --git a/nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-use-cases.nix b/nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-use-cases.nix index b3d57dc83a..0e6768b9ca 100644 --- a/nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-use-cases.nix +++ b/nix/pkgs/haskell/materialized-windows/.plan.nix/plutus-use-cases.nix @@ -67,6 +67,7 @@ "Plutus/Contracts/Escrow" "Plutus/Contracts/SimpleEscrow" "Plutus/Contracts/Future" + "Plutus/Contracts/Game" "Plutus/Contracts/GameStateMachine" "Plutus/Contracts/Governance" "Plutus/Contracts/MultiSig" @@ -143,6 +144,7 @@ "Spec/Escrow" "Spec/SimpleEscrow" "Spec/Future" + "Spec/Game" "Spec/GameStateMachine" "Spec/Governance" "Spec/MultiSig" @@ -199,6 +201,7 @@ "Spec/Escrow" "Spec/SimpleEscrow" "Spec/Future" + "Spec/Game" "Spec/GameStateMachine" "Spec/Governance" "Spec/MultiSig" diff --git a/plutus-pab-executables/examples/ContractExample.hs b/plutus-pab-executables/examples/ContractExample.hs index 225fae075c..d714ccd002 100644 --- a/plutus-pab-executables/examples/ContractExample.hs +++ b/plutus-pab-executables/examples/ContractExample.hs @@ -18,6 +18,7 @@ module ContractExample( import Control.Monad.Freer import Data.Aeson (FromJSON, ToJSON) import Data.Default (Default (def)) +import Data.Text (Text) import GHC.Generics (Generic) import Prettyprinter @@ -32,6 +33,7 @@ import Language.PureScript.Bridge.TypeParameters (A) import Ledger (TxId) import Playground.Types (FunctionSchema) import Plutus.Contracts.Currency qualified as Contracts.Currency +import Plutus.Contracts.Game qualified as Contracts.Game import Plutus.Contracts.GameStateMachine qualified as Contracts.GameStateMachine import Plutus.Contracts.PingPong qualified as Contracts.PingPong import Plutus.Contracts.Prism.Mirror qualified as Contracts.Prism @@ -49,6 +51,7 @@ import Schema (FormSchema) data ContractExample = UniswapInit | UniswapOwner | UniswapUser Contracts.Uniswap.Uniswap + | Game | GameStateMachine | PayToWallet | AtomicSwap @@ -78,6 +81,7 @@ instance HasPSTypes ContractExample where instance HasDefinitions ContractExample where getDefinitions = [ UniswapInit , UniswapOwner + , Game , GameStateMachine , PayToWallet , AtomicSwap @@ -97,6 +101,7 @@ getContractExampleSchema = \case UniswapInit -> Builtin.endpointsToSchemas @Empty UniswapUser _ -> Builtin.endpointsToSchemas @Contracts.Uniswap.UniswapUserSchema UniswapOwner -> Builtin.endpointsToSchemas @Contracts.Uniswap.UniswapOwnerSchema + Game -> Builtin.endpointsToSchemas @Contracts.Game.GameSchema GameStateMachine -> Builtin.endpointsToSchemas @Contracts.GameStateMachine.GameStateMachineSchema PayToWallet -> Builtin.endpointsToSchemas @Contracts.PayToWallet.PayToWalletSchema AtomicSwap -> Builtin.endpointsToSchemas @Contracts.AtomicSwap.AtomicSwapSchema @@ -114,6 +119,7 @@ getContractExample = \case UniswapInit -> SomeBuiltin Contracts.Uniswap.setupTokens UniswapUser us -> SomeBuiltin $ Contracts.Uniswap.userEndpoints us UniswapOwner -> SomeBuiltin Contracts.Uniswap.ownerEndpoint + Game -> SomeBuiltin (Contracts.Game.contract @Text) GameStateMachine -> SomeBuiltin Contracts.GameStateMachine.contract PayToWallet -> SomeBuiltin Contracts.PayToWallet.payToWallet AtomicSwap -> SomeBuiltin Contracts.AtomicSwap.atomicSwap diff --git a/plutus-pab-executables/test/full/Plutus/PAB/CoreSpec.hs b/plutus-pab-executables/test/full/Plutus/PAB/CoreSpec.hs index bba75a5d78..7b609e13a4 100644 --- a/plutus-pab-executables/test/full/Plutus/PAB/CoreSpec.hs +++ b/plutus-pab-executables/test/full/Plutus/PAB/CoreSpec.hs @@ -30,9 +30,11 @@ import Control.Monad.Freer.State (State) import Control.Monad.IO.Class (MonadIO (liftIO)) import Data.Aeson qualified as JSON import Data.Foldable (fold, traverse_) +import Ledger.TimeSlot qualified as TimeSlot import Control.Concurrent.STM qualified as STM import Data.Aeson.Types qualified as JSON +import Data.Default (def) import Data.Either (isRight) import Data.Map qualified as Map import Data.Maybe (isJust) @@ -54,6 +56,7 @@ import Ledger.Value (valueOf) import Plutus.ChainIndex (Depth (Depth), RollbackState (Committed, TentativelyConfirmed, Unknown), TxOutState (Spent, Unspent), TxValidity (TxValid), chainConstant) import Plutus.Contract.State (ContractResponse (ContractResponse, hooks)) +import Plutus.Contract.Test (mockWalletPaymentPubKeyHash, w1) import Plutus.Contracts.Currency (OneShotCurrency, SimpleMPS (SimpleMPS, amount, tokenName)) import Plutus.Contracts.GameStateMachine qualified as Contracts.GameStateMachine import Plutus.Contracts.PingPong (PingPongState (Pinged, Ponged)) @@ -341,6 +344,7 @@ guessingGameTest = (valueOf (balance <> fees) adaSymbol adaToken) instanceId <- Simulator.activateContract defaultWallet GameStateMachine + let gameParam = Contracts.GameStateMachine.GameParam (mockWalletPaymentPubKeyHash defaultWallet) (TimeSlot.scSlotZeroTime def) initialTxCounts <- Simulator.txCounts pubKeyHashFundsChange instanceId "Check our opening balance." 0 @@ -351,7 +355,8 @@ guessingGameTest = lock instanceId Contracts.GameStateMachine.LockArgs - { Contracts.GameStateMachine.lockArgsValue = lovelaceValueOf lockAmount + { Contracts.GameStateMachine.lockArgsGameParam = gameParam + , Contracts.GameStateMachine.lockArgsValue = lovelaceValueOf lockAmount , Contracts.GameStateMachine.lockArgsSecret = "password" } @@ -364,7 +369,8 @@ guessingGameTest = guess game1Id Contracts.GameStateMachine.GuessArgs - { Contracts.GameStateMachine.guessArgsNewSecret = "wrong" + { Contracts.GameStateMachine.guessArgsGameParam = gameParam + , Contracts.GameStateMachine.guessArgsNewSecret = "wrong" , Contracts.GameStateMachine.guessArgsOldSecret = "wrong" , Contracts.GameStateMachine.guessArgsValueTakenOut = lovelaceValueOf lockAmount } @@ -378,7 +384,8 @@ guessingGameTest = guess game2Id Contracts.GameStateMachine.GuessArgs - { Contracts.GameStateMachine.guessArgsNewSecret = "password" + { Contracts.GameStateMachine.guessArgsGameParam = gameParam + , Contracts.GameStateMachine.guessArgsNewSecret = "password" , Contracts.GameStateMachine.guessArgsOldSecret = "password" , Contracts.GameStateMachine.guessArgsValueTakenOut = lovelaceValueOf lockAmount } diff --git a/plutus-use-cases/plutus-use-cases.cabal b/plutus-use-cases/plutus-use-cases.cabal index d1e6ca8b21..d0c27c488c 100644 --- a/plutus-use-cases/plutus-use-cases.cabal +++ b/plutus-use-cases/plutus-use-cases.cabal @@ -35,6 +35,7 @@ library Plutus.Contracts.Escrow Plutus.Contracts.SimpleEscrow Plutus.Contracts.Future + Plutus.Contracts.Game Plutus.Contracts.GameStateMachine Plutus.Contracts.Governance Plutus.Contracts.MultiSig @@ -109,6 +110,7 @@ test-suite plutus-use-cases-test Spec.Escrow Spec.SimpleEscrow Spec.Future + Spec.Game Spec.GameStateMachine Spec.Governance Spec.MultiSig @@ -175,6 +177,7 @@ executable plutus-use-cases-scripts Spec.Escrow Spec.SimpleEscrow Spec.Future + Spec.Game Spec.GameStateMachine Spec.Governance Spec.MultiSig diff --git a/plutus-use-cases/scripts/Main.hs b/plutus-use-cases/scripts/Main.hs index b56c986c92..93285ebe00 100644 --- a/plutus-use-cases/scripts/Main.hs +++ b/plutus-use-cases/scripts/Main.hs @@ -1,10 +1,6 @@ -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DerivingStrategies #-} {-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE TypeFamilies #-} module Main(main, ExportTx(..)) where @@ -21,6 +17,7 @@ import Plutus.Trace (Command (..), ScriptsConfig (..), showStats, writeScriptsTo import Spec.Currency qualified as Currency import Spec.Escrow qualified as Escrow import Spec.Future qualified as Future +import Spec.Game qualified as Game import Spec.GameStateMachine qualified as GameStateMachine import Spec.MultiSig qualified as MultiSig import Spec.MultiSigStateMachine qualified as MultiSigStateMachine @@ -102,6 +99,7 @@ writeScripts config = do , ("future-increase-margin", Future.increaseMarginTrace, def) , ("future-settle-early", Future.settleEarlyTrace, def) , ("future-pay-out", Future.payOutTrace, def) + , ("game-success", Game.successTrace, def) , ("game-sm-success_1", GameStateMachine.successTrace, def) , ("game-sm-success_2", GameStateMachine.successTrace2, def) , ("multisig-success", MultiSig.succeedingTrace, def) diff --git a/plutus-use-cases/src/Plutus/Contracts/Game.hs b/plutus-use-cases/src/Plutus/Contracts/Game.hs new file mode 100644 index 0000000000..5e837d0cdd --- /dev/null +++ b/plutus-use-cases/src/Plutus/Contracts/Game.hs @@ -0,0 +1,195 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DerivingStrategies #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE MultiParamTypeClasses #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE NoImplicitPrelude #-} +{-# LANGUAGE PartialTypeSignatures #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} +{-# LANGUAGE ViewPatterns #-} + +-- | A guessing game. A simplified version of 'Plutus.Contract.GameStateMachine' +-- not using 'Plutus.Contract.StateMachine' and using `yieldUnbalancedTx' for +-- balancing, signing and submitting transactions. +-- +-- Currently, remote wallets (anything other than WBE) can only handles +-- `yieldUnbalancedTx` requests, and not `balanceTx`, `signTx` and `submitTx` +-- requests. +module Plutus.Contracts.Game + ( contract + , GameParam(..) + , GameSchema + , LockArgs(..) + , GuessArgs(..) + -- * Scripts + , gameInstance + , mkValidator + -- * Address + , gameAddress + , covIdx + ) where + +import Data.Aeson (FromJSON, ToJSON) +import Data.ByteString.Char8 qualified as C +import Data.Map (Map) +import Data.Map qualified as Map +import Data.Maybe (catMaybes) +import GHC.Generics (Generic) +import Ledger (Address, Datum (Datum), POSIXTime, PaymentPubKeyHash, ScriptContext, TxOutRef, Validator, Value) +import Ledger qualified +import Ledger.Ada qualified as Ada +import Ledger.Constraints qualified as Constraints +import Ledger.Tx (ChainIndexTxOut (..)) +import Ledger.Typed.Scripts qualified as Scripts +import Playground.Contract (ToSchema) +import Plutus.Contract (AsContractError, Contract, Endpoint, Promise, collectFromScript, endpoint, fundsAtAddressGeq, + logInfo, mkTxConstraints, selectList, type (.\/), yieldUnbalancedTx) +import PlutusTx qualified +import PlutusTx.Code (getCovIdx) +import PlutusTx.Coverage (CoverageIndex) +import PlutusTx.Prelude hiding (pure, (<$>)) +import Prelude qualified as Haskell + +-- | Datatype for creating a parameterized validator. +data GameParam = GameParam + { gameParamPayeePkh :: PaymentPubKeyHash + -- ^ Payment public key hash of the wallet locking some funds + , gameParamStartTime :: POSIXTime + -- ^ Starting time of the game + } deriving (Haskell.Show, Generic) + deriving anyclass (ToJSON, FromJSON, ToSchema) + +PlutusTx.makeLift ''GameParam + +newtype HashedString = HashedString BuiltinByteString + deriving newtype (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) + +PlutusTx.makeLift ''HashedString + +newtype ClearString = ClearString BuiltinByteString + deriving newtype (PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) + +PlutusTx.makeLift ''ClearString + +type GameSchema = + Endpoint "lock" LockArgs + .\/ Endpoint "guess" GuessArgs + +data Game +instance Scripts.ValidatorTypes Game where + type instance RedeemerType Game = ClearString + type instance DatumType Game = HashedString + +-- | The address of the game (the hash of its validator script) +gameAddress :: GameParam -> Address +gameAddress = Ledger.scriptAddress . gameValidator + +-- | The validator script of the game. +gameValidator :: GameParam -> Validator +gameValidator = Scripts.validatorScript . gameInstance + +gameInstance :: GameParam -> Scripts.TypedValidator Game +gameInstance = Scripts.mkTypedValidatorParam @Game + $$(PlutusTx.compile [|| mkValidator ||]) + $$(PlutusTx.compile [|| wrap ||]) where + wrap = Scripts.wrapValidator @HashedString @ClearString + +-- | The validation function (Datum -> Redeemer -> ScriptContext -> Bool) +-- +-- The 'GameParam' parameter is not used in the validation. It is meant to +-- parameterize the script address depending based on the value of 'GaramParam'. +{-# INLINABLE mkValidator #-} +mkValidator :: GameParam -> HashedString -> ClearString -> ScriptContext -> Bool +mkValidator _ hs cs _ = isGoodGuess hs cs + +{-# INLINABLE isGoodGuess #-} +isGoodGuess :: HashedString -> ClearString -> Bool +isGoodGuess (HashedString actual) (ClearString guess') = actual == sha2_256 guess' + +-- TODO: Ideas welcome for how to make this interface suck less. +-- Doing it this way actually generates coverage locations that we don't care about(!) +covIdx :: GameParam -> CoverageIndex +covIdx gameParam = + getCovIdx ($$(PlutusTx.compile [|| mkValidator ||]) `PlutusTx.applyCode` PlutusTx.liftCode gameParam) + +-- create a data script for the guessing game by hashing the string +-- and lifting the hash to its on-chain representation +hashString :: Haskell.String -> HashedString +hashString = HashedString . sha2_256 . toBuiltin . C.pack + +-- create a redeemer script for the guessing game by lifting the +-- string to its on-chain representation +clearString :: Haskell.String -> ClearString +clearString = ClearString . toBuiltin . C.pack + +-- | Arguments for the @"lock"@ endpoint +data LockArgs = + LockArgs + { lockArgsGameParam :: GameParam + -- ^ The parameters for parameterizing the validator. + , lockArgsSecret :: Haskell.String -- SecretArgument Haskell.String + -- ^ The secret + , lockArgsValue :: Value + -- ^ Value that is locked by the contract initially + } deriving stock (Haskell.Show, Generic) + deriving anyclass (ToJSON, FromJSON, ToSchema) + +-- | Arguments for the @"guess"@ endpoint +data GuessArgs = + GuessArgs + { guessArgsGameParam :: GameParam + -- ^ The parameters for parameterizing the validator. + , guessArgsSecret :: Haskell.String + -- ^ The guess + } deriving stock (Haskell.Show, Generic) + deriving anyclass (ToJSON, FromJSON, ToSchema) + +-- | The "lock" contract endpoint. See note [Contract endpoints] +lock :: AsContractError e => Promise () GameSchema e () +lock = endpoint @"lock" $ \LockArgs { lockArgsGameParam, lockArgsSecret, lockArgsValue } -> do + logInfo @Haskell.String $ "Pay " <> Haskell.show lockArgsValue <> " to the script" + let lookups = Constraints.typedValidatorLookups (gameInstance lockArgsGameParam) + tx = Constraints.mustPayToTheScript (hashString lockArgsSecret) lockArgsValue + unbalancedTx <- mkTxConstraints lookups tx + yieldUnbalancedTx $ Constraints.adjustUnbalancedTx unbalancedTx + +-- | The "guess" contract endpoint. See note [Contract endpoints] +guess :: AsContractError e => Promise () GameSchema e () +guess = endpoint @"guess" $ \GuessArgs { guessArgsGameParam, guessArgsSecret } -> do + -- Wait for script to have a UTxO of a least 1 lovelace + logInfo @Haskell.String "Waiting for script to have a UTxO of at least 1 lovelace" + utxos <- fundsAtAddressGeq (gameAddress guessArgsGameParam) (Ada.lovelaceValueOf 1) + + let lookups = Constraints.typedValidatorLookups (gameInstance guessArgsGameParam) + Haskell.<> Constraints.unspentOutputs utxos + redeemer = clearString guessArgsSecret + tx = collectFromScript utxos redeemer + + unbalancedTx <- mkTxConstraints lookups tx + yieldUnbalancedTx unbalancedTx + +-- | Find the secret word in the Datum of the UTxOs +findSecretWordValue :: Map TxOutRef ChainIndexTxOut -> Maybe HashedString +findSecretWordValue = + listToMaybe . catMaybes . Map.elems . Map.map secretWordValue + +-- | Extract the secret word in the Datum of a given transaction output is possible +secretWordValue :: ChainIndexTxOut -> Maybe HashedString +secretWordValue o = do + Datum d <- either (const Nothing) Just (_ciTxOutDatum o) + PlutusTx.fromBuiltinData d + +contract :: AsContractError e => Contract () GameSchema e () +contract = do + logInfo @Haskell.String "Waiting for lock or guess endpoint..." + selectList [lock, guess] >> contract diff --git a/plutus-use-cases/src/Plutus/Contracts/GameStateMachine.hs b/plutus-use-cases/src/Plutus/Contracts/GameStateMachine.hs index 7f23af0031..1d5b040c9e 100644 --- a/plutus-use-cases/src/Plutus/Contracts/GameStateMachine.hs +++ b/plutus-use-cases/src/Plutus/Contracts/GameStateMachine.hs @@ -25,12 +25,14 @@ module Plutus.Contracts.GameStateMachine( contract , typedValidator - , GameToken + , GameParam(..) + , GuessToken , mkValidator , mintingPolicy , LockArgs(..) , GuessArgs(..) - , GameStateMachineSchema, GameError + , GameStateMachineSchema + , GameError , token , covIdx ) where @@ -38,29 +40,38 @@ module Plutus.Contracts.GameStateMachine( import Control.Lens (makeClassyPrisms) import Control.Monad (void) import Data.Aeson (FromJSON, ToJSON) +import Data.ByteString.Char8 qualified as C import GHC.Generics (Generic) -import Ledger hiding (to) +import Ledger (MintingPolicyHash, POSIXTime, PaymentPubKeyHash, TokenName, Value) import Ledger.Ada qualified as Ada import Ledger.Constraints (TxConstraints) import Ledger.Constraints qualified as Constraints import Ledger.Typed.Scripts qualified as Scripts import Ledger.Value qualified as V -import PlutusTx qualified -import PlutusTx.Code -import PlutusTx.Coverage -import PlutusTx.Prelude hiding (Applicative (..), check) -import Schema (ToArgument, ToSchema) - -import Data.ByteString.Char8 qualified as C - -import Plutus.Contract.StateMachine (State (..), Void) +import Plutus.Contract (AsContractError (_ContractError), Contract, ContractError, Endpoint, Promise, endpoint, + selectList, type (.\/)) +import Plutus.Contract.Secrets (SecretArgument, escape_sha2_256, extractSecret) +import Plutus.Contract.StateMachine (State (State, stateData, stateValue), Void) import Plutus.Contract.StateMachine qualified as SM - -import Plutus.Contract -import Plutus.Contract.Secrets +import PlutusTx qualified +import PlutusTx.Code (getCovIdx) +import PlutusTx.Coverage (CoverageIndex) +import PlutusTx.Prelude (Bool (False, True), BuiltinByteString, Eq, Maybe (Just, Nothing), sha2_256, toBuiltin, + traceIfFalse, ($), (&&), (-), (.), (<$>), (<>), (==), (>>)) +import Schema (ToSchema) import Prelude qualified as Haskell +-- | Datatype for creating a parameterized validator. +data GameParam = GameParam + { gameParamPayeePkh :: PaymentPubKeyHash + -- ^ Payment public key hash of the wallet locking some funds + , gameParamStartTime :: POSIXTime + -- ^ Starting time of the game + } deriving (Haskell.Show, Generic) + deriving anyclass (ToJSON, FromJSON, ToSchema) + +PlutusTx.makeLift ''GameParam newtype HashedString = HashedString BuiltinByteString deriving newtype (Eq, PlutusTx.ToData, PlutusTx.FromData, PlutusTx.UnsafeFromData) @@ -79,24 +90,28 @@ PlutusTx.makeLift ''ClearString -- | Arguments for the @"lock"@ endpoint data LockArgs = LockArgs - { lockArgsSecret :: SecretArgument Haskell.String + { lockArgsGameParam :: GameParam + -- ^ The parameters for parameterizing the validator. + , lockArgsSecret :: SecretArgument Haskell.String -- ^ The secret - , lockArgsValue :: Value + , lockArgsValue :: Value -- ^ Value that is locked by the contract initially } deriving stock (Haskell.Show, Generic) - deriving anyclass (ToJSON, FromJSON, ToSchema, ToArgument) + deriving anyclass (ToJSON, FromJSON, ToSchema) -- | Arguments for the @"guess"@ endpoint data GuessArgs = GuessArgs - { guessArgsOldSecret :: Haskell.String + { guessArgsGameParam :: GameParam + -- ^ The parameters for parameterizing the validator. + , guessArgsOldSecret :: Haskell.String -- ^ The guess , guessArgsNewSecret :: SecretArgument Haskell.String -- ^ The new secret , guessArgsValueTakenOut :: Value -- ^ How much to extract from the contract } deriving stock (Haskell.Show, Generic) - deriving anyclass (ToJSON, FromJSON, ToSchema, ToArgument) + deriving anyclass (ToJSON, FromJSON, ToSchema) -- | The schema of the contract. It consists of the two endpoints @"lock"@ -- and @"guess"@ with their respective argument types. @@ -123,7 +138,7 @@ contract :: Contract () GameStateMachineSchema GameError () contract = selectList [lock, guess] >> contract -- | The token that represents the right to make a guess -newtype GameToken = GameToken { unGameToken :: Value } +newtype GuessToken = GuessToken { unGuessToken :: Value } deriving newtype (Eq, Haskell.Show) token :: MintingPolicyHash -> TokenName -> Value @@ -145,6 +160,7 @@ instance Eq GameState where {-# INLINABLE (==) #-} (Initialised sym tn s) == (Initialised sym' tn' s') = sym == sym' && s == s' && tn == tn' (Locked sym tn s) == (Locked sym' tn' s') = sym == sym' && s == s' && tn == tn' + Finished == Finished = True _ == _ = traceIfFalse "states not equal" False -- | Check whether a 'ClearString' is the preimage of a @@ -162,9 +178,15 @@ data GameInput = deriving stock (Haskell.Show, Generic) deriving anyclass (ToJSON, FromJSON) +-- The 'GameParam' parameter is not used in the validation. It is meant to +-- parameterize the script address depending based on the value of 'GaramParam'. {-# INLINABLE transition #-} -transition :: State GameState -> GameInput -> Maybe (TxConstraints Void Void, State GameState) -transition State{stateData=oldData, stateValue=oldValue} input = case (oldData, input) of +transition + :: GameParam + -> State GameState + -> GameInput + -> Maybe (TxConstraints Void Void, State GameState) +transition _ State{stateData=oldData, stateValue=oldValue} input = case (oldData, input) of (Initialised mph tn s, MintToken) -> let constraints = Constraints.mustMintCurrency mph tn 1 in Just ( constraints @@ -175,7 +197,8 @@ transition State{stateData=oldData, stateValue=oldValue} input = case (oldData, ) (Locked mph tn currentSecret, Guess theGuess nextSecret takenOut) | checkGuess currentSecret theGuess -> - let constraints = Constraints.mustSpendAtLeast (token mph tn) <> Constraints.mustMintCurrency mph tn 0 + let constraints = Constraints.mustSpendAtLeast (token mph tn) + <> Constraints.mustMintCurrency mph tn 0 newValue = oldValue - takenOut in Just ( constraints , State @@ -190,17 +213,17 @@ transition State{stateData=oldData, stateValue=oldValue} input = case (oldData, type GameStateMachine = SM.StateMachine GameState GameInput {-# INLINABLE machine #-} -machine :: GameStateMachine -machine = SM.mkStateMachine Nothing transition isFinal where +machine :: GameParam -> GameStateMachine +machine gameParam = SM.mkStateMachine Nothing (transition gameParam) isFinal where isFinal Finished = True isFinal _ = False {-# INLINABLE mkValidator #-} -mkValidator :: Scripts.ValidatorType GameStateMachine -mkValidator = SM.mkValidator machine +mkValidator :: GameParam -> Scripts.ValidatorType GameStateMachine +mkValidator gameParam = SM.mkValidator (machine gameParam) -typedValidator :: Scripts.TypedValidator GameStateMachine -typedValidator = Scripts.mkTypedValidator @GameStateMachine +typedValidator :: GameParam -> Scripts.TypedValidator GameStateMachine +typedValidator = Scripts.mkTypedValidatorParam @GameStateMachine $$(PlutusTx.compile [|| mkValidator ||]) $$(PlutusTx.compile [|| wrap ||]) where @@ -208,36 +231,37 @@ typedValidator = Scripts.mkTypedValidator @GameStateMachine -- TODO: Ideas welcome for how to make this interface suck less. -- Doing it this way actually generates coverage locations that we don't care about(!) -covIdx :: CoverageIndex -covIdx = getCovIdx $$(PlutusTx.compile [|| mkValidator ||]) +covIdx :: GameParam -> CoverageIndex +covIdx gp = getCovIdx ($$(PlutusTx.compile [|| mkValidator ||]) `PlutusTx.applyCode` PlutusTx.liftCode gp) + +mintingPolicy :: GameParam -> Scripts.MintingPolicy +mintingPolicy gp = Scripts.forwardingMintingPolicy $ typedValidator gp -mintingPolicy :: Scripts.MintingPolicy -mintingPolicy = Scripts.forwardingMintingPolicy typedValidator +client :: GameParam -> SM.StateMachineClient GameState GameInput +client gp = SM.mkStateMachineClient $ SM.StateMachineInstance (machine gp) $ typedValidator gp -client :: SM.StateMachineClient GameState GameInput -client = SM.mkStateMachineClient $ SM.StateMachineInstance machine typedValidator +-- | The @"lock"@ endpoint. +lock :: Promise () GameStateMachineSchema GameError () +lock = endpoint @"lock" $ \LockArgs{lockArgsGameParam, lockArgsSecret, lockArgsValue} -> do + let secret = HashedString (escape_sha2_256 (toBuiltin . C.pack <$> extractSecret lockArgsSecret)) + sym = Scripts.forwardingMintingPolicyHash $ typedValidator lockArgsGameParam + _ <- SM.runInitialise (client lockArgsGameParam) (Initialised sym "guess" secret) lockArgsValue + void $ SM.runStep (client lockArgsGameParam) MintToken -- | The @"guess"@ endpoint. guess :: Promise () GameStateMachineSchema GameError () -guess = endpoint @"guess" $ \GuessArgs{guessArgsOldSecret,guessArgsNewSecret, guessArgsValueTakenOut} -> do +guess = endpoint @"guess" $ \GuessArgs{guessArgsGameParam, guessArgsOldSecret, guessArgsNewSecret, guessArgsValueTakenOut} -> do let guessedSecret = ClearString (toBuiltin (C.pack guessArgsOldSecret)) newSecret = HashedString (escape_sha2_256 (toBuiltin . C.pack <$> extractSecret guessArgsNewSecret)) void - $ SM.runStep client + $ SM.runStep (client guessArgsGameParam) (Guess guessedSecret newSecret guessArgsValueTakenOut) -lock :: Promise () GameStateMachineSchema GameError () -lock = endpoint @"lock" $ \LockArgs{lockArgsSecret, lockArgsValue} -> do - let secret = HashedString (escape_sha2_256 (toBuiltin . C.pack <$> extractSecret lockArgsSecret)) - sym = Scripts.forwardingMintingPolicyHash typedValidator - _ <- SM.runInitialise client (Initialised sym "guess" secret) lockArgsValue - void $ SM.runStep client MintToken - PlutusTx.unstableMakeIsData ''GameState PlutusTx.makeLift ''GameState PlutusTx.unstableMakeIsData ''GameInput PlutusTx.makeLift ''GameInput -PlutusTx.makeLift ''GameToken -PlutusTx.unstableMakeIsData ''GameToken +PlutusTx.makeLift ''GuessToken +PlutusTx.unstableMakeIsData ''GuessToken diff --git a/plutus-use-cases/test/Spec.hs b/plutus-use-cases/test/Spec.hs index c29303c27b..291675f497 100644 --- a/plutus-use-cases/test/Spec.hs +++ b/plutus-use-cases/test/Spec.hs @@ -7,6 +7,7 @@ import Spec.Currency qualified import Spec.ErrorHandling qualified import Spec.Escrow qualified import Spec.Future qualified +import Spec.Game qualified import Spec.GameStateMachine qualified import Spec.Governance qualified import Spec.SealedBidAuction qualified @@ -48,6 +49,7 @@ tests = localOption limit $ testGroup "use cases" [ Spec.PubKey.tests, Spec.Escrow.tests, Spec.SimpleEscrow.tests, + Spec.Game.tests, Spec.GameStateMachine.tests, Spec.Rollup.tests, Spec.TokenAccount.tests, diff --git a/plutus-use-cases/test/Spec/Game.hs b/plutus-use-cases/test/Spec/Game.hs new file mode 100644 index 0000000000..a485b02386 --- /dev/null +++ b/plutus-use-cases/test/Spec/Game.hs @@ -0,0 +1,98 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE MultiWayIf #-} +{-# LANGUAGE NumericUnderscores #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE UndecidableInstances #-} +module Spec.Game + ( tests, successTrace, failTrace + ) where + +import Control.Monad (void) +import Data.Default (Default (def)) +import Data.Text (Text) +import Test.Tasty (TestTree, testGroup) +import Test.Tasty.HUnit qualified as HUnit + +import Ledger.Ada qualified as Ada +import Ledger.TimeSlot qualified as TimeSlot +import Ledger.Typed.Scripts qualified as Scripts +import Ledger.Value (Value) +import Plutus.Contract.Test (checkPredicate, goldenPir, mockWalletPaymentPubKeyHash, reasonable', valueAtAddress, w1, + w2, walletFundsChange, (.&&.)) +import Plutus.Contracts.Game (GuessArgs (GuessArgs, guessArgsGameParam, guessArgsSecret), + LockArgs (LockArgs, lockArgsGameParam, lockArgsSecret, lockArgsValue)) +import Plutus.Contracts.Game qualified as G +import Plutus.Trace.Emulator (EmulatorTrace) +import Plutus.Trace.Emulator qualified as Trace +import PlutusTx qualified + +gameParam :: G.GameParam +gameParam = G.GameParam (mockWalletPaymentPubKeyHash w1) (TimeSlot.scSlotZeroTime def) + +-- * Unit tests + +tests :: TestTree +tests = + testGroup "game state machine with secret arguments tests" + [ checkPredicate "run a successful game trace" + (walletFundsChange w2 (Ada.adaValueOf 8) + .&&. valueAtAddress (Scripts.validatorAddress $ G.gameInstance gameParam) (Ada.adaValueOf 0 ==) + .&&. walletFundsChange w1 (Ada.adaValueOf (-8))) + successTrace + + , checkPredicate "run a failed trace" + (walletFundsChange w2 mempty + .&&. valueAtAddress (Scripts.validatorAddress $ G.gameInstance gameParam) (Ada.adaValueOf 8 ==) + .&&. walletFundsChange w1 (Ada.adaValueOf (-8))) + failTrace + + , goldenPir "test/Spec/game.pir" $$(PlutusTx.compile [|| G.mkValidator ||]) + + , HUnit.testCaseSteps "script size is reasonable" $ \step -> + reasonable' step (Scripts.validatorScript $ G.gameInstance gameParam) 49000 + ] + +initialVal :: Value +initialVal = Ada.adaValueOf 10 + +-- | Wallet 1 locks some funds, and w2 then makes a correct guess. +successTrace :: EmulatorTrace () +successTrace = do + hdl <- Trace.activateContractWallet w1 $ G.contract @Text + Trace.callEndpoint @"lock" hdl LockArgs { lockArgsGameParam = gameParam + , lockArgsSecret = "hello" + , lockArgsValue = Ada.adaValueOf 8 + } + -- One slot for sending the Ada to the script. + _ <- Trace.waitNSlots 1 + hdl2 <- Trace.activateContractWallet w2 $ G.contract @Text + Trace.callEndpoint @"guess" hdl2 GuessArgs { guessArgsGameParam = gameParam + , guessArgsSecret = "hello" + } + void $ Trace.waitNSlots 1 + +-- | Wallet 1 locks some funds, and Wallet 2 makes a wrong guess. +failTrace :: EmulatorTrace () +failTrace = do + hdl <- Trace.activateContractWallet w1 $ G.contract @Text + Trace.callEndpoint @"lock" hdl LockArgs { lockArgsGameParam = gameParam + , lockArgsSecret = "hello" + , lockArgsValue = Ada.adaValueOf 8 + } + _ <- Trace.waitNSlots 1 + hdl2 <- Trace.activateContractWallet w2 $ G.contract @Text + _ <- Trace.callEndpoint @"guess" hdl2 GuessArgs { guessArgsGameParam = gameParam + , guessArgsSecret = "hola" + } + void $ Trace.waitNSlots 1 diff --git a/plutus-use-cases/test/Spec/GameStateMachine.hs b/plutus-use-cases/test/Spec/GameStateMachine.hs index 8c5ca40344..6026597605 100644 --- a/plutus-use-cases/test/Spec/GameStateMachine.hs +++ b/plutus-use-cases/test/Spec/GameStateMachine.hs @@ -33,8 +33,10 @@ import Test.Tasty hiding (after) import Test.Tasty.HUnit qualified as HUnit import Test.Tasty.QuickCheck (testProperty) +import Data.Default (Default (def)) import Ledger qualified import Ledger.Ada qualified as Ada +import Ledger.TimeSlot qualified as TimeSlot import Ledger.Typed.Scripts qualified as Scripts import Ledger.Value (Value) import Plutus.Contract.Secrets @@ -45,13 +47,18 @@ import Plutus.Contracts.GameStateMachine as G import Plutus.Trace.Emulator as Trace import PlutusTx qualified import PlutusTx.Coverage + +gameParam :: G.GameParam +gameParam = G.GameParam (mockWalletPaymentPubKeyHash w1) (TimeSlot.scSlotZeroTime def) + -- -- * QuickCheck model data GameModel = GameModel { _gameValue :: Integer , _hasToken :: Maybe Wallet - , _currentSecret :: String } + , _currentSecret :: String + } deriving (Show) makeLenses 'GameModel @@ -88,17 +95,22 @@ instance ContractModel GameModel where perform handle _ s cmd = case cmd of Lock w new val -> do Trace.callEndpoint @"lock" (handle $ WalletKey w) - LockArgs{lockArgsSecret = secretArg new, lockArgsValue = Ada.lovelaceValueOf val} + LockArgs { lockArgsGameParam = gameParam + , lockArgsSecret = secretArg new + , lockArgsValue = Ada.lovelaceValueOf val + } delay 2 Guess w old new val -> do Trace.callEndpoint @"guess" (handle $ WalletKey w) - GuessArgs{ guessArgsOldSecret = old - , guessArgsNewSecret = secretArg new - , guessArgsValueTakenOut = Ada.lovelaceValueOf val} + GuessArgs { guessArgsGameParam = gameParam + , guessArgsOldSecret = old + , guessArgsNewSecret = secretArg new + , guessArgsValueTakenOut = Ada.lovelaceValueOf val + } delay 1 GiveToken w' -> do let w = fromJust (s ^. contractState . hasToken) - _ <- Trace.payToWallet w w' gameTokenVal + _ <- Trace.payToWallet w w' guessTokenVal delay 1 -- 'nextState' descibes how each command affects the state of the model @@ -107,8 +119,8 @@ instance ContractModel GameModel where hasToken .= Just w currentSecret .= secret gameValue .= val - mint gameTokenVal - deposit w gameTokenVal + mint guessTokenVal + deposit w guessTokenVal withdraw w $ Ada.lovelaceValueOf val wait 2 @@ -124,7 +136,7 @@ instance ContractModel GameModel where w0 <- fromJust <$> viewContractState hasToken withdraw w0 $ Ada.toValue Ledger.minAdaTxOut deposit w $ Ada.toValue Ledger.minAdaTxOut - transfer w0 w gameTokenVal + transfer w0 w guessTokenVal hasToken .= Just w wait 1 @@ -183,7 +195,7 @@ prop_SanityCheckModel = propSanityCheckModel @GameModel check_prop_Game_with_coverage :: IO CoverageReport check_prop_Game_with_coverage = - quickCheckWithCoverage (set coverageIndex covIdx $ defaultCoverageOptions) $ \covopts -> + quickCheckWithCoverage (set coverageIndex (covIdx gameParam) defaultCoverageOptions) $ \covopts -> propRunActionsWithOptions @GameModel defaultCheckOptionsContractModel covopts (const (pure True)) @@ -280,39 +292,38 @@ tests :: TestTree tests = testGroup "game state machine with secret arguments tests" [ checkPredicate "run a successful game trace" - (walletFundsChange w2 (Ada.toValue Ledger.minAdaTxOut <> Ada.adaValueOf 3 <> gameTokenVal) - .&&. valueAtAddress (Scripts.validatorAddress G.typedValidator) (Ada.adaValueOf 5 ==) + (walletFundsChange w2 (Ada.toValue Ledger.minAdaTxOut <> Ada.adaValueOf 3 <> guessTokenVal) + .&&. valueAtAddress (Scripts.validatorAddress $ G.typedValidator gameParam) (Ada.adaValueOf 5 ==) .&&. walletFundsChange w1 (Ada.toValue (-Ledger.minAdaTxOut) <> Ada.adaValueOf (-8))) successTrace , checkPredicate "run a 2nd successful game trace" (walletFundsChange w2 (Ada.adaValueOf 3) - .&&. valueAtAddress (Scripts.validatorAddress G.typedValidator) (Ada.adaValueOf 0 ==) + .&&. valueAtAddress (Scripts.validatorAddress $ G.typedValidator gameParam) (Ada.adaValueOf 0 ==) .&&. walletFundsChange w1 (Ada.toValue (-Ledger.minAdaTxOut) <> Ada.adaValueOf (-8)) - .&&. walletFundsChange w3 (Ada.toValue Ledger.minAdaTxOut <> Ada.adaValueOf 5 <> gameTokenVal)) + .&&. walletFundsChange w3 (Ada.toValue Ledger.minAdaTxOut <> Ada.adaValueOf 5 <> guessTokenVal)) successTrace2 , checkPredicate "run a successful game trace where we try to leave 1 Ada in the script address" - (walletFundsChange w1 (Ada.toValue (-Ledger.minAdaTxOut) <> gameTokenVal) - .&&. valueAtAddress (Scripts.validatorAddress G.typedValidator) (Ada.toValue Ledger.minAdaTxOut ==)) + (walletFundsChange w1 (Ada.toValue (-Ledger.minAdaTxOut) <> guessTokenVal) + .&&. valueAtAddress (Scripts.validatorAddress $ G.typedValidator gameParam) (Ada.toValue Ledger.minAdaTxOut ==)) traceLeaveOneAdaInScript , checkPredicate "run a failed trace" - (walletFundsChange w2 (Ada.toValue Ledger.minAdaTxOut <> gameTokenVal) - .&&. valueAtAddress (Scripts.validatorAddress G.typedValidator) (Ada.adaValueOf 8 ==) + (walletFundsChange w2 (Ada.toValue Ledger.minAdaTxOut <> guessTokenVal) + .&&. valueAtAddress (Scripts.validatorAddress $ G.typedValidator gameParam) (Ada.adaValueOf 8 ==) .&&. walletFundsChange w1 (Ada.toValue (-Ledger.minAdaTxOut) <> Ada.adaValueOf (-8))) failTrace , goldenPir "test/Spec/gameStateMachine.pir" $$(PlutusTx.compile [|| mkValidator ||]) , HUnit.testCaseSteps "script size is reasonable" $ \step -> - reasonable' step (Scripts.validatorScript G.typedValidator) 49000 + reasonable' step (Scripts.validatorScript $ G.typedValidator gameParam) 49000 , testProperty "can always get the funds out" $ withMaxSuccess 10 prop_NoLockedFunds - , testProperty "sanity check the contract model" $ - prop_SanityCheckModel + , testProperty "sanity check the contract model" prop_SanityCheckModel ] initialVal :: Value @@ -324,14 +335,21 @@ initialVal = Ada.adaValueOf 10 successTrace :: EmulatorTrace () successTrace = do hdl <- Trace.activateContractWallet w1 G.contract - Trace.callEndpoint @"lock" hdl LockArgs{lockArgsSecret=secretArg "hello", lockArgsValue= Ada.adaValueOf 8} + Trace.callEndpoint @"lock" hdl LockArgs { lockArgsGameParam = gameParam + , lockArgsSecret = secretArg "hello" + , lockArgsValue = Ada.adaValueOf 8 + } -- One slot for sending the Ada to the script and one slot for minting the -- guess token _ <- Trace.waitNSlots 2 - _ <- Trace.payToWallet w1 w2 gameTokenVal + _ <- Trace.payToWallet w1 w2 guessTokenVal _ <- Trace.waitNSlots 1 hdl2 <- Trace.activateContractWallet w2 G.contract - Trace.callEndpoint @"guess" hdl2 GuessArgs{guessArgsOldSecret="hello", guessArgsNewSecret=secretArg "new secret", guessArgsValueTakenOut=Ada.adaValueOf 3} + Trace.callEndpoint @"guess" hdl2 GuessArgs { guessArgsGameParam = gameParam + , guessArgsOldSecret = "hello" + , guessArgsNewSecret = secretArg "new secret" + , guessArgsValueTakenOut = Ada.adaValueOf 3 + } void $ Trace.waitNSlots 1 -- | Run 'successTrace', then wallet 2 transfers the token to wallet 3, which @@ -339,10 +357,14 @@ successTrace = do successTrace2 :: EmulatorTrace () successTrace2 = do successTrace - _ <- Trace.payToWallet w2 w3 gameTokenVal + _ <- Trace.payToWallet w2 w3 guessTokenVal _ <- Trace.waitNSlots 1 hdl3 <- Trace.activateContractWallet w3 G.contract - Trace.callEndpoint @"guess" hdl3 GuessArgs{guessArgsOldSecret="new secret", guessArgsNewSecret=secretArg "hello", guessArgsValueTakenOut=Ada.adaValueOf 5} + Trace.callEndpoint @"guess" hdl3 GuessArgs { guessArgsGameParam = gameParam + , guessArgsOldSecret = "new secret" + , guessArgsNewSecret = secretArg "hello" + , guessArgsValueTakenOut = Ada.adaValueOf 5 + } void $ Trace.waitNSlots 1 -- | Tests whether the contract correctly handles the case where we leave less @@ -350,9 +372,16 @@ successTrace2 = do traceLeaveOneAdaInScript :: EmulatorTrace () traceLeaveOneAdaInScript = do hdl <- Trace.activateContractWallet w1 G.contract - Trace.callEndpoint @"lock" hdl LockArgs{lockArgsSecret=secretArg "hello", lockArgsValue= Ada.adaValueOf 8} + Trace.callEndpoint @"lock" hdl LockArgs { lockArgsGameParam = gameParam + , lockArgsSecret = secretArg "hello" + , lockArgsValue = Ada.adaValueOf 8 + } _ <- Trace.waitNSlots 2 - _ <- Trace.callEndpoint @"guess" hdl GuessArgs{guessArgsOldSecret="hello", guessArgsNewSecret=secretArg "new secret", guessArgsValueTakenOut=Ada.adaValueOf 7} + _ <- Trace.callEndpoint @"guess" hdl GuessArgs { guessArgsGameParam = gameParam + , guessArgsOldSecret = "hello" + , guessArgsNewSecret = secretArg "new secret" + , guessArgsValueTakenOut = Ada.adaValueOf 7 + } void $ Trace.waitNSlots 1 -- | Wallet 1 locks some funds, transfers the token to wallet 2 @@ -360,15 +389,22 @@ traceLeaveOneAdaInScript = do failTrace :: EmulatorTrace () failTrace = do hdl <- Trace.activateContractWallet w1 G.contract - Trace.callEndpoint @"lock" hdl LockArgs{lockArgsSecret=secretArg "hello", lockArgsValue= Ada.adaValueOf 8} + Trace.callEndpoint @"lock" hdl LockArgs { lockArgsGameParam = gameParam + , lockArgsSecret = secretArg "hello" + , lockArgsValue = Ada.adaValueOf 8 + } _ <- Trace.waitNSlots 2 - _ <- Trace.payToWallet w1 w2 gameTokenVal + _ <- Trace.payToWallet w1 w2 guessTokenVal _ <- Trace.waitNSlots 1 hdl2 <- Trace.activateContractWallet w2 G.contract - _ <- Trace.callEndpoint @"guess" hdl2 GuessArgs{guessArgsOldSecret="hola", guessArgsNewSecret=secretArg "new secret", guessArgsValueTakenOut=Ada.adaValueOf 3} + _ <- Trace.callEndpoint @"guess" hdl2 GuessArgs { guessArgsGameParam = gameParam + , guessArgsOldSecret = "hola" + , guessArgsNewSecret = secretArg "new secret" + , guessArgsValueTakenOut = Ada.adaValueOf 3 + } void $ Trace.waitNSlots 1 -gameTokenVal :: Value -gameTokenVal = - let sym = Scripts.forwardingMintingPolicyHash G.typedValidator +guessTokenVal :: Value +guessTokenVal = + let sym = Scripts.forwardingMintingPolicyHash $ G.typedValidator gameParam in G.token sym "guess" diff --git a/plutus-use-cases/test/Spec/game.pir b/plutus-use-cases/test/Spec/game.pir new file mode 100644 index 0000000000..1b76f326e3 --- /dev/null +++ b/plutus-use-cases/test/Spec/game.pir @@ -0,0 +1,43 @@ +(program + (let + (nonrec) + (typebind (tyvardecl GameParam (type)) (all a (type) (fun a a))) + (typebind (tyvardecl ScriptContext (type)) (all a (type) (fun a a))) + (datatypebind + (datatype + (tyvardecl Bool (type)) + + Bool_match + (vardecl True Bool) (vardecl False Bool) + ) + ) + (lam + ds + GameParam + (lam + hs + (con bytestring) + (lam + cs + (con bytestring) + (lam + ds + ScriptContext + [ + [ + [ + { (builtin ifThenElse) Bool } + [ + [ (builtin equalsByteString) hs ] [ (builtin sha2_256) cs ] + ] + ] + True + ] + False + ] + ) + ) + ) + ) + ) +) \ No newline at end of file diff --git a/plutus-use-cases/test/Spec/gameStateMachine.pir b/plutus-use-cases/test/Spec/gameStateMachine.pir index 0d9fb892ee..2528a81c8c 100644 --- a/plutus-use-cases/test/Spec/gameStateMachine.pir +++ b/plutus-use-cases/test/Spec/gameStateMachine.pir @@ -16051,6 +16051,10 @@ (vardecl MintToken GameInput) ) ) + (typebind + (tyvardecl GameParam (type)) + (all a (type) (fun a a)) + ) (datatypebind (datatype (tyvardecl GameState (type)) @@ -16087,523 +16091,505 @@ [ (builtin mkNilData) unitval ] ] ) - (termbind - (strict) - (vardecl w [ [ StateMachine GameState ] GameInput ]) - [ - [ + (lam + gameParam + GameParam + (let + (nonrec) + (termbind + (strict) + (vardecl + w [ [ StateMachine GameState ] GameInput ] + ) [ [ - { { StateMachine GameState } GameInput } - (lam - w - [ State GameState ] - (lam - w - GameInput - [ - { - [ { State_match GameState } w ] + [ + [ + { { StateMachine GameState } GameInput } + (lam + w + [ State GameState ] + (lam + w + GameInput [ - Maybe - [ + { + [ { State_match GameState } w ] [ - Tuple2 + Maybe [ - [ TxConstraints Void ] Void - ] - ] - [ State GameState ] - ] - ] - } - (lam - ww - GameState - (lam - ww - [ - [ - (lam - k - (type) - (lam - v - (type) + [ + Tuple2 [ - List [ [ Tuple2 k ] v ] + [ TxConstraints Void ] + Void ] - ) - ) - (con bytestring) + ] + [ State GameState ] + ] ] - [ + } + (lam + ww + GameState + (lam + ww [ - (lam - k - (type) + [ (lam - v + k (type) - [ - List - [ [ Tuple2 k ] v ] - ] + (lam + v + (type) + [ + List + [ [ Tuple2 k ] v ] + ] + ) ) - ) - (con bytestring) - ] - (con integer) - ] - ] - { - [ - [ + (con bytestring) + ] [ - { - [ GameState_match ww ] - (all - dead + [ + (lam + k (type) - [ - Maybe + (lam + v + (type) [ - [ - Tuple2 - [ - [ - TxConstraints - Void - ] - Void - ] - ] - [ - State GameState - ] + List + [ [ Tuple2 k ] v ] ] - ] + ) ) - } - (abs - dead - (type) - { - Nothing - [ + (con bytestring) + ] + (con integer) + ] + ] + { + [ + [ + [ + { [ - Tuple2 + GameState_match ww + ] + (all + dead + (type) [ + Maybe [ - TxConstraints - Void + [ + Tuple2 + [ + [ + TxConstraints + Void + ] + Void + ] + ] + [ + State + GameState + ] ] - Void ] - ] - [ State GameState ] - ] - } - ) - ] - (lam - mph - (con bytestring) - (lam - tn - (con bytestring) - (lam - s - (con bytestring) + ) + } (abs dead (type) { + Nothing [ [ - { + Tuple2 + [ [ - GameInput_match - w + TxConstraints + Void ] - (all - dead - (type) - [ - Maybe + Void + ] + ] + [ + State + GameState + ] + ] + } + ) + ] + (lam + mph + (con bytestring) + (lam + tn + (con bytestring) + (lam + s + (con bytestring) + (abs + dead + (type) + { + [ + [ + { [ + GameInput_match + w + ] + (all + dead + (type) [ - Tuple2 + Maybe [ [ - TxConstraints - Void - ] - Void - ] - ] - [ - State - GameState - ] - ] - ] - ) - } - (lam - ipv - (con - bytestring - ) - (lam - ipv - (con - bytestring - ) - (lam - ipv - [ - [ - (lam - k - (type) - (lam - v - (type) + Tuple2 [ - List [ - [ - Tuple2 - k - ] - v + TxConstraints + Void ] + Void ] - ) - ) - (con - bytestring - ) + ] + [ + State + GameState + ] + ] ] - [ + ) + } + (lam + ipv + (con + bytestring + ) + (lam + ipv + (con + bytestring + ) + (lam + ipv [ - (lam - k - (type) + [ (lam - v + k (type) - [ - List + (lam + v + (type) [ + List [ - Tuple2 - k + [ + Tuple2 + k + ] + v ] - v ] - ] + ) ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - ] - (abs - dead - (type) - { - Nothing - [ + (con + bytestring + ) + ] [ - Tuple2 [ - [ - TxConstraints - Void - ] - Void + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) ] - ] - [ - State - GameState + (con + integer + ) ] ] - } + (abs + dead + (type) + { + Nothing + [ + [ + Tuple2 + [ + [ + TxConstraints + Void + ] + Void + ] + ] + [ + State + GameState + ] + ] + } + ) + ) ) ) - ) - ) - ] - (abs - dead - (type) - [ - { - Just - [ - [ - Tuple2 - [ - [ - TxConstraints - Void - ] - Void - ] - ] - [ - State - GameState - ] - ] - } - [ + ] + (abs + dead + (type) [ { - { - Tuple2 + Just + [ [ + Tuple2 [ - TxConstraints + [ + TxConstraints + Void + ] Void ] - Void ] - } - [ - State - GameState + [ + State + GameState + ] ] } [ [ - [ + { { - { - TxConstraints + Tuple2 + [ + [ + TxConstraints + Void + ] Void - } - Void + ] } [ - { - build - TxConstraint - } - (abs - a - (type) - (lam - c - (fun + State + GameState + ] + } + [ + [ + [ + { + { + TxConstraints + Void + } + Void + } + [ + { + build TxConstraint - (fun - a - a - ) - ) - (lam - n + } + (abs a - [ - [ - c + (type) + (lam + c + (fun + TxConstraint + (fun + a + a + ) + ) + (lam + n + a [ [ + c [ [ - MustMintValue - mph + [ + [ + MustMintValue + mph + ] + unitDatum + ] + tn ] - unitDatum + (con + integer + 1 + ) ] - tn ] - (con - integer - 1 - ) + n ] - ] - n - ] + ) + ) ) - ) - ) + ] + ] + { + Nil + [ + InputConstraint + Void + ] + } ] + { + Nil + [ + OutputConstraint + Void + ] + } ] - { - Nil - [ - InputConstraint - Void - ] - } ] - { - Nil - [ - OutputConstraint - Void - ] - } - ] - ] - [ - [ - { - State - GameState - } [ [ + { + State + GameState + } [ - Locked - mph + [ + [ + Locked + mph + ] + tn + ] + s ] - tn ] - s + ww ] ] - ww ] - ] + ) ] - ) - ] - (all - dead (type) dead + (all + dead + (type) + dead + ) + } ) - } + ) ) ) - ) - ) - ] - (lam - mph - (con bytestring) - (lam - tn - (con bytestring) + ] (lam - currentSecret + mph (con bytestring) - (abs - dead - (type) - { - [ - [ - { + (lam + tn + (con bytestring) + (lam + currentSecret + (con bytestring) + (abs + dead + (type) + { + [ [ - GameInput_match - w - ] - (all - dead - (type) - [ - Maybe + { [ + GameInput_match + w + ] + (all + dead + (type) [ - Tuple2 + Maybe [ [ - TxConstraints - Void - ] - Void - ] - ] - [ - State - GameState - ] - ] - ] - ) - } - (lam - theGuess - (con - bytestring - ) - (lam - nextSecret - (con - bytestring - ) - (lam - takenOut - [ - [ - (lam - k - (type) - (lam - v - (type) + Tuple2 [ - List [ - [ - Tuple2 - k - ] - v + TxConstraints + Void ] + Void ] - ) - ) - (con - bytestring - ) + ] + [ + State + GameState + ] + ] ] - [ + ) + } + (lam + theGuess + (con + bytestring + ) + (lam + nextSecret + (con + bytestring + ) + (lam + takenOut [ - (lam - k - (type) + [ (lam - v + k (type) - [ - List + (lam + v + (type) [ + List [ - Tuple2 - k + [ + Tuple2 + k + ] + v ] - v ] - ] + ) ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - ] - (let - (nonrec) - (termbind - (nonstrict) - (vardecl - newValue + (con + bytestring + ) + ] [ [ (lam @@ -16628,379 +16614,455 @@ bytestring ) ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - ] - ) - [ - [ - [ - unionWith - addInteger - ] - ww - ] - [ - [ - fAdditiveGroupValue_cscale - fAdditiveGroupValue - ] - takenOut + (con + integer + ) ] ] - ) - (abs - dead - (type) - { - [ - [ - { + (let + (nonrec) + (termbind + (nonstrict) + (vardecl + newValue + [ [ - Bool_match - [ - [ + (lam + k + (type) + (lam + v + (type) [ - { - (builtin - ifThenElse - ) - Bool - } + List [ [ - (builtin - equalsByteString - ) - currentSecret - ] - [ - (builtin - sha2_256 - ) - theGuess + Tuple2 + k ] + v ] ] - True - ] - False - ] + ) + ) + (con + bytestring + ) ] - (all - dead - (type) + [ [ - Maybe - [ - [ - Tuple2 + (lam + k + (type) + (lam + v + (type) [ + List [ - TxConstraints - Void + [ + Tuple2 + k + ] + v ] - Void ] - ] - [ - State - GameState - ] - ] + ) + ) + (con + bytestring + ) ] - ) - } - (abs - dead - (type) + (con + integer + ) + ] + ] + ) + [ + [ + [ + unionWith + addInteger + ] + ww + ] + [ + [ + fAdditiveGroupValue_cscale + fAdditiveGroupValue + ] + takenOut + ] + ] + ) + (abs + dead + (type) + { + [ [ { - Just [ + Bool_match [ - Tuple2 [ [ - TxConstraints - Void + { + (builtin + ifThenElse + ) + Bool + } + [ + [ + (builtin + equalsByteString + ) + currentSecret + ] + [ + (builtin + sha2_256 + ) + theGuess + ] + ] ] - Void + True ] + False ] + ] + (all + dead + (type) [ - State - GameState + Maybe + [ + [ + Tuple2 + [ + [ + TxConstraints + Void + ] + Void + ] + ] + [ + State + GameState + ] + ] ] - ] + ) } - [ + (abs + dead + (type) [ { - { - Tuple2 + Just + [ [ + Tuple2 [ - TxConstraints + [ + TxConstraints + Void + ] Void ] - Void ] - } - [ - State - GameState + [ + State + GameState + ] ] } [ [ - [ + { { - { - TxConstraints + Tuple2 + [ + [ + TxConstraints + Void + ] Void - } - Void + ] } + [ + State + GameState + ] + } + [ [ [ - [ - { - { - foldr - TxConstraint - } - [ - List - TxConstraint - ] - } + { { - Cons - TxConstraint + TxConstraints + Void } - ] + Void + } [ - { - build - TxConstraint - } - (abs - a - (type) - (lam - c - (fun + [ + [ + { + { + foldr + TxConstraint + } + [ + List + TxConstraint + ] + } + { + Cons TxConstraint - (fun - a - a - ) - ) - (lam - n + } + ] + [ + { + build + TxConstraint + } + (abs a - [ - [ - c + (type) + (lam + c + (fun + TxConstraint + (fun + a + a + ) + ) + (lam + n + a [ [ + c [ [ - MustMintValue - mph + [ + [ + MustMintValue + mph + ] + unitDatum + ] + tn ] - unitDatum + (con + integer + 0 + ) ] - tn ] - (con - integer - 0 - ) + n ] - ] - n - ] + ) + ) ) - ) - ) - ] - ] - [ - { - build - TxConstraint - } - (abs - a - (type) - (lam - c - (fun + ] + ] + [ + { + build TxConstraint - (fun - a - a - ) - ) - (lam - n + } + (abs a - [ - [ - c + (type) + (lam + c + (fun + TxConstraint + (fun + a + a + ) + ) + (lam + n + a [ - MustSpendAtLeast [ + c [ - { - Cons - [ - [ - Tuple2 - (con - bytestring - ) - ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - ] - } + MustSpendAtLeast [ [ { - { - Tuple2 - (con - bytestring - ) - } + Cons [ [ - (lam - k - (type) - (lam - v + Tuple2 + (con + bytestring + ) + ] + [ + [ + (lam + k (type) - [ - List + (lam + v + (type) [ + List [ - Tuple2 - k + [ + Tuple2 + k + ] + v ] - v ] - ] + ) ) - ) + (con + bytestring + ) + ] (con - bytestring + integer ) ] - (con - integer - ) ] } - mph - ] - [ [ - { - Cons - [ - [ + [ + { + { Tuple2 (con bytestring ) + } + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) ] - (con - integer - ) - ] - } + } + mph + ] [ [ { - { + Cons + [ + [ + Tuple2 + (con + bytestring + ) + ] + (con + integer + ) + ] + } + [ + [ + { + { + Tuple2 + (con + bytestring + ) + } + (con + integer + ) + } + tn + ] + (con + integer + 1 + ) + ] + ] + { + Nil + [ + [ Tuple2 (con bytestring ) - } + ] (con integer ) - } - tn - ] + ] + } + ] + ] + ] + { + Nil + [ + [ + Tuple2 (con - integer - 1 + bytestring ) ] - ] - { - Nil [ [ - Tuple2 + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) (con bytestring ) @@ -17009,83 +17071,94 @@ integer ) ] - } - ] - ] - ] - { - Nil - [ - [ - Tuple2 - (con - bytestring - ) - ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) ] - (con - integer - ) - ] + } ] - } + ] ] + n ] - ] - n - ] + ) + ) ) - ) - ) + ] + ] ] - ] - ] - [ - [ [ - { + [ + [ + { + { + foldr + [ + InputConstraint + Void + ] + } + [ + List + [ + InputConstraint + Void + ] + ] + } + { + Cons + [ + InputConstraint + Void + ] + } + ] { - foldr + Nil [ InputConstraint Void ] } + ] + { + Nil [ - List + InputConstraint + Void + ] + } + ] + ] + [ + [ + [ + { + { + foldr + [ + OutputConstraint + Void + ] + } [ - InputConstraint + List + [ + OutputConstraint + Void + ] + ] + } + { + Cons + [ + OutputConstraint Void ] - ] - } + } + ] { - Cons + Nil [ - InputConstraint + OutputConstraint Void ] } @@ -17093,167 +17166,58 @@ { Nil [ - InputConstraint + OutputConstraint Void ] } ] - { - Nil - [ - InputConstraint - Void - ] - } ] ] [ [ - [ - { - { - foldr - [ - OutputConstraint - Void - ] - } - [ - List - [ - OutputConstraint - Void - ] - ] - } - { - Cons - [ - OutputConstraint - Void - ] - } - ] { - Nil - [ - OutputConstraint - Void - ] + State + GameState } - ] - { - Nil - [ - OutputConstraint - Void - ] - } - ] - ] - ] - [ - [ - { - State - GameState - } - { - [ - [ - { + { + [ [ - Bool_match - [ - isZero + { [ + Bool_match [ - { - Cons - [ - [ - Tuple2 - (con - bytestring - ) - ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - ] - } + isZero [ [ { - { - Tuple2 - (con - bytestring - ) - } + Cons [ [ - (lam - k - (type) + Tuple2 + (con + bytestring + ) + ] + [ + [ (lam - v + k (type) - [ - List + (lam + v + (type) [ + List [ - Tuple2 - k + [ + Tuple2 + k + ] + v ] - v ] - ] + ) ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - } - emptyByteString - ] - [ - [ - { - Cons - [ - [ - Tuple2 (con bytestring ) @@ -17262,39 +17226,137 @@ integer ) ] - } + ] + } + [ [ - [ + { { - { - Tuple2 + Tuple2 + (con + bytestring + ) + } + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) (con bytestring ) - } + ] (con integer ) - } - emptyByteString - ] + ] + } + emptyByteString + ] + [ [ + { + Cons + [ + [ + Tuple2 + (con + bytestring + ) + ] + (con + integer + ) + ] + } [ [ - valueOf - newValue + { + { + Tuple2 + (con + bytestring + ) + } + (con + integer + ) + } + emptyByteString + ] + [ + [ + [ + valueOf + newValue + ] + emptyByteString + ] + emptyByteString ] - emptyByteString ] - emptyByteString ] + { + Nil + [ + [ + Tuple2 + (con + bytestring + ) + ] + (con + integer + ) + ] + } ] ] - { - Nil + ] + { + Nil + [ + [ + Tuple2 + (con + bytestring + ) + ] [ [ - Tuple2 + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) (con bytestring ) @@ -17303,373 +17365,259 @@ integer ) ] - } - ] - ] - ] - { - Nil - [ - [ - Tuple2 - (con - bytestring - ) - ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) ] - (con - integer - ) - ] + } ] - } + ] ] - ] + (all + dead + (type) + GameState + ) + } + (abs + dead + (type) + Finished + ) ] - (all + (abs dead (type) - GameState + [ + [ + [ + Locked + mph + ] + tn + ] + nextSecret + ] ) - } - (abs + ] + (all dead (type) - Finished + dead ) - ] - (abs - dead - (type) - [ - [ - [ - Locked - mph - ] - tn - ] - nextSecret - ] - ) + } ] - (all - dead - (type) - dead - ) - } + newValue + ] ] - newValue ] - ] + ) ] - ) - ] - (abs - dead - (type) - { - Nothing - [ - [ - Tuple2 + (abs + dead + (type) + { + Nothing [ [ - TxConstraints - Void + Tuple2 + [ + [ + TxConstraints + Void + ] + Void + ] + ] + [ + State + GameState ] - Void ] - ] - [ - State - GameState - ] - ] - } - ) - ] - (all - dead - (type) - dead + } + ) + ] + (all + dead + (type) + dead + ) + } ) - } + ) ) ) ) - ) - ) - ] - (abs - dead - (type) - { - Nothing - [ - [ - Tuple2 + ] + (abs + dead + (type) + { + Nothing [ [ - TxConstraints - Void + Tuple2 + [ + [ + TxConstraints + Void + ] + Void + ] + ] + [ + State + GameState ] - Void ] - ] - [ - State - GameState - ] - ] - } - ) - ] - (all - dead (type) dead + } + ) + ] + (all + dead + (type) + dead + ) + } ) - } + ) ) ) - ) - ) - ] - (all dead (type) dead) - } - ) + ] + (all dead (type) dead) + } + ) + ) + ] ) - ] - ) - ) - ] - (lam - ds - GameState - { - [ - [ + ) + ] + (lam + ds + GameState + { [ - { - [ GameState_match ds ] - (all dead (type) Bool) - } - (abs dead (type) True) - ] - (lam - default_arg0 - (con bytestring) - (lam - default_arg1 - (con bytestring) + [ + [ + { + [ GameState_match ds ] + (all dead (type) Bool) + } + (abs dead (type) True) + ] (lam - default_arg2 + default_arg0 (con bytestring) - (abs dead (type) False) + (lam + default_arg1 + (con bytestring) + (lam + default_arg2 + (con bytestring) + (abs dead (type) False) + ) + ) ) - ) - ) - ] - (lam - default_arg0 - (con bytestring) - (lam - default_arg1 - (con bytestring) + ] (lam - default_arg2 + default_arg0 (con bytestring) - (abs dead (type) False) + (lam + default_arg1 + (con bytestring) + (lam + default_arg2 + (con bytestring) + (abs dead (type) False) + ) + ) ) - ) - ) - ] - (all dead (type) dead) - } - ) - ] - (lam - ds - GameState - (lam ds GameInput (lam ds ScriptContext True)) - ) - ] - { Nothing ThreadToken } - ] - ) - (lam - w - GameState - (lam - w - GameInput + ] + (all dead (type) dead) + } + ) + ] + (lam + ds + GameState + (lam + ds GameInput (lam ds ScriptContext True) + ) + ) + ] + { Nothing ThreadToken } + ] + ) (lam w - ScriptContext - [ - { + GameState + (lam + w + GameInput + (lam + w + ScriptContext [ { - { StateMachine_match GameState } - GameInput - } - w - ] - Bool - } - (lam - ww - (fun - [ State GameState ] - (fun - GameInput [ - Maybe - [ - [ - Tuple2 - [ [ TxConstraints Void ] Void ] - ] - [ State GameState ] - ] + { + { StateMachine_match GameState } + GameInput + } + w ] - ) - ) - (lam - ww - (fun GameState Bool) + Bool + } (lam ww (fun - GameState + [ State GameState ] (fun - GameInput (fun ScriptContext Bool) + GameInput + [ + Maybe + [ + [ + Tuple2 + [ + [ TxConstraints Void ] Void + ] + ] + [ State GameState ] + ] + ] ) ) (lam ww - [ Maybe ThreadToken ] - [ - [ + (fun GameState Bool) + (lam + ww + (fun + GameState + (fun + GameInput + (fun ScriptContext Bool) + ) + ) + (lam + ww + [ Maybe ThreadToken ] [ - (lam - w - GameState - (lam - w - GameInput + [ + [ (lam w - ScriptContext - (let - (nonrec) - (termbind - (nonstrict) - (vardecl - vl - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con bytestring) - ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] - (con integer) - ] - ] - ) - [ - { - [ - ScriptContext_match - w - ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] + GameState + (lam + w + GameInput + (lam + w + ScriptContext + (let + (nonrec) + (termbind + (nonstrict) + (vardecl + vl [ [ (lam @@ -17694,21 +17642,65 @@ bytestring ) ] - (con integer) + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) + ] ] - ] - } - (lam - ww - TxInfo - (lam - ww - ScriptPurpose - [ - { + ) + [ + { + [ + ScriptContext_match + w + ] + [ [ - TxInfo_match - ww + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) ] [ [ @@ -17734,60 +17726,34 @@ bytestring ) ] - [ + (con + integer + ) + ] + ] + } + (lam + ww + TxInfo + (lam + ww + ScriptPurpose + [ + { [ - (lam - k - (type) + TxInfo_match + ww + ] + [ + [ (lam - v + k (type) - [ - List + (lam + v + (type) [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - ] - } - (lam - ww - [ - List - TxInInfo - ] - (lam - ww - [ - List - TxOut - ] - (lam - ww - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List + List [ [ Tuple2 @@ -17831,32 +17797,21 @@ ) ] ] + } + (lam + ww + [ + List + TxInInfo + ] (lam ww [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] + List + TxOut + ] + (lam + ww [ [ (lam @@ -17881,25 +17836,84 @@ bytestring ) ] - (con - integer - ) - ] - ] - (lam - ww - [ - List - DCert + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) + ] ] (lam ww [ - List + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] [ [ - Tuple2 - StakingCredential + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) ] (con integer @@ -17909,127 +17923,80 @@ (lam ww [ - Interval - (con - integer - ) + List + DCert ] (lam ww [ List - (con - bytestring - ) + [ + [ + Tuple2 + StakingCredential + ] + (con + integer + ) + ] ] (lam ww [ - List + Interval + (con + integer + ) + ] + (lam + ww [ - [ - Tuple2 - (con - bytestring - ) - ] + List (con - data + bytestring ) ] - ] - (lam - ww - (con - bytestring - ) - { + (lam + ww [ + List [ - { + [ + Tuple2 + (con + bytestring + ) + ] + (con + data + ) + ] + ] + (lam + ww + (con + bytestring + ) + { + [ [ { - Maybe_match - TxInInfo - } - [ - [ - wfindOwnInput - ww - ] - ww - ] - ] - (all - dead - (type) - [ [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) + { + Maybe_match + TxInInfo + } + [ + [ + wfindOwnInput + ww + ] + ww + ] ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - ] - ) - } - (lam - a - TxInInfo - (abs - dead - (type) - [ - { - [ - TxInInfo_match - a - ] + (all + dead + (type) [ [ (lam @@ -18083,18 +18050,43 @@ ) ] ] - } - (lam - ds - TxOutRef - (lam - ds - TxOut - [ - { + ) + } + (lam + a + TxInInfo + (abs + dead + (type) + [ + { + [ + TxInInfo_match + a + ] + [ [ - TxOut_match - ds + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) ] [ [ @@ -18120,64 +18112,23 @@ bytestring ) ] - [ - [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] + (con + integer + ) ] - } + ] + } + (lam + ds + TxOutRef (lam ds - Address - (lam - ds - [ + TxOut + [ + { [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) + TxOut_match + ds ] [ [ @@ -18203,134 +18154,219 @@ bytestring ) ] - (con - integer - ) + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) + ] ] - ] + } (lam ds - [ - Maybe - (con - bytestring + Address + (lam + ds + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) + ] + ] + (lam + ds + [ + Maybe + (con + bytestring + ) + ] + ds ) - ] - ds + ) ) - ) + ] ) - ] - ) - ) - ] - ) - ) - ] - (abs - dead - (type) - (let - (nonrec) - (termbind - (strict) - (vardecl - thunk - (con - unit + ) + ] ) ) - [ - { - [ - Unit_match - [ - [ - { - (builtin - trace - ) - Unit - } - (con - string - "S0" - ) - ] - Unit - ] - ] - (con - unit + ] + (abs + dead + (type) + (let + (nonrec) + (termbind + (strict) + (vardecl + thunk + (con + unit + ) ) - } - unitval - ] - ) - (error - [ - [ - (lam - k - (type) - (lam - v - (type) + [ + { [ - List + Unit_match [ [ - Tuple2 - k + { + (builtin + trace + ) + Unit + } + (con + string + "S0" + ) ] - v + Unit ] ] - ) - ) - (con - bytestring - ) - ] - [ + (con + unit + ) + } + unitval + ] + ) + (error [ - (lam - k - (type) + [ (lam - v + k (type) - [ - List + (lam + v + (type) [ + List [ - Tuple2 - k + [ + Tuple2 + k + ] + v ] - v ] - ] + ) ) - ) - (con - bytestring - ) + (con + bytestring + ) + ] + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List + [ + [ + Tuple2 + k + ] + v + ] + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) + ] ] - (con - integer - ) - ] - ] + ) + ) ) + ] + (all + dead + (type) + dead ) - ) - ] - (all - dead - (type) - dead + } ) - } + ) ) ) ) @@ -18339,566 +18375,527 @@ ) ) ) - ) + ] ) - ] - ) + ) + ] ) - ] - ) - (termbind - (nonstrict) - (vardecl j Bool) - { - [ - [ - { + (termbind + (nonstrict) + (vardecl j Bool) + { + [ [ { - Maybe_match [ - [ - Tuple2 + { + Maybe_match [ [ - TxConstraints - Void + Tuple2 + [ + [ + TxConstraints + Void + ] + Void + ] ] - Void - ] - ] - [ - State - GameState - ] - ] - } - [ - [ - ww - [ - [ - { + [ State GameState - } - w + ] ] + } + [ [ + ww [ [ - unionWith - addInteger - ] - vl - ] - [ - [ - fAdditiveGroupValue_cscale - (con - integer - -1 - ) + { + State + GameState + } + w ] [ [ - threadTokenValueInner - ww + [ + unionWith + addInteger + ] + vl ] [ - ownHash - w + [ + fAdditiveGroupValue_cscale + (con + integer + -1 + ) + ] + [ + [ + threadTokenValueInner + ww + ] + [ + ownHash + w + ] + ] ] ] ] ] + w ] ] - w - ] - ] - (all - dead - (type) - Bool - ) - } - (lam - ds - [ - [ - Tuple2 + (all + dead + (type) + Bool + ) + } + (lam + ds [ [ - TxConstraints - Void + Tuple2 + [ + [ + TxConstraints + Void + ] + Void + ] + ] + [ + State + GameState ] - Void ] - ] - [ - State - GameState - ] - ] - (abs - dead - (type) - [ - { + (abs + dead + (type) [ { - { - Tuple2_match - [ - [ - TxConstraints - Void - ] - Void - ] - } - [ - State - GameState - ] - } - ds - ] - Bool - } - (lam - newConstraints - [ - [ - TxConstraints - Void - ] - Void - ] - (let - (nonrec) - (termbind - (nonstrict) - (vardecl - j - Bool - ) [ { - [ - { - { - TxConstraints_match + { + Tuple2_match + [ + [ + TxConstraints Void - } + ] Void - } - newConstraints + ] + } + [ + State + GameState ] - Bool } - (lam - ww + ds + ] + Bool + } + (lam + newConstraints + [ + [ + TxConstraints + Void + ] + Void + ] + (let + (nonrec) + (termbind + (nonstrict) + (vardecl + j + Bool + ) [ - List - TxConstraint - ] - (lam - ww - [ - List + { [ - InputConstraint - Void + { + { + TxConstraints_match + Void + } + Void + } + newConstraints ] - ] + Bool + } (lam ww [ List - [ - OutputConstraint - Void - ] + TxConstraint ] - { + (lam + ww [ + List [ - { + InputConstraint + Void + ] + ] + (lam + ww + [ + List + [ + OutputConstraint + Void + ] + ] + { + [ [ - Bool_match - [ + { [ + Bool_match [ [ [ - { - { - wcheckScriptContext - Void - } - Void - } - (lam - a - Void - { - [ - Void_match + [ + [ + { + { + wcheckScriptContext + Void + } + Void + } + (lam a - ] - (con - data + Void + { + [ + Void_match + a + ] + (con + data + ) + } ) - } - ) + ] + ww + ] + ww ] ww ] - ww + w ] - ww ] - w - ] + (all + dead + (type) + Bool + ) + } + (abs + dead + (type) + True + ) ] - (all + (abs dead (type) - Bool + [ + [ + { + (builtin + trace + ) + Bool + } + (con + string + "S4" + ) + ] + False + ] ) - } - (abs + ] + (all dead (type) - True + dead ) - ] - (abs - dead - (type) - [ - [ - { - (builtin - trace - ) - Bool - } - (con - string - "S4" - ) - ] - False - ] - ) - ] - (all - dead - (type) - dead + } ) - } + ) ) - ) - ) - ] - ) - (lam - ds - [ - State - GameState - ] - [ - { - [ - { - State_match - GameState - } - ds ] - Bool - } + ) (lam ds - GameState - (lam - ds - [ + [ + State + GameState + ] + [ + { [ - (lam - k - (type) - (lam - v - (type) - [ - List - [ - [ - Tuple2 - k - ] - v - ] - ] - ) - ) - (con - bytestring - ) + { + State_match + GameState + } + ds ] - [ - [ - (lam - k - (type) + Bool + } + (lam + ds + GameState + (lam + ds + [ + [ (lam - v + k (type) - [ - List + (lam + v + (type) [ + List [ - Tuple2 - k + [ + Tuple2 + k + ] + v ] - v ] - ] + ) ) - ) - (con - bytestring - ) - ] - (con - integer - ) - ] - ] - { - [ - [ - { - [ - Bool_match - [ - ww - ds - ] - ] - (all - dead - (type) - Bool + (con + bytestring ) - } - (abs - dead - (type) - { - [ - [ - { + ] + [ + [ + (lam + k + (type) + (lam + v + (type) + [ + List [ - Bool_match [ - isZero - ds + Tuple2 + k ] + v ] - (all - dead - (type) - Bool - ) - } - (abs - dead - (type) - j - ) + ] + ) + ) + (con + bytestring + ) + ] + (con + integer + ) + ] + ] + { + [ + [ + { + [ + Bool_match + [ + ww + ds + ] ] - (abs + (all dead (type) - { + Bool + ) + } + (abs + dead + (type) + { + [ [ - [ - { + { + [ + Bool_match [ - Bool_match - [ - [ - { - (builtin - trace - ) - Bool - } - (con - string - "S3" - ) - ] - False - ] + isZero + ds ] - (all - dead - (type) - Bool - ) - } - (abs + ] + (all dead (type) - j + Bool ) - ] + } (abs dead (type) - False + j ) ] - (all + (abs dead (type) - dead + { + [ + [ + { + [ + Bool_match + [ + [ + { + (builtin + trace + ) + Bool + } + (con + string + "S3" + ) + ] + False + ] + ] + (all + dead + (type) + Bool + ) + } + (abs + dead + (type) + j + ) + ] + (abs + dead + (type) + False + ) + ] + (all + dead + (type) + dead + ) + } ) - } - ) - ] - (all - dead - (type) - dead + ] + (all + dead + (type) + dead + ) + } ) - } - ) - ] - (abs - dead - (type) - [ - { + ] + (abs + dead + (type) [ { - { - TxConstraints_match - Void - } - Void - } - newConstraints - ] - Bool - } - (lam - ds - [ - List - TxConstraint - ] - (lam - ds - [ - List [ - InputConstraint - Void + { + { + TxConstraints_match + Void + } + Void + } + newConstraints ] - ] + Bool + } (lam ds [ List - [ - OutputConstraint - Void - ] + TxConstraint ] - { + (lam + ds [ + List [ - { - [ - Bool_match - [ + InputConstraint + Void + ] + ] + (lam + ds + [ + List + [ + OutputConstraint + Void + ] + ] + { + [ + [ + { [ + Bool_match [ [ [ - { - { - wcheckScriptContext - Void - } - GameState - } - (lam - ds - GameState - { - [ - [ + [ + [ + { + { + wcheckScriptContext + Void + } + GameState + } + (lam + ds + GameState + { [ - { - [ - GameState_match - ds - ] - (all - dead - (type) - (con - data - ) - ) - } - (abs - dead - (type) + [ [ - [ - (builtin - constrData - ) - (con - integer - 2 - ) - ] - [ - (builtin - mkNilData + { + [ + GameState_match + ds + ] + (all + dead + (type) + (con + data + ) ) - unitval - ] - ] - ) - ] - (lam - arg - (con - bytestring - ) - (lam - arg - (con - bytestring - ) - (lam - arg - (con - bytestring - ) + } (abs dead (type) @@ -18909,42 +18906,45 @@ ) (con integer - 0 + 2 ) ] [ + (builtin + mkNilData + ) + unitval + ] + ] + ) + ] + (lam + arg + (con + bytestring + ) + (lam + arg + (con + bytestring + ) + (lam + arg + (con + bytestring + ) + (abs + dead + (type) [ - { + [ (builtin - mkCons + constrData ) (con - data - ) - } - [ - (builtin - bData + integer + 0 ) - arg - ] - ] - [ - [ - { - (builtin - mkCons - ) - (con - data - ) - } - [ - (builtin - bData - ) - arg - ] ] [ [ @@ -18964,81 +18964,81 @@ ] ] [ - (builtin - mkNilData - ) - unitval + [ + { + (builtin + mkCons + ) + (con + data + ) + } + [ + (builtin + bData + ) + arg + ] + ] + [ + [ + { + (builtin + mkCons + ) + (con + data + ) + } + [ + (builtin + bData + ) + arg + ] + ] + [ + (builtin + mkNilData + ) + unitval + ] + ] ] ] ] - ] - ] + ) + ) ) ) - ) - ) - ] - (lam - arg - (con - bytestring - ) - (lam - arg - (con - bytestring - ) + ] (lam arg (con bytestring ) - (abs - dead - (type) - [ - [ - (builtin - constrData - ) - (con - integer - 1 - ) - ] - [ + (lam + arg + (con + bytestring + ) + (lam + arg + (con + bytestring + ) + (abs + dead + (type) [ - { + [ (builtin - mkCons + constrData ) (con - data - ) - } - [ - (builtin - bData + integer + 1 ) - arg - ] - ] - [ - [ - { - (builtin - mkCons - ) - (con - data - ) - } - [ - (builtin - bData - ) - arg - ] ] [ [ @@ -19058,449 +19058,498 @@ ] ] [ - (builtin - mkNilData - ) - unitval - ] - ] - ] - ] - ] - ) - ) - ) - ) - ] - (all - dead - (type) - dead - ) - } - ) - ] - ds - ] - ds - ] - [ - { - build - [ - OutputConstraint - GameState - ] - } - (abs - a - (type) - (lam - c - (fun + [ + { + (builtin + mkCons + ) + (con + data + ) + } + [ + (builtin + bData + ) + arg + ] + ] + [ + [ + { + (builtin + mkCons + ) + (con + data + ) + } + [ + (builtin + bData + ) + arg + ] + ] + [ + (builtin + mkNilData + ) + unitval + ] + ] + ] + ] + ] + ) + ) + ) + ) + ] + (all + dead + (type) + dead + ) + } + ) + ] + ds + ] + ds + ] + [ + { + build [ OutputConstraint GameState ] - (fun - a - a - ) - ) - (lam - n + } + (abs a - [ - [ - c + (type) + (lam + c + (fun + [ + OutputConstraint + GameState + ] + (fun + a + a + ) + ) + (lam + n + a [ [ - { - OutputConstraint - GameState - } - ds - ] - [ - [ - [ - unionWith - addInteger - ] - ds - ] + c [ [ - threadTokenValueInner - ww + { + OutputConstraint + GameState + } + ds ] [ - ownHash - w + [ + [ + unionWith + addInteger + ] + ds + ] + [ + [ + threadTokenValueInner + ww + ] + [ + ownHash + w + ] + ] ] ] ] + n ] - ] - n - ] + ) + ) ) - ) - ) + ] + ] + w ] ] - w - ] + (all + dead + (type) + Bool + ) + } + (abs + dead + (type) + True + ) ] - (all + (abs dead (type) - Bool + [ + [ + { + (builtin + trace + ) + Bool + } + (con + string + "S5" + ) + ] + False + ] ) - } - (abs + ] + (all dead (type) - True + dead ) - ] - (abs - dead - (type) - [ - [ - { - (builtin - trace - ) - Bool - } - (con - string - "S5" - ) - ] - False - ] - ) - ] - (all - dead - (type) - dead + } ) - } + ) ) - ) + ] ) ] - ) - ] - (all - dead - (type) - dead + (all + dead + (type) + dead + ) + } ) - } - ) + ) + ] ) - ] + ) ) - ) + ] ) + ) + ] + (abs + dead + (type) + [ + [ + { + (builtin + trace + ) + Bool + } + (con + string + "S6" + ) + ] + False ] ) + ] + (all + dead + (type) + dead ) - ] - (abs - dead - (type) + } + ) + (termbind + (nonstrict) + (vardecl j Bool) + { [ [ { - (builtin - trace + [ + { + Maybe_match + ThreadToken + } + ww + ] + (all + dead + (type) + Bool ) - Bool - } - (con - string - "S6" - ) - ] - False - ] - ) - ] - (all - dead (type) dead - ) - } - ) - (termbind - (nonstrict) - (vardecl j Bool) - { - [ - [ - { - [ - { - Maybe_match - ThreadToken } - ww - ] - (all - dead - (type) - Bool - ) - } - (lam - threadToken - ThreadToken - (abs - dead - (type) - { - [ - [ - { - [ - Bool_match - [ - [ - [ - { - (builtin - ifThenElse - ) - Bool - } - [ - [ - (builtin - equalsInteger - ) - [ - [ - [ - valueOf - vl - ] - [ - { - [ - ThreadToken_match - threadToken - ] - (con - bytestring - ) - } - (lam - ds - TxOutRef - (lam - ds - (con - bytestring - ) - ds - ) - ) - ] - ] - [ - ownHash - w - ] - ] - ] - (con - integer - 1 - ) - ] - ] - True - ] - False - ] - ] - (all - dead - (type) - Bool - ) - } - (abs - dead - (type) - j - ) - ] - (abs - dead - (type) - { + (lam + threadToken + ThreadToken + (abs + dead + (type) + { + [ [ - [ - { + { + [ + Bool_match [ - Bool_match [ [ { (builtin - trace + ifThenElse ) Bool } - (con - string - "S2" - ) + [ + [ + (builtin + equalsInteger + ) + [ + [ + [ + valueOf + vl + ] + [ + { + [ + ThreadToken_match + threadToken + ] + (con + bytestring + ) + } + (lam + ds + TxOutRef + (lam + ds + (con + bytestring + ) + ds + ) + ) + ] + ] + [ + ownHash + w + ] + ] + ] + (con + integer + 1 + ) + ] ] - False + True ] + False ] - (all - dead - (type) - Bool - ) - } - (abs + ] + (all dead (type) - j + Bool ) - ] + } (abs dead (type) - False + j ) ] - (all + (abs dead (type) - dead + { + [ + [ + { + [ + Bool_match + [ + [ + { + (builtin + trace + ) + Bool + } + (con + string + "S2" + ) + ] + False + ] + ] + (all + dead + (type) + Bool + ) + } + (abs + dead + (type) + j + ) + ] + (abs + dead + (type) + False + ) + ] + (all + dead + (type) + dead + ) + } ) - } - ) - ] - (all - dead - (type) - dead + ] + (all + dead + (type) + dead + ) + } ) - } - ) - ) - ] - (abs - dead (type) j - ) - ] - (all - dead (type) dead - ) - } - ) - { - [ - [ - { - [ - Bool_match - [ - [ - [ ww w ] w - ] - w + ) ] + (abs + dead + (type) + j + ) ] (all dead (type) - Bool + dead ) } - (abs - dead (type) j - ) - ] - (abs - dead - (type) - { + ) + { + [ [ - [ - { + { + [ + Bool_match [ - Bool_match [ [ - { - (builtin - trace - ) - Bool - } - (con - string - "S1" - ) + ww w ] - False + w ] + w ] - (all - dead - (type) - Bool - ) - } - (abs + ] + (all dead (type) - j + Bool ) - ] + } (abs dead (type) - False + j ) ] - (all + (abs dead (type) - dead + { + [ + [ + { + [ + Bool_match + [ + [ + { + (builtin + trace + ) + Bool + } + (con + string + "S1" + ) + ] + False + ] + ] + (all + dead + (type) + Bool + ) + } + (abs + dead + (type) + j + ) + ] + (abs + dead + (type) + False + ) + ] + (all + dead + (type) + dead + ) + } ) - } - ) - ] - (all dead (type) dead) - } + ] + (all + dead (type) dead + ) + } + ) + ) ) ) - ) - ) + w + ] + w + ] w ] - w - ] - w - ] + ) + ) ) ) - ) + ] ) - ] + ) ) ) ) diff --git a/plutus-use-cases/test/Spec/renderGuess.txt b/plutus-use-cases/test/Spec/renderGuess.txt index 1fc2f846a8..5387a37f28 100644 --- a/plutus-use-cases/test/Spec/renderGuess.txt +++ b/plutus-use-cases/test/Spec/renderGuess.txt @@ -101,11 +101,11 @@ Balances Carried Forward: Ada: Lovelace: 100000000 ==== Slot #1, Tx #0 ==== -TxId: fbf569fcc6703c1121cb343fe0afdb084b769d63d8582dfcb60aaba38582653e +TxId: 1bde7a47c6280b3dc4cf97d27f26e626e72ee5439f73282498ec9e74db121e16 Fee: Ada: Lovelace: 10 Mint: - Signatures PubKey: 8d9de88fbf445b7f6c3875a14daba94caee2ffcb... - Signature: 5840a14912d4e671bcb2ae5e6fe4aa6feb2df0d1... + Signature: 58406f91217fee72c4526f672ff5af07b112bf30... Inputs: ---- Input 0 ---- Destination: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) @@ -124,7 +124,7 @@ Outputs: Ada: Lovelace: 91999990 ---- Output 1 ---- - Destination: Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Destination: Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: Ada: Lovelace: 8000000 @@ -170,51 +170,51 @@ Balances Carried Forward: Value: Ada: Lovelace: 100000000 - Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: Ada: Lovelace: 8000000 ==== Slot #2, Tx #0 ==== -TxId: 10ff378ede3ce450bc76cc4c44d98c251b1def0f0ef070a45cb046c020b39b74 -Fee: Ada: Lovelace: 13958 -Mint: 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 +TxId: a1e0e22051ee8f91e0b096e7d0a7919a66015bfb737570b1810ac918308bab43 +Fee: Ada: Lovelace: 14000 +Mint: 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 Signatures PubKey: 8d9de88fbf445b7f6c3875a14daba94caee2ffcb... - Signature: 58406df9ef05ad950a06c3d51401abbe32752aaf... + Signature: 5840b88bd91e34e364f1286b6263f9d60eacc60c... Inputs: ---- Input 0 ---- Destination: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: Ada: Lovelace: 91999990 Source: - Tx: fbf569fcc6703c1121cb343fe0afdb084b769d63d8582dfcb60aaba38582653e + Tx: 1bde7a47c6280b3dc4cf97d27f26e626e72ee5439f73282498ec9e74db121e16 Output #0 ---- Input 1 ---- - Destination: Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Destination: Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: Ada: Lovelace: 8000000 Source: - Tx: fbf569fcc6703c1121cb343fe0afdb084b769d63d8582dfcb60aaba38582653e + Tx: 1bde7a47c6280b3dc4cf97d27f26e626e72ee5439f73282498ec9e74db121e16 Output #1 - Script: 59da850100003323233223332223332223333222... + Script: 59dc180100003323233223332223332223333222... Outputs: ---- Output 0 ---- Destination: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: - Ada: Lovelace: 89986032 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: - + Ada: Lovelace: 89985990 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: - ---- Output 1 ---- Destination: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 Ada: Lovelace: 2000000 ---- Output 2 ---- - Destination: Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Destination: Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: Ada: Lovelace: 8000000 @@ -242,8 +242,8 @@ Balances Carried Forward: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: - Ada: Lovelace: 91986032 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 + Ada: Lovelace: 91985990 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 PaymentPubKeyHash: a96a668ed7be83e332c872f51da7925b4472ca98... (Wallet bdf8dbca0cadeb365480c6ec29ec746a2b85274f) Value: @@ -261,34 +261,34 @@ Balances Carried Forward: Value: Ada: Lovelace: 100000000 - Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: Ada: Lovelace: 8000000 ==== Slot #3, Tx #0 ==== -TxId: ee489892ba01a05b52edb4c4fe1c3601c99fdab982029987f40e5cc9d3c493d3 +TxId: d94be30b957adb7240d7245fd8e150591993b9d03b24687abaa19c54293e3ddf Fee: Ada: Lovelace: 10 Mint: - Signatures PubKey: 8d9de88fbf445b7f6c3875a14daba94caee2ffcb... - Signature: 58403fd9943237e8d9e5c6c7b478d636213b0db3... + Signature: 58400eb39d75f894c91d48fc174c8c94e7607a27... Inputs: ---- Input 0 ---- Destination: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: - Ada: Lovelace: 89986032 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: - + Ada: Lovelace: 89985990 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: - Source: - Tx: 10ff378ede3ce450bc76cc4c44d98c251b1def0f0ef070a45cb046c020b39b74 + Tx: a1e0e22051ee8f91e0b096e7d0a7919a66015bfb737570b1810ac918308bab43 Output #0 ---- Input 1 ---- Destination: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 Ada: Lovelace: 2000000 Source: - Tx: 10ff378ede3ce450bc76cc4c44d98c251b1def0f0ef070a45cb046c020b39b74 + Tx: a1e0e22051ee8f91e0b096e7d0a7919a66015bfb737570b1810ac918308bab43 Output #1 @@ -297,13 +297,13 @@ Outputs: ---- Output 0 ---- Destination: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: - Ada: Lovelace: 89986022 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 0 + Ada: Lovelace: 89985980 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 0 ---- Output 1 ---- Destination: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) Value: - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 Ada: Lovelace: 2000000 @@ -319,7 +319,7 @@ Balances Carried Forward: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) Value: Ada: Lovelace: 102000000 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 PaymentPubKeyHash: 8952ed1aff55f5b7674b122804a3c0a96f4e2863... (Wallet 3a4778247ad35117d7c3150d194da389f3148f4a) Value: @@ -331,8 +331,8 @@ Balances Carried Forward: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: - Ada: Lovelace: 89986022 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 0 + Ada: Lovelace: 89985980 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 0 PaymentPubKeyHash: a96a668ed7be83e332c872f51da7925b4472ca98... (Wallet bdf8dbca0cadeb365480c6ec29ec746a2b85274f) Value: @@ -350,42 +350,42 @@ Balances Carried Forward: Value: Ada: Lovelace: 100000000 - Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: Ada: Lovelace: 8000000 ==== Slot #4, Tx #0 ==== -TxId: c5d2948a2aa4b4f0cb56931a5c685c2a9974bef87263eac591cd56c669cba8ae -Fee: Ada: Lovelace: 13958 -Mint: 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 0 +TxId: c8d986af4b67bebe28e2edf6826f2803d1eefe53ec790d8d92cb035a683f179a +Fee: Ada: Lovelace: 14000 +Mint: 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 0 Signatures PubKey: 98c77c40ccc536e0d433874dae97d4a0787b10b3... - Signature: 58408ea6415359396dc787edfaf25b284b0474f9... + Signature: 584064217b7032aee31d2f7b3c859f35f7ddf139... Inputs: ---- Input 0 ---- - Destination: Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Destination: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) Value: - Ada: Lovelace: 8000000 + Ada: Lovelace: 100000000 Source: - Tx: 10ff378ede3ce450bc76cc4c44d98c251b1def0f0ef070a45cb046c020b39b74 + Tx: 98d5fbcefe21113b3f0390c1441e075b8a870cc5a8fa2a56dcde1d8247e41715 Output #2 - Script: 59da850100003323233223332223332223333222... + ---- Input 1 ---- - Destination: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) + Destination: Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: - Ada: Lovelace: 100000000 + Ada: Lovelace: 8000000 Source: - Tx: 98d5fbcefe21113b3f0390c1441e075b8a870cc5a8fa2a56dcde1d8247e41715 + Tx: a1e0e22051ee8f91e0b096e7d0a7919a66015bfb737570b1810ac918308bab43 Output #2 - + Script: 59dc180100003323233223332223332223333222... ---- Input 2 ---- Destination: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) Value: - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 Ada: Lovelace: 2000000 Source: - Tx: ee489892ba01a05b52edb4c4fe1c3601c99fdab982029987f40e5cc9d3c493d3 + Tx: d94be30b957adb7240d7245fd8e150591993b9d03b24687abaa19c54293e3ddf Output #1 @@ -394,23 +394,23 @@ Outputs: ---- Output 0 ---- Destination: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) Value: - Ada: Lovelace: 100986042 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 0 + Ada: Lovelace: 100986000 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 0 ---- Output 1 ---- Destination: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) Value: - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: - + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: - Ada: Lovelace: 2000000 ---- Output 2 ---- Destination: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) Value: - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 Ada: Lovelace: 2000000 ---- Output 3 ---- - Destination: Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Destination: Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: Ada: Lovelace: 5000000 @@ -426,8 +426,8 @@ Balances Carried Forward: PaymentPubKeyHash: 80a4f45b56b88d1139da23bc4c3c75ec6d32943c... (Wallet 7ce812d7a4770bbf58004067665c3a48f28ddd58) Value: - Ada: Lovelace: 104986042 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 1 + Ada: Lovelace: 104986000 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 1 PaymentPubKeyHash: 8952ed1aff55f5b7674b122804a3c0a96f4e2863... (Wallet 3a4778247ad35117d7c3150d194da389f3148f4a) Value: @@ -439,8 +439,8 @@ Balances Carried Forward: PaymentPubKeyHash: a2c20c77887ace1cd986193e4e75babd8993cfd5... (Wallet 872cb83b5ee40eb23bfdab1772660c822a48d491) Value: - Ada: Lovelace: 89986022 - 1ce1229e49445ba21336a308a4b03067b87474c7d506a18c26edf4f9: guess: 0 + Ada: Lovelace: 89985980 + 29e8f16fda0fa2f2feec606361c87c62912818f1ec6602b92ac2eee0: guess: 0 PaymentPubKeyHash: a96a668ed7be83e332c872f51da7925b4472ca98... (Wallet bdf8dbca0cadeb365480c6ec29ec746a2b85274f) Value: @@ -458,6 +458,6 @@ Balances Carried Forward: Value: Ada: Lovelace: 100000000 - Script: 2bcd95dba6c486e77390ca441d700f26efb24ce8b40ebd95f0ffe72d + Script: 1bf560abcbb2517692fa58b726497293fb33bda17cac62b27a19e9e3 Value: Ada: Lovelace: 5000000 \ No newline at end of file