- This cheastsheet is quick reminder, not a tutorial about
cooked-validators
. - Minimum prior knowledge (Cardano, general idea of what
cooked-validators
is about) is expected. - It reminds how to use or help discover
cooked-validators
features. - Code snippets are not usable as is, they give intuition and direction. Adapt them to your use case.
- In a test
Tasty.testCase "foo" $ C.testSucceeds foo
Tasty.testCase "foo" $ C.testFails foo
- In the REPL
printCooked $ interpretAndRun foo
for all tracesprintCooked $ runMockChain foo
forMonadBlockChain
traces only
- With only values
initDist :: InitialDistribution initDist = distributionFromList $ [ (wallet 1 , [ ada 42 , ada 2 <> quickValue "TOK" 1 ] , (wallet 2 , [ ada 10 ]) , (wallet 3 , [ ada 10 <> permanentValue "XYZ" 10]) ]
- With arbitrary payments
initDist :: InitialDistribution initDist = InitialDistribution [ paysPK (walletPKHash (wallet 3)) (ada 6) , paysScript fooTypedValidator FooTypedDatum (lovelaceValueOf 6_000_000) , paysPK (walletPKHash (wallet 2)) (ada 2) `withDatum` fooDatum , paysPK (walletPKHash (wallet 1)) (ada 2) `withReferenceScript` fooValidator ]
- In a test
Tasty.testCase "foo" $ testSucceedsFrom def initDist foo
- In the REPL
printCooked $ interpretAndRunWith (runMockChainTFrom initDist) foo
pcOpts :: C.PrettyCookedOpts
pcOpts =
def
{ C.pcOptHashes =
def
{ C.pcOptHashNames =
C.hashNamesFromList
[ (alice, "Alice"),
(bob, "Bob"),
(carrie, "Carie")
]
<> C.hashNamesFromList
[ (nftCurrencySymbol, "NFT"),
(customCoinsCurrencySymbol, "Custom Coins")
]
<> C.hashNamesFromList
[ (fooValidator, "Foo")
]
<> C.defaultHashNames -- IMPORTANT: must be the last element
}
}
foo :: MonadBlockChain m => m ()
foo = do
transactionOrEndpoint1
transactionOrEndpoint2
transactionOrEndpoint3
foo :: MonadBlockChain m => m ()
foo = do
...
(firstMsOfCurrentSlot, lastMsOfCurrentSlot) <- currentTime
...
foo :: MonadBlockChain m => m ()
foo = do
...
(firstMsOfCurrentSlot, lastMsOfCurrentSlot) <- currentTime
targetSlot <- getEnclosingSlot $ lastMsOfCurrentSlot + 3_600_000 -- 1 hour
awaitSlot targetSlot
...
foo :: MonadBlockChain m => m ()
foo = do
...
cardanoTx <-
validateTxSkel $
txSkelTemplate
{ txSkelIns = ...,
txSkelOuts = ...,
txSkelMints = ...,
txSkelSigners = ...
}
...
- 10 wallets:
wallet 1
towallet 10
walletAddress (wallet 3)
walletPKHash (wallet 2)
validateTxSkel $
txSkelTemplate
{ ...
txSkelSigners = [wallet 1]
...
}
paysPK (walletPKHash (wallet 3)) (lovelaceValueOf 6_000_000)
paysScript fooTypedValidator FooTypedDatum (lovelaceValueOf 6_000_000)
validateTxSkel $
txSkelTemplate
{ ...
txSkelOuts = [paysPK ..., paysScript ...]
...
}
- No redeemer:
(txOutRef, TxSkelNoRedeemerForPK)
- With redeemer:
- Regular script:
(txOutRef, TxSkelRedeemerForScript typedRedeemer)
- Reference script:
(txOutRef, TxSkelRedeemerForReferencedScript txOutRefCarryingReferenceScript typedRedeemer)
- Regular script:
validateTxSkel $
txSkelTemplate
{ ...
txSkelIns = Map.fromList [(txOutRef1, ...), (txOutRef2, ...)]
...
}
endpointFoo :: MonadBlockChain m => m (Pl.TxOutRef, Pl.TxOutRef)
endpointFoo = do
cTx <- validateTxSkel $ txSkelTemplate { ..., ... }
let (txOutRef1, _) : (txOutRef2, _) : _ = utxosFromCardanoTx cTx
return (txOutRef1, txOutRef2)
foo :: MonadBlockChain m => Pl.TxOutRef -> m ()
foo txOutRef = do
Just txOut <- txOutByRef txOutRef
foo :: MonadBlockChain m => Pl.TxOutRef -> m ()
foo txOutRef = do
Just address <- outputAddress <$> txOutByRef txOutRef
Just value <- valueFromTxOutRef txOutRef
Just datum <- typedDatumFromTxOutRef @typeOfDatum txOutRef
import qualified Plutus.Script.Utils.Scripts as Pl
- No redeemer:
(Pl.Versioned fooPolicy Pl.PlutusV2, NoMintsRedeemer, "fooName", 3)
- With redeemer:
(Pl.Versioned barPolicy Pl.PlutusV2, SomeMintsRedeemer typedRedeemer, "barName", 12)
- Burn tokens (negative amount):
(Pl.Versioned bazPolicy Pl.PlutusV2, ..., "bazName", -7)
validateTxSkel $
txSkelTemplate
{ ...
txSkelMints = txSkelMintsFromList
[ (Pl.Versioned fooPolicy Pl.PlutusV2, ..., ..., ...),
(Pl.Versioned barPolicy Pl.PlutusV2, ..., ..., ...)
]
...
}
validateTxSkel $
txSkelTemplate
{ ...
txOpts = def {txOptEnsureMinAda = True}
...
}
initialDistribution [(..., ... <> permanentValue "customToken" 1000), ...]
paysPK ... (permanentValue "customToken" 7)
paysPK ... `withDatum` FooTypedDatum
paysPK ... `withInlineDatum` FooTypedDatum
paysScriptInlineDatum fooTypedValidator FooTypedDatum (lovelaceValueOf 6_000_000)
paysPK ... `withDatumHash` FooTypedDatum
paysScriptDatumHash fooTypedValidator FooTypedDatum (lovelaceValueOf 6_000_000)
paysScriptNoDatum fooTypedValidator (lovelaceValueOf 6_000_000) `withDatum` FooTypedDatum
paysScriptNoDatum fooTypedValidator (lovelaceValueOf 6_000_000) `withInlineDatum` FooTypedDatum
paysScriptNoDatum fooTypedValidator (lovelaceValueOf 6_000_000) `withDatumHash` FooTypedDatum
validateTxSkel $
txSkelTemplate
{ ...
txSkelInsReference = Set.fromList [txOutRef1, txOutRef2, ...]
...
}
paysPK ... `withReferenceScript` fooTypedValidator
paysScript... ... `withReferenceScript` fooTypedValidator
paysPK ... `withStakingCredential` ...
paysScript... ... `withStakingCredential` ...
validateTxSkel
txSkelTemplate
{ ...
txSkelIns = Map.fromList [(scriptTxOutRefToSpend, TxSkelRedeemerForReferencedScript txOutRefCarryingReferenceScript redeemer), ...],
...
}
First signer:
validateTxSkel $
txSkelTemplate
{ ...
txSkelSigners = [wallet 1, wallet 2]
...
}
Another signer:
validateTxSkel $
txSkelTemplate
{ ...
txSkelSigners = [wallet 1, wallet 2],
txOpts = def {txOptBalanceWallet = BalanceWith (wallet 2)}
...
}
validateTxSkel $
txSkelTemplate
{ ...
txOpts = def {txOptBalancingUtxos = BalancingUtxosDatumless}
...
}
foo :: MonadBlockChain m => m ()
foo = do
...
-- searchResults :: [(Pl.TxOutRef, Pl.TxOut)]
searchResults <- runUtxoSearch $ allUtxos
...
foo :: MonadBlockChain m => m ()
foo = do
...
-- searchResults :: [(Pl.TxOutRef, Pl.TxOut)]
searchResults <- runUtxoSearch $ utxosAtSearch (walletAddress (wallet 2))
...
foo :: MonadBlockChain m => m ()
foo = do
...
searchResults <-
runUtxoSearch $
allUtxos `filterWithPred` ((== Pl.lovelaceValueOf 10_000_000) . outputValue)
...
foo :: MonadBlockChain m => m ()
foo = do
...
searchResults <- runUtxoSearch $ allUtxos `filterWithPure` isOutputWithoutDatum
...
foo :: MonadBlockChain m => m ()
foo = do
...
searchResults <-
runUtxoSearch $
utxosAtSearch (walletAddress (wallet 2))
`filterWithPure` isOutputWithoutDatum
`filterWithPred` ((== Pl.lovelaceValueOf 10_000_000) . outputValue)
...
foo :: MonadBlockChain m => m ()
foo = do
bar `withTweak` modification
foo :: MonadBlockChain m => m ()
foo = do
bar `withTweak` ( do
addOutputTweak $ paysScript bazValidator bazDatum bazValue
removeOutputTweak (\(Pays out) -> somePredicate out)
addInputTweak somePkTxOutRef C.TxSkelNoRedeemerForPK
removeInputTweak (\txOutRef redeemer -> somePredicate txOutRef redeemer)
)
foo :: MonadBlockChain m => m ()
foo = do
bar `withTweak` ( do
addSignersTweak [alice, bob]
replaceFirstSigner carol
removeSigners [eve]
)
foo :: MonadBlockChain m => m ()
foo = do
bar `withTweak` ( do
C.overTweak
(txSkelOutsL % _head % txSkelOutValueL) -- Value of first output
(<> assetClassValue bazAssetClass 10) -- Add 10 baz tokens
)