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.