0

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.

1 Answer 1

1

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.