<p>This one is a bit technical it has to do with looking up and updating the constraints of an already existing transaction (that belongs to the script address). See Case ii) to skip my synopsis.</p>
<p>Just a little synopsis for future readers: The <a href="https://github.com/input-output-hk/plutus-pioneer-program/blob/main/code/week06/src/Week06/Oracle/Core.hs" rel="nofollow noreferrer"><code>Core.hs</code></a> script is an Oracle, that has to update its datum regarding Ada price. The lines in which lookups occur are in the function <code>updateOracle</code> that has the purpose of building a transaction and then submitting it. To accomplish this the constraints need to refer to typed script inputs and outputs. In <code>updateOracle</code> we dealt with two cases</p>
<pre><code>.
.
    case m of
        Nothing -&gt; do
            ledgerTx &lt;- submitTxConstraints (typedOracleValidator oracle) c
            .
            .
        Just (oref, o,  _) -&gt; do
            let lookups = Constraints.unspentOutputs (Map.singleton oref o)     &lt;&gt;
                          Constraints.typedValidatorLookups (typedOracleValidator oracle) &lt;&gt;
                          Constraints.otherScript (oracleValidator oracle)
                tx      = c &lt;&gt; Constraints.mustSpendScriptOutput oref (Redeemer $ PlutusTx.toBuiltinData Update)
            ledgerTx &lt;- submitTxConstraintsWith @Oracling lookups tx
            .
            .
</code></pre>
<ul>
<li><p>i) Create the Oracle (if it doesn't exists) at the same time of submission and add datum.</p>
</li>
<li><p>ii) Just update the datum of an existing Oracle</p>
</li>
</ul>
<p>Case i) uses <code>submitTxConstraints</code> which takes the constraints as inputs in the form of a script instance (with typed validator hash &amp; the compiled program) and the locked value with the script.</p>
<p>Case ii) on the other hand, uses <code>submitTxConstraintsWith</code> which takes the updated constraints as <code>ScriptLookup</code> type rather than a script instance. To your question, we need to semigroup:</p>
<ul>
<li><code>Constraints.typedValidatorLookups</code> (this gets the previous
parameters of the <code>ScriptLookup</code>)</li>
<li><code>Constraints.unspentOutputs</code> (updates <code>slTxOutputs</code> from
<code>ScriptLookup</code>, which are the unspent outputs that the script wants to
spend)</li>
<li><code>Constraints.otherScript</code> (updates <code>slOtherScripts</code> from
<code>ScriptLookup</code>, which are validators of the script other than our
script)</li>
</ul>
<p>The reason why <code>Constraints.typedValidatorLookups</code> alone is not enough is because we would not be updating anything without semigrouping <code>ScriptLookup</code> element by element as defined in <a href="https://github.com/input-output-hk/plutus/blob/master/plutus-ledger/src/Ledger/Constraints/OffChain.hs" rel="nofollow noreferrer"><code>OffChain.hs</code></a>)</p>

CC BY-SA 4.0
2021-08-11T15:04:21.113Z
What do you mean by "*the previous parameters* of the ScriptLookup"? Isn't the point of these lines precisely to construct the ScriptLookup?
ZachSweet
CC BY-SA 4.0
2021-08-11T16:44:20.400Z
No, that is handled when `case m of -> Nothing` for creating the Oracle for the first time. After that we do have initial ScripLookup  parameters.
Igodlab
CC BY-SA 4.0
2021-08-11T19:42:24.063Z
Wait, so the Scriptlookup "state" is persistent while the (off-chain) contract is running in the wallet? Is that correct? I had understood that we were building everything up from scratch each time for each new transaction, on each pass. And if that is so, then where exacly is this Scriptlookup stored / why is it not lost once we leave the updateOracle function?  As far as I can make out it is not stored on the blockchain... (btw thanks for your answers so far!)
ZachSweet
CC BY-SA 4.0
2021-08-12T18:59:49.770Z
Yes, we build it from scratch the first time, ScriptLookup gives instructions to the wallet on how to create the transaction, and since transactions are unique it lives in the blockchain. Thus, we can access and update it latter on. Updates are only possible through new transactions, these are also build every time but they access to the previous state of the lookups and `<>` UTXOs out and validators.
Igodlab
CC BY-SA 4.0
2021-08-10T22:07:00.070Z
2021-08-10T22:07:00.070Z
Igodlab
<p>I share your confusion around this. I  think a lot of it is due to the flux in the codebase.</p>
<p>On the other hand, I don't think it is anything complicated. The main purpose of Lookups, and thus also those two lines is to supply information needed for the transaction.</p>
<p>I noted that <code>Constraints.otherScript</code> seems to be consistently used where a transaction consumes uTxOs and needs to supply the validator script.</p>
<p>Have a look at Lars explanation in the <a href="https://www.youtube.com/watch?v=24SHPHEc3zo" rel="nofollow noreferrer">Iteration #2 Lecture #6</a> video at 00:50h. In it he mentions that two scripts need to be supplied: one for the input uTxO (consume) and one for output uTxO. This explains why there are two entries, and my guess is that otherScript entry is to be able to consume a script uTxO.</p>

CC BY-SA 4.0
2021-08-10T18:29:26.387Z
2021-08-10T18:29:26.387Z
vcwebco
<p>Can somebody explain these lines and why (both) Constraints.typedValidatorLookups... and
Constraints.otherScript... are used? Still struggling to get my head around lookups, so maybe that is why I'm somehow failing to grasp what exactly the purpose of these lines is and why for example, just the second is not enough by itself?</p>
<pre><code>let lookups = Constraints.unspentOutputs (Map.singleton oref o)     &lt;&gt;
Constraints.typedValidatorLookups (typedValidator oracle) &lt;&gt;
Constraints.otherScript (oracleValidator oracle)```

(Core.hs : lines 169, 170)
</code></pre>

<plutus-pioneer-program><plutustx>
(Lecture #6 It #2 - Core.Hs) : Explaining lookups use of both typedValidatorLookups and otherScript?
# (Lecture #6 It #2 - Core.Hs) : Explaining lookups use of both typedValidatorLookups and otherScript?

(Asked by: username_0 on 2021-08-10)

Can somebody explain these lines and why (both) Constraints.typedValidatorLookups... and
Constraints.otherScript... are used? Still struggling to get my head around lookups, so maybe that is why I'm somehow failing to grasp what exactly the purpose of these lines is and why for example, just the second is not enough by itself?
let lookups = Constraints.unspentOutputs (Map.singleton oref o)     <>
Constraints.typedValidatorLookups (typedValidator oracle) <>
Constraints.otherScript (oracleValidator oracle)```

(Core.hs : lines 169, 170)

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

---

## 2 answers

### Answer by username_1 on 2021-08-10. Score: 2

This one is a bit technical it has to do with looking up and updating the constraints of an already existing transaction (that belongs to the script address). See Case ii) to skip my synopsis.
Just a little synopsis for future readers: The Core.hs script is an Oracle, that has to update its datum regarding Ada price. The lines in which lookups occur are in the function updateOracle that has the purpose of building a transaction and then submitting it. To accomplish this the constraints need to refer to typed script inputs and outputs. In updateOracle we dealt with two cases
.
.
    case m of
        Nothing -> do
            ledgerTx <- submitTxConstraints (typedOracleValidator oracle) c
            .
            .
        Just (oref, o,  _) -> do
            let lookups = Constraints.unspentOutputs (Map.singleton oref o)     <>
                          Constraints.typedValidatorLookups (typedOracleValidator oracle) <>
                          Constraints.otherScript (oracleValidator oracle)
                tx      = c <> Constraints.mustSpendScriptOutput oref (Redeemer $ PlutusTx.toBuiltinData Update)
            ledgerTx <- submitTxConstraintsWith @Oracling lookups tx
            .
            .


i) Create the Oracle (if it doesn't exists) at the same time of submission and add datum.

ii) Just update the datum of an existing Oracle


Case i) uses submitTxConstraints which takes the constraints as inputs in the form of a script instance (with typed validator hash & the compiled program) and the locked value with the script.
Case ii) on the other hand, uses submitTxConstraintsWith which takes the updated constraints as ScriptLookup type rather than a script instance. To your question, we need to semigroup:

Constraints.typedValidatorLookups (this gets the previous
parameters of the ScriptLookup)
Constraints.unspentOutputs (updates slTxOutputs from
ScriptLookup, which are the unspent outputs that the script wants to
spend)
Constraints.otherScript (updates slOtherScripts from
ScriptLookup, which are validators of the script other than our
script)

The reason why Constraints.typedValidatorLookups alone is not enough is because we would not be updating anything without semigrouping ScriptLookup element by element as defined in OffChain.hs)

> **Comments:**
> **username_0**: What do you mean by "*the previous parameters* of the ScriptLookup"? Isn't the point of these lines precisely to construct the ScriptLookup?  
> **username_1**: No, that is handled when `case m of -> Nothing` for creating the Oracle for the first time. After that we do have initial ScripLookup  parameters.  
> **username_0**: Wait, so the Scriptlookup "state" is persistent while the (off-chain) contract is running in the wallet? Is that correct? I had understood that we were building everything up from scratch each time for each new transaction, on each pass. And if that is so, then where exacly is this Scriptlookup stored / why is it not lost once we leave the updateOracle function?  As far as I can make out it is not stored on the blockchain... (btw thanks for your answers so far!)  
> **username_1**: Yes, we build it from scratch the first time, ScriptLookup gives instructions to the wallet on how to create the transaction, and since transactions are unique it lives in the blockchain. Thus, we can access and update it latter on. Updates are only possible through new transactions, these are also build every time but they access to the previous state of the lookups and `<>` UTXOs out and validators.  

---

### Answer by username_2 on 2021-08-10. Score: 0

I share your confusion around this. I think a lot of it is due to the flux in the codebase.

On the other hand, I don't think it is anything complicated. The main purpose of Lookups, and thus also those two lines is to supply information needed for the transaction.

I noted that `Constraints.otherScript` seems to be consistently used where a transaction consumes uTxOs and needs to supply the validator script.

Have a look at Lars explanation in the [Iteration #2 Lecture #6](https://www.youtube.com/watch?v=24SHPHEc3zo) video at 00:50h. In it he mentions that two scripts need to be supplied: one for the input uTxO (consume) and one for output uTxO. This explains why there are two entries, and my guess is that otherScript entry is to be able to consume a script uTxO.


---

