<p><code>TxInfo</code> is a Record type and one of the fields of the <code>TxInfo</code>-record is <code>txInfoSignatories</code>. The fields in the records work as &quot;getters&quot;. You may refer e.g. to <a href="http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax" rel="nofollow noreferrer">learnyouhaskell-records</a> for an example.</p>
<p>The whole definition for <code>TxInfo</code> is here:</p>
<p><a href="https://i.sstatic.net/vvRNk.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/vvRNk.png" alt="TxInfo" /></a></p>
<p>It is also completely fine to use the <code>txSignedBy</code> helper function as you have done to check whether the given hash is one of the signatories.</p>

CC BY-SA 4.0
2022-01-31T21:31:45.530Z
Your answer simply moves my question from  txInfoSignatories   to TxInfo. Where does TxInfo come from? It is not defined in the code for Solution1.hs. If I (in the repl) do ":i TxInfo" or ":t TxInfo" or simply "TxInfo" I get a "variable not in scope" error message. Where does that definition (a very nice and helpful definition to be sure) for TxInfo come from, and how could I have found it on my own?
XiTouch
CC BY-SA 4.0
2022-01-31T22:42:31.710Z
It is one of the fields of the ScriptContext ctx, see "info :: TxInfo
    info = scriptContextTxInfo ctx". In repl, do "import Ledger" then ":i TxInfo" and ":i ScriptContext" should work.
Mihai Codescu
CC BY-SA 4.0
2022-01-31T23:50:30.120Z
Thank you @MihaiCodescu, I see that now. Is there a way to quickly trace/track these nested types/data/functions/records or is a tedious hunting mission necessary when reverse engineering? BTW, I discovered the :browse command in the repl, which does help.
XiTouch
CC BY-SA 4.0
2022-02-01T05:32:48.613Z
@XiTouch It also helps to remember that the validators in the extended UTXO model "see" the whole transaction they are about to validate. In other words: the context where the script is run contains full transaction info. Thus, it is not a big surprise to find TxInfo within ScriptContext.
hsteamroller
CC BY-SA 4.0
2022-02-02T15:51:06.270Z
I spent a day creating this animation to visualize the connections and sources of each part. Hope this helps anyone else.   https://www.youtube.com/watch?v=ZLURnogC_kU
XiTouch
CC BY-SA 4.0
2022-02-03T20:39:44.023Z
Impressive animation!
hsteamroller
CC BY-SA 4.0
2022-01-31T18:32:57.633Z
2022-02-01T05:41:51.987Z
2022-02-01T05:41:51.987Z
hsteamroller
<p>Spoiler Alert!</p>
<p>The solution for lesson 3 includes the following:</p>
<blockquote><pre>
{-# 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 ctx
<pre><code>sigs :: [PubKeyHash]
sigs = txInfoSignatories info

range :: POSIXTimeRange
range = txInfoValidRange info
</code></pre>
<p></pre></blockquote></p>
<p>It appears that &quot; txInfoSignatories &quot; is a function (functor?) that analyzes &quot; info &quot; which itself is drawn from the script context, but I am at a loss as to where the &quot; txInfoSignatories &quot; 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.</p>
<p>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.</p>
<blockquote><pre>
{-# 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 ctx
<pre><code>signedByBeneficiary1 :: 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
</code></pre>
<p></pre></blockquote>
Any Haskell wisdom is much appreciated. I feel like this is more a Haskell knowledge deficit than anything else.</p>

<plutus-pioneer-program><haskell>
Lesson 3 - unsure how "sigs" is created or where txInfoSignatories comes from or how it works
# Lesson 3 - unsure how "sigs" is created or where txInfoSignatories comes from or how it works

(Asked by: username_0 on 2022-01-31)

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 ctx
sigs :: [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.

{-# 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 ctx
signedByBeneficiary1 :: 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


Any Haskell wisdom is much appreciated. I feel like this is more a Haskell knowledge deficit than anything else.

**Tags:** plutus-pioneer-program, haskell

---

## 1 answers

### Answer by username_1 on 2022-01-31. Score: 3 | Accepted answer

`TxInfo` is a Record type and one of the fields of the `TxInfo`-record is `txInfoSignatories`. The fields in the records work as "getters". You may refer e.g. to [learnyouhaskell-records](http://learnyouahaskell.com/making-our-own-types-and-typeclasses#record-syntax) for an example.

The whole definition for `TxInfo` is here:

[![TxInfo](https://i.sstatic.net/vvRNk.png)](https://i.sstatic.net/vvRNk.png)

It is also completely fine to use the `txSignedBy` helper function as you have done to check whether the given hash is one of the signatories.

> **Comments:**
> **username_0**: Your answer simply moves my question from  txInfoSignatories   to TxInfo. Where does TxInfo come from? It is not defined in the code for Solution1.hs. If I (in the repl) do ":i TxInfo" or ":t TxInfo" or simply "TxInfo" I get a "variable not in scope" error message. Where does that definition (a very nice and helpful definition to be sure) for TxInfo come from, and how could I have found it on my own?  
> **username_2**: It is one of the fields of the ScriptContext ctx, see "info :: TxInfo     info = scriptContextTxInfo ctx". In repl, do "import Ledger" then ":i TxInfo" and ":i ScriptContext" should work.  
> **username_0**: Thank you @MihaiCodescu, I see that now. Is there a way to quickly trace/track these nested types/data/functions/records or is a tedious hunting mission necessary when reverse engineering? BTW, I discovered the :browse command in the repl, which does help.  
> **username_1**: @XiTouch It also helps to remember that the validators in the extended UTXO model "see" the whole transaction they are about to validate. In other words: the context where the script is run contains full transaction info. Thus, it is not a big surprise to find TxInfo within ScriptContext.  
> **username_0**: I spent a day creating this animation to visualize the connections and sources of each part. Hope this helps anyone else.   https://www.youtube.com/watch?v=ZLURnogC_kU  
> **username_1**: Impressive animation!  

---

