Skip to content

Commit

Permalink
Upgrade plutus-use-cases to use V2 scripts, plutus-contract StateMach…
Browse files Browse the repository at this point in the history
…ine needed upgrading too
  • Loading branch information
James Browning committed Jan 24, 2023
1 parent 3c47d52 commit 721df12
Show file tree
Hide file tree
Showing 30 changed files with 243 additions and 214 deletions.
4 changes: 2 additions & 2 deletions plutus-contract/src/Plutus/Contract/Oracle.hs
Expand Up @@ -63,14 +63,14 @@ import PlutusTx.Prelude (Applicative (pure), Either (Left, Right), Eq ((==)), ma
import Ledger.Address (PaymentPrivateKey (unPaymentPrivateKey), PaymentPubKey (PaymentPubKey))
import Ledger.Constraints (TxConstraints)
import Ledger.Constraints qualified as Constraints
import Ledger.Constraints.OnChain.V1 qualified as Constraints
import Ledger.Constraints.OnChain.V2 qualified as Constraints
import Ledger.Crypto (Passphrase, PubKey (..), Signature (..))
import Ledger.Crypto qualified as Crypto
import Ledger.Scripts (Datum (Datum), DatumHash (DatumHash))
import Plutus.Script.Utils.Scripts qualified as Scripts
import Plutus.V1.Ledger.Bytes (LedgerBytes (LedgerBytes))
import Plutus.V1.Ledger.Contexts (ScriptContext)
import Plutus.V1.Ledger.Time (POSIXTime)
import Plutus.V2.Ledger.Contexts (ScriptContext)

import Prelude qualified as Haskell

Expand Down
8 changes: 4 additions & 4 deletions plutus-contract/src/Plutus/Contract/StateMachine.hs
Expand Up @@ -68,7 +68,7 @@ import Ledger (POSIXTime, Slot, TxOutRef, Value)
import Ledger qualified
import Ledger.Constraints (ScriptLookups, TxConstraints (txOwnInputs, txOwnOutputs), UnbalancedTx,
mustMintValueWithRedeemer, mustPayToTheScriptWithDatumInTx, mustSpendOutputFromTheScript,
mustSpendPubKeyOutput, plutusV1MintingPolicy)
mustSpendPubKeyOutput, plutusV2MintingPolicy)
import Ledger.Constraints.OffChain qualified as Constraints
import Ledger.Tx qualified as Tx
import Ledger.Typed.Scripts qualified as Scripts
Expand All @@ -85,7 +85,7 @@ import Plutus.Contract.StateMachine.OnChain (State (State, stateData, stateValue
StateMachineInstance (StateMachineInstance, stateMachine, typedValidator))
import Plutus.Contract.StateMachine.OnChain qualified as SM
import Plutus.Contract.StateMachine.ThreadToken (ThreadToken (ThreadToken), curPolicy, ttOutRef)
import Plutus.Script.Utils.V1.Scripts (scriptCurrencySymbol)
import Plutus.Script.Utils.V2.Scripts (scriptCurrencySymbol)
import Plutus.Script.Utils.V2.Typed.Scripts qualified as Typed
import Plutus.V2.Ledger.Tx qualified as V2
import PlutusTx qualified
Expand Down Expand Up @@ -446,7 +446,7 @@ runInitialiseWith customLookups customConstraints StateMachineClient{scInstance}
mustMintValueWithRedeemer red (SM.threadTokenValueOrZero scInstance)
<> mustSpendPubKeyOutput ttOutRef
lookups = Constraints.typedValidatorLookups typedValidator
<> foldMap (plutusV1MintingPolicy . curPolicy . ttOutRef) (smThreadToken stateMachine)
<> foldMap (plutusV2MintingPolicy . curPolicy . ttOutRef) (smThreadToken stateMachine)
<> Constraints.unspentOutputs utxo
<> customLookups
utx <- mkTxConstraints lookups constraints
Expand Down Expand Up @@ -543,7 +543,7 @@ mkStep client@StateMachineClient{scInstance} input = do
lookups =
Constraints.typedValidatorLookups typedValidator
<> Constraints.unspentOutputs utxo
<> if isFinal then foldMap (plutusV1MintingPolicy . curPolicy . ttOutRef) (smThreadToken stateMachine) else mempty
<> if isFinal then foldMap (plutusV2MintingPolicy . curPolicy . ttOutRef) (smThreadToken stateMachine) else mempty
red = Ledger.Redeemer (PlutusTx.toBuiltinData (Scripts.validatorHash typedValidator, Burn))
unmint = if isFinal then mustMintValueWithRedeemer red (inv $ SM.threadTokenValueOrZero scInstance) else mempty
-- Add the thread token value back to the output
Expand Down
18 changes: 9 additions & 9 deletions plutus-contract/src/Plutus/Contract/StateMachine/OnChain.hs
Expand Up @@ -31,14 +31,14 @@ import Data.Void (Void)
import GHC.Generics (Generic)
import Ledger (CardanoAddress)
import Ledger.Constraints (TxConstraints (txOwnOutputs), mustPayToTheScriptWithDatumInTx)
import Ledger.Constraints.OnChain.V1 (checkScriptContext)
import Ledger.Typed.Scripts (DatumType, RedeemerType, TypedValidator, ValidatorTypes, validatorCardanoAddress,
validatorHash)
import Ledger.Constraints.OnChain.V2 (checkScriptContext)
import Ledger.Typed.Scripts (DatumType, RedeemerType, ValidatorTypes, validatorCardanoAddress, validatorHash)
import Ledger.Value (Value, isZero)
import Plutus.Script.Utils.V1.Typed.Scripts qualified as PV1
import Plutus.V1.Ledger.Api (ValidatorHash)
import Plutus.V1.Ledger.Contexts (ScriptContext, TxInInfo (txInInfoResolved), findOwnInput, ownHash)
import Plutus.V1.Ledger.Tx qualified as PV1
import Plutus.Script.Utils.V2.Typed.Scripts (TypedValidator, ValidatorType)
import Plutus.Script.Utils.V2.Typed.Scripts qualified as PV2
import Plutus.V2.Ledger.Api (ValidatorHash)
import Plutus.V2.Ledger.Contexts (ScriptContext, TxInInfo (txInInfoResolved), findOwnInput, ownHash)
import Plutus.V2.Ledger.Tx qualified as PV2
import PlutusTx qualified
import PlutusTx.Prelude hiding (check)
import Prelude qualified as Haskell
Expand Down Expand Up @@ -114,9 +114,9 @@ machineAddress = validatorCardanoAddress (Testnet $ NetworkMagic 1) . typedValid

{-# INLINABLE mkValidator #-}
-- | Turn a state machine into a validator script.
mkValidator :: forall s i. (PlutusTx.ToData s) => StateMachine s i -> PV1.ValidatorType (StateMachine s i)
mkValidator :: forall s i. (PlutusTx.ToData s) => StateMachine s i -> ValidatorType (StateMachine s i)
mkValidator (StateMachine step isFinal check threadToken) currentState input ptx =
let vl = maybe (traceError "S0" {-"Can't find validation input"-}) (PV1.txOutValue . txInInfoResolved) (findOwnInput ptx)
let vl = maybe (traceError "S0" {-"Can't find validation input"-}) (PV2.txOutValue . txInInfoResolved) (findOwnInput ptx)
checkOk =
traceIfFalse "S1" {-"State transition invalid - checks failed"-} (check currentState input ptx)
&& traceIfFalse "S2" {-"Thread token not found"-} (TT.checkThreadToken threadToken (ownHash ptx) vl 1)
Expand Down
16 changes: 8 additions & 8 deletions plutus-contract/src/Plutus/Contract/StateMachine/ThreadToken.hs
Expand Up @@ -26,8 +26,8 @@ import Ledger.Scripts
import Ledger.Value (TokenName (..), Value (..))
import Ledger.Value qualified as Value
import Plutus.Contract.StateMachine.MintingPolarity (MintingPolarity (..))
import Plutus.Script.Utils.Typed (ScriptContextV1, mkUntypedMintingPolicy)
import Plutus.V1.Ledger.Contexts qualified as V
import Plutus.Script.Utils.Typed (ScriptContextV2, mkUntypedMintingPolicy)
import Plutus.V2.Ledger.Contexts qualified as V2
import PlutusTx qualified
import Prelude qualified as Haskell

Expand All @@ -42,12 +42,12 @@ data ThreadToken = ThreadToken
PlutusTx.makeIsDataIndexed ''ThreadToken [('ThreadToken,0)]
PlutusTx.makeLift ''ThreadToken

checkPolicy :: TxOutRef -> (ValidatorHash, MintingPolarity) -> V.ScriptContext -> Bool
checkPolicy (TxOutRef refHash refIdx) (vHash, mintingPolarity) ctx@V.ScriptContext{V.scriptContextTxInfo=txinfo} =
checkPolicy :: TxOutRef -> (ValidatorHash, MintingPolarity) -> V2.ScriptContext -> Bool
checkPolicy (TxOutRef refHash refIdx) (vHash, mintingPolarity) ctx@V2.ScriptContext{V2.scriptContextTxInfo=txinfo} =
let
ownSymbol = V.ownCurrencySymbol ctx
ownSymbol = V2.ownCurrencySymbol ctx

minted = V.txInfoMint txinfo
minted = V2.txInfoMint txinfo
expected = if mintingPolarity == Burn then -1 else 1

-- True if the pending transaction mints the amount of
Expand All @@ -59,14 +59,14 @@ checkPolicy (TxOutRef refHash refIdx) (vHash, mintingPolarity) ctx@V.ScriptConte
-- True if the pending transaction spends the output
-- identified by @(refHash, refIdx)@
txOutputSpent =
let v = V.spendsOutput txinfo refHash refIdx
let v = V2.spendsOutput txinfo refHash refIdx
in traceIfFalse "S8" {-"Pending transaction does not spend the designated transaction output"-} v

in mintOK && (if mintingPolarity == Mint then txOutputSpent else True)

curPolicy :: TxOutRef -> MintingPolicy
curPolicy outRef = mkMintingPolicyScript $
$$(PlutusTx.compile [|| \r -> mkUntypedMintingPolicy @ScriptContextV1 (checkPolicy r) ||])
$$(PlutusTx.compile [|| \r -> mkUntypedMintingPolicy @ScriptContextV2 (checkPolicy r) ||])
`PlutusTx.applyCode`
PlutusTx.liftCode outRef

Expand Down
9 changes: 5 additions & 4 deletions plutus-contract/test/Spec/ThreadToken.hs
Expand Up @@ -13,13 +13,14 @@ import Prelude (Show, String, show)

import Control.Monad (void)
import GHC.Generics (Generic)
import Ledger.Typed.Scripts (TypedValidator, mkTypedValidator)
import Ledger.Typed.Scripts (TypedValidator)
import Plutus.Contract (Contract, EmptySchema, logError, mapError)
import Plutus.Contract.StateMachine (StateMachine, StateMachineClient, ThreadToken, mkStateMachine, stateData)
import Plutus.Contract.StateMachine qualified as SM
import Plutus.Contract.Test
import Plutus.Script.Utils.Typed (ScriptContextV1)
import Plutus.Script.Utils.Typed (ScriptContextV2)
import Plutus.Script.Utils.V1.Typed.Scripts qualified as Scripts
import Plutus.Script.Utils.V2.Typed.Scripts qualified as V2
import Plutus.Trace (EmulatorTrace, activateContractWallet)
import Plutus.Trace qualified as Trace
import PlutusTx qualified
Expand Down Expand Up @@ -55,12 +56,12 @@ stateMachine threadToken =

typedValidator :: ThreadToken -> TypedValidator (StateMachine State Input)
typedValidator threadToken =
mkTypedValidator @(StateMachine State Input)
V2.mkTypedValidator @(StateMachine State Input)
($$(PlutusTx.compile [||validator||]) `PlutusTx.applyCode` PlutusTx.liftCode threadToken)
$$(PlutusTx.compile [||wrap||])
where
validator c = SM.mkValidator (stateMachine c)
wrap = Scripts.mkUntypedValidator @ScriptContextV1 @State @Input
wrap = Scripts.mkUntypedValidator @ScriptContextV2 @State @Input

stateMachineClient :: ThreadToken -> StateMachineClient State Input
stateMachineClient threadToken =
Expand Down
9 changes: 5 additions & 4 deletions plutus-use-cases/src/Plutus/Contracts/Auction.hs
Expand Up @@ -46,6 +46,7 @@ import Plutus.Contract.StateMachine (State (..), StateMachine (..), StateMachine
WaitingResult (..))
import Plutus.Contract.StateMachine qualified as SM
import Plutus.Contract.Util (loopM)
import Plutus.Script.Utils.V2.Typed.Scripts qualified as PV2
import PlutusTx qualified
import PlutusTx.Code
import PlutusTx.Coverage
Expand Down Expand Up @@ -162,13 +163,13 @@ auctionStateMachine (threadToken, auctionParams) =
isFinal _ = False

{-# INLINABLE mkValidator #-}
mkValidator :: (ThreadToken, AuctionParams) -> Scripts.ValidatorType AuctionMachine
mkValidator :: (ThreadToken, AuctionParams) -> PV2.ValidatorType AuctionMachine
mkValidator = SM.mkValidator . auctionStateMachine

-- | The script instance of the auction state machine. It contains the state
-- machine compiled to a Plutus core validator script.
typedValidator :: (ThreadToken, AuctionParams) -> Scripts.TypedValidator AuctionMachine
typedValidator = Scripts.mkTypedValidatorParam @AuctionMachine
typedValidator :: (ThreadToken, AuctionParams) -> PV2.TypedValidator AuctionMachine
typedValidator = PV2.mkTypedValidatorParam @AuctionMachine
$$(PlutusTx.compile [|| mkValidator ||])
$$(PlutusTx.compile [|| wrap ||])
where
Expand All @@ -178,7 +179,7 @@ typedValidator = Scripts.mkTypedValidatorParam @AuctionMachine
-- with the on-chain code, and the Haskell definition of the state machine for
-- off-chain use.
machineClient
:: Scripts.TypedValidator AuctionMachine
:: PV2.TypedValidator AuctionMachine
-> ThreadToken -- ^ Thread token of the instance
-> AuctionParams
-> StateMachineClient AuctionState AuctionInput
Expand Down
2 changes: 1 addition & 1 deletion plutus-use-cases/src/Plutus/Contracts/Crowdfunding.hs
Expand Up @@ -133,7 +133,7 @@ refundRange :: Campaign -> ValidityInterval.ValidityInterval PV1.POSIXTime
refundRange cmp = ValidityInterval.from (campaignCollectionDeadline cmp)

data Crowdfunding
instance PV2.ValidatorTypes Crowdfunding where
instance Scripts.ValidatorTypes Crowdfunding where
type instance RedeemerType Crowdfunding = CampaignAction
type instance DatumType Crowdfunding = PaymentPubKeyHash

Expand Down
18 changes: 9 additions & 9 deletions plutus-use-cases/src/Plutus/Contracts/Currency.hs
Expand Up @@ -32,7 +32,7 @@ import Control.Lens
import Data.Aeson (FromJSON, ToJSON)
import Data.Semigroup (Last (..))
import GHC.Generics (Generic)
import Plutus.V1.Ledger.Contexts qualified as V
import Plutus.V2.Ledger.Contexts qualified as V2
import PlutusTx qualified
import PlutusTx.AssocMap qualified as AssocMap
import PlutusTx.Prelude hiding (Monoid (..), Semigroup (..))
Expand All @@ -45,7 +45,7 @@ import Ledger.Value (TokenName, Value)
import Ledger.Value qualified as Value
import Plutus.Contract as Contract
import Plutus.Contract.Request (getUnspentOutput)
import Plutus.Script.Utils.V1.Scripts qualified as PV1
import Plutus.Script.Utils.V2.Scripts qualified as PV2

import Control.Monad (void)
import Prelude (Semigroup (..))
Expand Down Expand Up @@ -80,13 +80,13 @@ mkCurrency (TxOutRef h i) amts =
, curAmounts = AssocMap.fromList amts
}

checkPolicy :: OneShotCurrency -> () -> V.ScriptContext -> Bool
checkPolicy c@(OneShotCurrency (refHash, refIdx) _) _ ctx@V.ScriptContext{V.scriptContextTxInfo=txinfo} =
checkPolicy :: OneShotCurrency -> () -> V2.ScriptContext -> Bool
checkPolicy c@(OneShotCurrency (refHash, refIdx) _) _ ctx@V2.ScriptContext{V2.scriptContextTxInfo=txinfo} =
let
-- see note [Obtaining the currency symbol]
ownSymbol = V.ownCurrencySymbol ctx
ownSymbol = V2.ownCurrencySymbol ctx

minted = V.txInfoMint txinfo
minted = V2.txInfoMint txinfo
expected = currencyValue ownSymbol c

-- True if the pending transaction mints the amount of
Expand All @@ -98,7 +98,7 @@ checkPolicy c@(OneShotCurrency (refHash, refIdx) _) _ ctx@V.ScriptContext{V.scri
-- True if the pending transaction spends the output
-- identified by @(refHash, refIdx)@
txOutputSpent =
let v = V.spendsOutput txinfo refHash refIdx
let v = V2.spendsOutput txinfo refHash refIdx
in traceIfFalse "C1" {-"Pending transaction does not spend the designated transaction output"-} v

in mintOK && txOutputSpent
Expand All @@ -117,7 +117,7 @@ for example in 'mintedValue'.
Inside the validator script (on-chain) we can't use 'Ledger.scriptAddress',
because at that point we don't know the hash of the script yet. That
is why we use 'V.ownCurrencySymbol', which obtains the hash from the
is why we use 'V2.ownCurrencySymbol', which obtains the hash from the
'PolicyCtx' value.
-}
Expand All @@ -127,7 +127,7 @@ mintedValue :: OneShotCurrency -> Value
mintedValue cur = currencyValue (currencySymbol cur) cur

currencySymbol :: OneShotCurrency -> CurrencySymbol
currencySymbol = PV1.scriptCurrencySymbol . curPolicy
currencySymbol = PV2.scriptCurrencySymbol . curPolicy

newtype CurrencyError =
CurContractError ContractError
Expand Down
15 changes: 8 additions & 7 deletions plutus-use-cases/src/Plutus/Contracts/Escrow.hs
Expand Up @@ -51,16 +51,14 @@ import Control.Monad.Error.Lens (throwing)
import Data.Aeson (FromJSON, ToJSON)
import GHC.Generics (Generic)

import Plutus.V1.Ledger.Api (ScriptContext (..), TxInfo (..))
import Plutus.Script.Utils.V2.Contexts (ScriptContext (..), TxInfo (..), scriptOutputsAt, txInfoValidRange, txSignedBy)
import PlutusTx qualified
import PlutusTx.Code
import PlutusTx.Coverage
import PlutusTx.Prelude hiding (Applicative (..), Semigroup (..), check, foldMap)

import Cardano.Node.Emulator.Params (pNetworkId)
import Ledger (POSIXTime, PaymentPubKeyHash (unPaymentPubKeyHash), TxId, getCardanoTxId, scriptOutputsAt, txSignedBy,
valuePaidTo)
import Ledger qualified
import Ledger (POSIXTime, PaymentPubKeyHash (unPaymentPubKeyHash), TxId, getCardanoTxId)
import Ledger.Constraints (TxConstraints)
import Ledger.Constraints qualified as Constraints
import Ledger.Constraints.ValidityInterval qualified as Interval
Expand All @@ -71,7 +69,10 @@ import Ledger.Typed.Scripts qualified as Scripts
import Ledger.Value (Value, geq, lt)
import Plutus.Contract
import Plutus.Script.Utils.Scripts (datumHash)
import Plutus.Script.Utils.V2.Typed.Scripts qualified as V2
import Plutus.V1.Ledger.Scripts (Datum (Datum), DatumHash, ValidatorHash)
import Plutus.V2.Ledger.Contexts (valuePaidTo)
import Plutus.V2.Ledger.Tx (OutputDatum (OutputDatumHash))

import Prelude (Semigroup (..), foldMap)
import Prelude qualified as Haskell
Expand Down Expand Up @@ -197,7 +198,7 @@ meetsTarget ptx = \case
ScriptTarget validatorHash dataValue vl ->
case scriptOutputsAt validatorHash ptx of
[(dataValue', vl')] ->
traceIfFalse "dataValue" (dataValue' == dataValue)
traceIfFalse "dataValue" (dataValue' == (OutputDatumHash dataValue))
&& traceIfFalse "value" (vl' `geq` vl)
_ -> False

Expand All @@ -212,9 +213,9 @@ validate EscrowParams{escrowDeadline, escrowTargets} contributor action ScriptCo
traceIfFalse "escrowDeadline-before" ((escrowDeadline - 1) `before` txInfoValidRange scriptContextTxInfo)
&& traceIfFalse "txSignedBy" (scriptContextTxInfo `txSignedBy` unPaymentPubKeyHash contributor)

typedValidator :: EscrowParams Datum -> Scripts.TypedValidator Escrow
typedValidator :: EscrowParams Datum -> V2.TypedValidator Escrow
typedValidator escrow = go (Haskell.fmap datumHash escrow) where
go = Scripts.mkTypedValidatorParam @Escrow
go = V2.mkTypedValidatorParam @Escrow
$$(PlutusTx.compile [|| validate ||])
$$(PlutusTx.compile [|| wrap ||])
wrap = Scripts.mkUntypedValidator
Expand Down
13 changes: 7 additions & 6 deletions plutus-use-cases/src/Plutus/Contracts/Future.hs
Expand Up @@ -63,9 +63,10 @@ import Plutus.Contract
import Plutus.Contract.Oracle (Observation (..), SignedMessage (..))
import Plutus.Contract.Oracle qualified as Oracle
import Plutus.Contract.Util (loopM)
import Plutus.Script.Utils.V1.Address (mkValidatorAddress)
import Plutus.Script.Utils.V1.Scripts (validatorHash)
import Plutus.V1.Ledger.Api (Datum (Datum), Validator, ValidatorHash)
import Plutus.Script.Utils.V2.Address (mkValidatorAddress)
import Plutus.Script.Utils.V2.Scripts (validatorHash)
import Plutus.Script.Utils.V2.Typed.Scripts qualified as V2
import Plutus.V2.Ledger.Api (Datum (Datum), Validator, ValidatorHash)

import Plutus.Contract.StateMachine (AsSMContractError, State (..), StateMachine (..), Void)
import Plutus.Contract.StateMachine qualified as SM
Expand Down Expand Up @@ -309,17 +310,17 @@ futureStateMachine ft fos = SM.mkStateMachine Nothing (transition ft fos) isFina
isFinal Finished = True
isFinal _ = False

typedValidator :: Future -> FutureAccounts -> Scripts.TypedValidator (SM.StateMachine FutureState FutureAction)
typedValidator :: Future -> FutureAccounts -> V2.TypedValidator (SM.StateMachine FutureState FutureAction)
typedValidator future ftos =
let val = $$(PlutusTx.compile [|| validatorParam ||])
`PlutusTx.applyCode`
PlutusTx.liftCode future
`PlutusTx.applyCode`
PlutusTx.liftCode ftos
validatorParam f g = SM.mkValidator (futureStateMachine f g)
wrap = Scripts.mkUntypedValidator @Scripts.ScriptContextV1 @FutureState @FutureAction
wrap = Scripts.mkUntypedValidator @Scripts.ScriptContextV2 @FutureState @FutureAction

in Scripts.mkTypedValidator @(SM.StateMachine FutureState FutureAction)
in V2.mkTypedValidator @(SM.StateMachine FutureState FutureAction)
val
$$(PlutusTx.compile [|| wrap ||])

Expand Down

0 comments on commit 721df12

Please sign in to comment.