Spoiler Alert!
The solution for lesson 3 includes the following:
{-# INLINABLE mkValidator #-} -- This should validate if either beneficiary1 has signed the transaction and the current slot is before or at the deadline -- or if beneficiary2 has signed the transaction and the deadline has passed. mkValidator :: VestingDatum -> () -> ScriptContext -> Bool mkValidator dat () ctx | (unPaymentPubKeyHash (beneficiary1 dat) `elem` sigs) && (to (deadline dat) `contains` range) = True | (unPaymentPubKeyHash (beneficiary2 dat) `elem` sigs) && (from (1 + deadline dat) `contains` range) = True | otherwise = False where info :: TxInfo info = scriptContextTxInfo ctxsigs :: [PubKeyHash] sigs = txInfoSignatories info range :: POSIXTimeRange range = txInfoValidRange info
It appears that " txInfoSignatories " is a function (functor?) that analyzes " info " which itself is drawn from the script context, but I am at a loss as to where the " txInfoSignatories " code actually comes from. Is there a way to analyze which imported module it is attached to? Is there a way to analyze its code in order to understand what it does? Much of what I am seeing in Haskell seems so opaque, with new features simply appearing and magically doing something, but I am lost as to how I could have analyzed the code/modules/options and come up with this solution on my own.
For the record, here is what I created before I looked at the solution. It compiles without error, but does not behave in the playground as intended.
Any Haskell wisdom is much appreciated. I feel like this is more a Haskell knowledge deficit than anything else.{-# INLINABLE mkValidator #-} -- This should validate if either beneficiary1 has signed the transaction and the current slot is before or at the deadline -- or if beneficiary2 has signed the transaction and the deadline has passed. mkValidator :: VestingDatum -> () -> ScriptContext -> Bool -- mkValidator _ _ _ = False -- FIX ME! mkValidator dat () ctx = ( traceIfFalse "beneficiary 1 - signature missing" signedByBeneficiary1 && traceIfFalse "deadline 1 has passed" deadline1Reached ) || (traceIfFalse "beneficiary 2 - signature missing" signedByBeneficiary2 && traceIfFalse "deadline 2 not reached" deadline2Reached ) where info :: TxInfo info = scriptContextTxInfo ctxsignedByBeneficiary1 :: Bool signedByBeneficiary1 = txSignedBy info $ unPaymentPubKeyHash $ beneficiary1 dat signedByBeneficiary2 :: Bool signedByBeneficiary2 = txSignedBy info $ unPaymentPubKeyHash $ beneficiary2 dat deadline1Reached :: Bool deadline1Reached = contains (to $ deadline dat) $ txInfoValidRange info deadline2Reached :: Bool deadline2Reached = contains (from $ deadline dat) $ txInfoValidRange info