<p>The short answer is, you can't call <code>curSymbol</code> in <code>mkValidator</code> because that would involve compiling the policy and various template haskell stuff in your validator script, this cannot be done in PLC. You can instead use use Lift to pass the CurrencySymbol into <code>mkValidator</code> as an additional argument.</p>

CC BY-SA 4.0
2022-10-05T17:19:35.223Z
2022-10-05T17:19:35.223Z
james
<p>I have a minting policy which is parameterized by <code>PaymentPubKeyHash</code> and a script which checks that a token from that minting policy has been burned. The script also takes <code>PaymentPubKeyHash</code> as a parameter. I get an error when I try to compile it to plutus core.</p>
<pre><code>Program error: GHC Core to PLC plugin: E042:Error: Unsupported feature: Type constructor: GHC.Prim.ByteArray#

</code></pre>
<p>It appears to be due to the fact that I called the parameterized <code>curSymbol</code> function within the plutus validator. Is this not allowed for some reason in plutus? Are there any ways around this? It seems quite important to be able to calculate the address of a parameterized minting policy from within a validator in order to check that a token comes from an appropriate policy.</p>
<p>The code I used is below:</p>
<pre><code>{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE NoImplicitPrelude   #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}
{-# LANGUAGE NamedFieldPuns      #-}
{-# LANGUAGE MultiParamTypeClasses #-}

{-# OPTIONS_GHC -fno-ignore-interface-pragmas #-}

module CheckBurned where

import           Ledger                 hiding (mint, singleton)
import qualified Ledger.Typed.Scripts   as Scripts
import qualified PlutusTx
import           PlutusTx.Prelude       hiding (Semigroup(..), unless)
import           Ledger.Value           as Value


--This minting policy requires that the transaction is signed by the minting authority. Burning is always allowed.
{-# INLINABLE mkPolicy #-}
mkPolicy :: PaymentPubKeyHash -&gt; () -&gt; ScriptContext -&gt; Bool
mkPolicy authPkh () ctx = case flattenValue $ txInfoMint txInfo of
                            [(_,_,n)]
                              | n &lt; 0 -&gt; True --Burning is allowed.    
                              | n &gt; 0 -&gt; traceIfFalse &quot;not signed by authority&quot; signedByAuthority

                            _         -&gt; traceIfFalse &quot;Must mint/burn exactly one type of token&quot; False
  where
    txInfo = scriptContextTxInfo ctx
    signedByAuthority = txSignedBy txInfo (unPaymentPubKeyHash authPkh)

{-# INLINABLE policy #-}
policy :: PaymentPubKeyHash -&gt; Scripts.MintingPolicy
policy pkh = mkMintingPolicyScript $
  $$(PlutusTx.compile [|| Scripts.wrapMintingPolicy . mkPolicy ||])
  `PlutusTx.applyCode`
  PlutusTx.liftCode pkh

{-# INLINABLE curSymbol #-}
curSymbol :: PaymentPubKeyHash -&gt; CurrencySymbol
curSymbol = scriptCurrencySymbol . policy

--This scipt allows spending as long as it is accompanied by the burning of the corresponding token 
{-# INLINABLE mkValidator #-}
mkValidator :: PaymentPubKeyHash -&gt; () -&gt; () -&gt; ScriptContext -&gt; Bool
mkValidator pkh _ _ ctx = traceIfFalse &quot;Not correct token&quot; consumesCorrectToken
    where
        txInfo = scriptContextTxInfo ctx
        valueMinted = txInfoMint txInfo :: Value.Value
        consumesCorrectToken = valueOf valueMinted (curSymbol pkh) &quot;tn&quot; == (-1) :: Bool

data Contract1Type
instance Scripts.ValidatorTypes Contract1Type where
    type instance DatumType Contract1Type = ()
    type instance RedeemerType Contract1Type = ()

--Compiling to plutus here gives the error.
typedValidator :: PaymentPubKeyHash -&gt; Scripts.TypedValidator Contract1Type
typedValidator pkh = Scripts.mkTypedValidator @Contract1Type
    ($$(PlutusTx.compile [|| mkValidator ||])
        `PlutusTx.applyCode` PlutusTx.liftCode pkh)
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator @() @()

</code></pre>
<p>This question seems closely related to <a href="https://cardano.stackexchange.com/questions/4383/is-it-possible-to-use-a-parameterised-currencysymbol-inside-another-validator-sc">Is it possible to use a parameterised CurrencySymbol inside another validator script? Unsupported feature: Type constructor: GHC.Prim.ByteArray#</a> which didn't receive an answer. I tried to simplify the question.</p>

<plutus><plutus-pioneer-program><smart-contract><token>
Use a parameterized currencySymbol within a Plutus Validator. Unsupported feature: Type constructor: GHC.Prim.ByteArray#
# Use a parameterized currencySymbol within a Plutus Validator. Unsupported feature: Type constructor: GHC.Prim.ByteArray#

(Asked by: username_0 on 2022-10-05)

I have a minting policy which is parameterized by PaymentPubKeyHash and a script which checks that a token from that minting policy has been burned. The script also takes PaymentPubKeyHash as a parameter. I get an error when I try to compile it to plutus core.
Program error: GHC Core to PLC plugin: E042:Error: Unsupported feature: Type constructor: GHC.Prim.ByteArray#


It appears to be due to the fact that I called the parameterized curSymbol function within the plutus validator. Is this not allowed for some reason in plutus? Are there any ways around this? It seems quite important to be able to calculate the address of a parameterized minting policy from within a validator in order to check that a token comes from an appropriate policy.
The code I used is below:
{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE DeriveAnyClass      #-}
{-# LANGUAGE DeriveGeneric       #-}
{-# LANGUAGE NoImplicitPrelude   #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell     #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeFamilies        #-}
{-# LANGUAGE TypeOperators       #-}
{-# LANGUAGE NamedFieldPuns      #-}
{-# LANGUAGE MultiParamTypeClasses #-}

{-# OPTIONS_GHC -fno-ignore-interface-pragmas #-}

module CheckBurned where

import           Ledger                 hiding (mint, singleton)
import qualified Ledger.Typed.Scripts   as Scripts
import qualified PlutusTx
import           PlutusTx.Prelude       hiding (Semigroup(..), unless)
import           Ledger.Value           as Value


--This minting policy requires that the transaction is signed by the minting authority. Burning is always allowed.
{-# INLINABLE mkPolicy #-}
mkPolicy :: PaymentPubKeyHash -> () -> ScriptContext -> Bool
mkPolicy authPkh () ctx = case flattenValue $ txInfoMint txInfo of
                            [(_,_,n)]
                              | n < 0 -> True --Burning is allowed.    
                              | n > 0 -> traceIfFalse "not signed by authority" signedByAuthority

                            _         -> traceIfFalse "Must mint/burn exactly one type of token" False
  where
    txInfo = scriptContextTxInfo ctx
    signedByAuthority = txSignedBy txInfo (unPaymentPubKeyHash authPkh)

{-# INLINABLE policy #-}
policy :: PaymentPubKeyHash -> Scripts.MintingPolicy
policy pkh = mkMintingPolicyScript $
  $$(PlutusTx.compile [|| Scripts.wrapMintingPolicy . mkPolicy ||])
  `PlutusTx.applyCode`
  PlutusTx.liftCode pkh

{-# INLINABLE curSymbol #-}
curSymbol :: PaymentPubKeyHash -> CurrencySymbol
curSymbol = scriptCurrencySymbol . policy

--This scipt allows spending as long as it is accompanied by the burning of the corresponding token 
{-# INLINABLE mkValidator #-}
mkValidator :: PaymentPubKeyHash -> () -> () -> ScriptContext -> Bool
mkValidator pkh _ _ ctx = traceIfFalse "Not correct token" consumesCorrectToken
    where
        txInfo = scriptContextTxInfo ctx
        valueMinted = txInfoMint txInfo :: Value.Value
        consumesCorrectToken = valueOf valueMinted (curSymbol pkh) "tn" == (-1) :: Bool

data Contract1Type
instance Scripts.ValidatorTypes Contract1Type where
    type instance DatumType Contract1Type = ()
    type instance RedeemerType Contract1Type = ()

--Compiling to plutus here gives the error.
typedValidator :: PaymentPubKeyHash -> Scripts.TypedValidator Contract1Type
typedValidator pkh = Scripts.mkTypedValidator @Contract1Type
    ($$(PlutusTx.compile [|| mkValidator ||])
        `PlutusTx.applyCode` PlutusTx.liftCode pkh)
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator @() @()


This question seems closely related to Is it possible to use a parameterised CurrencySymbol inside another validator script? Unsupported feature: Type constructor: GHC.Prim.ByteArray# which didn't receive an answer. I tried to simplify the question.

**Tags:** plutus, plutus-pioneer-program, smart-contract, token

---

## 1 answers

### Answer by username_1 on 2022-10-05. Score: 1 | Accepted answer

The short answer is, you can't call `curSymbol` in `mkValidator` because that would involve compiling the policy and various template haskell stuff in your validator script, this cannot be done in PLC. You can instead use use Lift to pass the CurrencySymbol into `mkValidator` as an additional argument.


---

