<p><code>Script.validatorHash</code> can not be compiled to Plutus Core (probably for good reason, as it would've resulted in much larger on-chain scripts).</p>
<p><a href="https://cardano.stackexchange.com/a/9007/7225">As Erik mentioned</a>, if you only need the hash of your current validator, <code>ownHash</code> is the answer. But if you want to recreate the validator hash of another script on the fly, that's not possible.</p>
<p>A typical solution is to provide this desired validator hash as a parameter to your current script, and therefore make it &quot;aware&quot; of your other script.</p>

CC BY-SA 4.0
2022-09-07T02:19:03.817Z
Is there any other work-around to calculate script address onchain? Even if others have provided the validator hash in, checking on it seems necessary to prevent bad actors on exploiting the script
SIDAN Whatever
CC BY-SA 4.0
2022-09-08T01:51:48.550Z
Generating a script hash from parameters is a somewhat resource intensive task, so it may not even be possible to achieve that within the 16KB transaction size constraint.

This depends on your contract of course, but one solution might be for your script to demand the presence of a known asset (i.e. native token) from the arbitrary script you're trying to check. This has the additional benefit of making sure that said script is in fact capable of spending its UTxOs.
keyanm
CC BY-SA 4.0
2022-09-06T11:32:05.180Z
2022-09-06T11:32:05.180Z
keyanm
<p>I suspect that this might actually be a GHC Template Haskell (TH) staging error. My understanding is that when you use TH in a file, it must all be expanded (TH is basically a macro expansion system) on the first TH evaluation pass.</p>
<p>Your function <code>valHash</code> calls <code>typedValidator</code> which includes TH functionality and then you are tying to call that within <code>mkValidator</code> which also uses TH. That is why I think you are actually hitting a staging error due to the implicit recursion of <code>mkValidate</code> -&gt; <code>valHash</code> -&gt; <code>typeValidator</code> -&gt; <code>mkValidate</code>.</p>
<p>The current solution (not really that nice IMO) is to provide (ie hard code) the hash itself to <code>mkValidate</code>. You can probably also write a test to validate that the supplied hash is the same as the actual hash provided by TH.</p>
<p><strong>Update</strong>: Apparently there is an <code>ownHash</code> in the Plutus libs that will give you the hash of a validator inside the same validator. I have not tried it.</p>

CC BY-SA 4.0
2022-09-07T02:16:32.243Z
How about I want to calculate the script address on chain to conduct the checking? Simply submitting a validator hash in provides loophole for bad actors to exploit. Is it somewhat impossible as mentioned by @KeyanM & @Tuvshintsenguun?
SIDAN Whatever
CC BY-SA 4.0
2022-09-06T05:29:03.583Z
2022-09-06T06:14:35.350Z
2022-09-06T06:14:35.350Z
Erik de Castro Lopo
<p>In this case, when compiling your validator, compiler is trying to compute a value (which is only available after successfully compiled your validator) to complete compiling your validator, thus, it's impossible case.</p>
<p>Your validator is parameterized validator so with each different parameter, it's different validator with different validator hash.</p>
<p>If you want to get outputs of the same validator with same parameter then, that's same validator with same validator hash so there is a <code>getContinuingOutputs</code> function you can use or <code>findContinuingOutputs</code> if you are only interested in amount. Also <code>ownHash</code> is available for getting the validator hash within the same validator.</p>
<p>If it's the case that you want to check an output is locked by the same validator but with different parameter, then it's no longer same validator, it's a completely different validator with different validator hash even if the source code is the same. In this case, you probably might want to provide validator hash directly to the validator via datum or redeemer rather than providing the different parameter which is not possible to compute hash from.</p>

CC BY-SA 4.0
2022-09-07T02:21:29.897Z
I am looking for checking whether some value is correctly paid to "certain parameterized scripts" while I dont know the script address beforehand. Certainly I could remove to parameter field to use `getContinuingOutputs` entirely, but sometimes I also want to enable it to look at other validator and minting script as well. Any thought any workaround instead of using above code to compute?
SIDAN Whatever
CC BY-SA 4.0
2022-09-07T06:53:19.253Z
If you want to check for "another validator" and have the functionality at hands for future cases, i would suggest you to dynamically provide the validator hash to the validator either via datum or via redeemer.
Tuvshintsenguun
CC BY-SA 4.0
2022-09-07T06:59:01.897Z
About computing script's hash (minting script or validator) on chain, i am not sure if it's possible. Let's say, that, it's possible to compute hash on chain from script's binary. How are you going to put binary in the validator? Hard code it? or again, via datum or redeemer? We now came back to the first step. If binary can be hard-coded, why not the hash of it? Same question for datum and redeemer.
Tuvshintsenguun
CC BY-SA 4.0
2022-09-06T06:42:36.290Z
2022-09-06T06:42:36.290Z
Tuvshintsenguun
<p>Supposed I have a validator below, checking only if the output value is locked by the same script.</p>
<pre class="lang-haskell prettyprint-override"><code>{-# INLINEABLE mkValidator #-}
mkValidator :: TestingParam -&gt; TestingDatum -&gt; TestingRedeemer -&gt; ScriptContext -&gt; Bool
mkValidator param _ red ctx = case red of
  (MergeScript anotherParam) -&gt; 
    traceIfFalse &quot;Script provided is incorrect&quot; (valueLockedBy info (valHash anotherParam) == txOutValue ownInput)
  _ -&gt; False
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    ownInput :: TxOut
    ownInput = case findOwnInput ctx of
      Nothing -&gt; traceError &quot;input missing&quot;
      Just i -&gt; txInInfoResolved i

{-# INLINABLE typedValidator #-}
typedValidator :: TestingParam -&gt; Scripts.TypedValidator TestingScript
typedValidator param =
  Scripts.mkTypedValidator @TestingScript
    ($$(PlutusTx.compile [||mkValidator||]) `PlutusTx.applyCode` PlutusTx.liftCode param)
    $$(PlutusTx.compile [||wrap||])
  where
    wrap = Scripts.wrapValidator @TestingDatum @TestingRedeemer

{-# INLINABLE validator #-}
validator :: TestingParam -&gt; Validator
validator = Scripts.validatorScript . typedValidator

{-# INLINABLE valHash #-}
valHash :: TestingParam -&gt; Ledger.ValidatorHash
valHash = Scripts.validatorHash . typedValidator
</code></pre>
<p>However, it then throws the error <code>GHC Core to PLC plugin: E043:Error: Reference to a name which is not a local, a builtin, or an external INLINABLE function: Variable OtherScripts.Testing.ReferenceTesting.valHash</code>.</p>
<p>Another similar issue with supplying minting policy here:
<a href="https://cardano.stackexchange.com/questions/8327/using-cursymbol-function-in-validator-script">Using `curSymbol` function in Validator script</a></p>
<p>Looked at several sources and stuck with this issue for months. Can someone advises me if it is a dead end current Plutus ability?</p>
<p>If so, happy to see if someone is interested in drafting a CIP for this together, since allowing to use <code>mkValidator</code> or <code>mkMintingPolicy</code> script externally allows another level of scripts composibility which I think is essential for Cardano smart contract to get into mainstream. Also, this would enable scripts to be composed more secured as validator could know the identity of other scripts they are interacting with, instead of just hardcoding-supplying a validator hash externally.</p>

<script><validator><policy><plutus-core><reference-request>
Is it possible to call the `mkValidator` inside the same / another `mkValidator` function for script composibility?
# Is it possible to call the `mkValidator` inside the same / another `mkValidator` function for script composibility?

(Asked by: username_0 on 2022-09-06)

Supposed I have a validator below, checking only if the output value is locked by the same script.
{-# INLINEABLE mkValidator #-}
mkValidator :: TestingParam -> TestingDatum -> TestingRedeemer -> ScriptContext -> Bool
mkValidator param _ red ctx = case red of
  (MergeScript anotherParam) -> 
    traceIfFalse "Script provided is incorrect" (valueLockedBy info (valHash anotherParam) == txOutValue ownInput)
  _ -> False
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    ownInput :: TxOut
    ownInput = case findOwnInput ctx of
      Nothing -> traceError "input missing"
      Just i -> txInInfoResolved i

{-# INLINABLE typedValidator #-}
typedValidator :: TestingParam -> Scripts.TypedValidator TestingScript
typedValidator param =
  Scripts.mkTypedValidator @TestingScript
    ($$(PlutusTx.compile [||mkValidator||]) `PlutusTx.applyCode` PlutusTx.liftCode param)
    $$(PlutusTx.compile [||wrap||])
  where
    wrap = Scripts.wrapValidator @TestingDatum @TestingRedeemer

{-# INLINABLE validator #-}
validator :: TestingParam -> Validator
validator = Scripts.validatorScript . typedValidator

{-# INLINABLE valHash #-}
valHash :: TestingParam -> Ledger.ValidatorHash
valHash = Scripts.validatorHash . typedValidator

However, it then throws the error GHC Core to PLC plugin: E043:Error: Reference to a name which is not a local, a builtin, or an external INLINABLE function: Variable OtherScripts.Testing.ReferenceTesting.valHash.
Another similar issue with supplying minting policy here:
Using `curSymbol` function in Validator script
Looked at several sources and stuck with this issue for months. Can someone advises me if it is a dead end current Plutus ability?
If so, happy to see if someone is interested in drafting a CIP for this together, since allowing to use mkValidator or mkMintingPolicy script externally allows another level of scripts composibility which I think is essential for Cardano smart contract to get into mainstream. Also, this would enable scripts to be composed more secured as validator could know the identity of other scripts they are interacting with, instead of just hardcoding-supplying a validator hash externally.

**Tags:** script, validator, policy, plutus-core, reference-request

---

## 3 answers

### Answer by username_3 on 2022-09-06. Score: 3

In this case, when compiling your validator, compiler is trying to compute a value (which is only available after successfully compiled your validator) to complete compiling your validator, thus, it's impossible case.

Your validator is parameterized validator so with each different parameter, it's different validator with different validator hash.

If you want to get outputs of the same validator with same parameter then, that's same validator with same validator hash so there is a `getContinuingOutputs` function you can use or `findContinuingOutputs` if you are only interested in amount. Also `ownHash` is available for getting the validator hash within the same validator.

If it's the case that you want to check an output is locked by the same validator but with different parameter, then it's no longer same validator, it's a completely different validator with different validator hash even if the source code is the same. In this case, you probably might want to provide validator hash directly to the validator via datum or redeemer rather than providing the different parameter which is not possible to compute hash from.

> **Comments:**
> **username_0**: I am looking for checking whether some value is correctly paid to "certain parameterized scripts" while I dont know the script address beforehand. Certainly I could remove to parameter field to use `getContinuingOutputs` entirely, but sometimes I also want to enable it to look at other validator and minting script as well. Any thought any workaround instead of using above code to compute?  
> **username_3**: If you want to check for "another validator" and have the functionality at hands for future cases, i would suggest you to dynamically provide the validator hash to the validator either via datum or via redeemer.  
> **username_3**: About computing script's hash (minting script or validator) on chain, i am not sure if it's possible. Let's say, that, it's possible to compute hash on chain from script's binary. How are you going to put binary in the validator? Hard code it? or again, via datum or redeemer? We now came back to the first step. If binary can be hard-coded, why not the hash of it? Same question for datum and redeemer.  

---

### Answer by username_1 on 2022-09-06. Score: 1

`Script.validatorHash` can not be compiled to Plutus Core (probably for good reason, as it would've resulted in much larger on-chain scripts).

[As Erik mentioned](https://cardano.stackexchange.com/a/9007/7225), if you only need the hash of your current validator, `ownHash` is the answer. But if you want to recreate the validator hash of another script on the fly, that's not possible.

A typical solution is to provide this desired validator hash as a parameter to your current script, and therefore make it "aware" of your other script.

> **Comments:**
> **username_0**: Is there any other work-around to calculate script address onchain? Even if others have provided the validator hash in, checking on it seems necessary to prevent bad actors on exploiting the script  
> **username_1**: Generating a script hash from parameters is a somewhat resource intensive task, so it may not even be possible to achieve that within the 16KB transaction size constraint.  This depends on your contract of course, but one solution might be for your script to demand the presence of a known asset (i.e. native token) from the arbitrary script you're trying to check. This has the additional benefit of making sure that said script is in fact capable of spending its UTxOs.  

---

### Answer by username_2 on 2022-09-06. Score: 0

I suspect that this might actually be a GHC Template Haskell (TH) staging error. My understanding is that when you use TH in a file, it must all be expanded (TH is basically a macro expansion system) on the first TH evaluation pass.

Your function `valHash` calls `typedValidator` which includes TH functionality and then you are tying to call that within `mkValidator` which also uses TH. That is why I think you are actually hitting a staging error due to the implicit recursion of `mkValidate` -> `valHash` -> `typeValidator` -> `mkValidate`.

The current solution (not really that nice IMO) is to provide (ie hard code) the hash itself to `mkValidate`. You can probably also write a test to validate that the supplied hash is the same as the actual hash provided by TH.

**Update**: Apparently there is an `ownHash` in the Plutus libs that will give you the hash of a validator inside the same validator. I have not tried it.

> **Comments:**
> **username_0**: How about I want to calculate the script address on chain to conduct the checking? Simply submitting a validator hash in provides loophole for bad actors to exploit. Is it somewhat impossible as mentioned by @KeyanM & @Tuvshintsenguun?  

---

