2

I am having trouble using a parameterised CurrencySymbol inside another validator script. It seems to work (not shown here) when the currency symbol is unparametrised but not otherwise:

GHC Core to PLC plugin: E042:Error: Unsupported feature: Type constructor: GHC.Prim.ByteArray#
Context: Compiling type: GHC.Prim.ByteArray#
Context: Compiling data constructor type: GHC.Integer.Type.BN#
Context: Compiling type: GHC.Integer.Type.BigNat
Context: Compiling data constructor type: GHC.Natural.NatJ#
Context: Compiling type: GHC.Natural.Natural
Context: Compiling data constructor type: PlutusCore.Core.Type.Version
Context: Compiling type: PlutusCore.Core.Type.Version ann
Context: Compiling data constructor type: UntypedPlutusCore.Core.Type.Program
Context: Compiling type: UntypedPlutusCore.Core.Type.Program
                           PlutusCore.DeBruijn.Internal.DeBruijn
                           PlutusCore.Default.Universe.DefaultUni
                           PlutusCore.Default.Builtins.DefaultFun
                           ()
Context: Compiling type: Plutus.V1.Ledger.Scripts.Script
Context: Compiling type: Plutus.V1.Ledger.Scripts.MintingPolicy
Context: Compiling type: Plutus.V1.Ledger.Scripts.MintingPolicy
                         -> Data.ByteString.Internal.ByteString
Context: Compiling definition of: Ledger.Scripts.mintingPolicyHash1
Context: Compiling expr: Ledger.Scripts.mintingPolicyHash1
Context: Compiling expr: Ledger.Scripts.mintingPolicyHash1
                           (TestContract.tokenPolicy oref nm)
Context: Compiling expr: \ (nm [Occ=Once]
                              :: Plutus.V1.Ledger.Value.TokenName) ->
                           Ledger.Scripts.mintingPolicyHash1
                             (TestContract.tokenPolicy oref nm)
Context: Compiling expr: \ (oref [Occ=Once] :: Plutus.V1.Ledger.Tx.TxOutRef)
                           (nm [Occ=Once] :: Plutus.V1.Ledger.Value.TokenName) ->
                           Ledger.Scripts.mintingPolicyHash1
                             (TestContract.tokenPolicy oref nm)
Context: Compiling expr: (\ (oref [Occ=Once]
                               :: Plutus.V1.Ledger.Tx.TxOutRef)
                            (nm [Occ=Once] :: Plutus.V1.Ledger.Value.TokenName) ->
                            Ledger.Scripts.mintingPolicyHash1
                              (TestContract.tokenPolicy oref nm))
                         `cast` (<Plutus.V1.Ledger.Tx.TxOutRef>_R
                                 ->_R <Plutus.V1.Ledger.Value.TokenName>_R
                                 ->_R Sym (PlutusTx.Builtins.Internal.N:BuiltinByteString[0]) ; Sym (Plutus.V1.Ledger.Value.N:CurrencySymbol[0])
                                 :: GHC.Types.Coercible
                                      (Plutus.V1.Ledger.Tx.TxOutRef
                                       -> Plutus.V1.Ledger.Value.TokenName
                                       -> Data.ByteString.Internal.ByteString)
                                      (Plutus.V1.Ledger.Tx.TxOutRef
                                       -> Plutus.V1.Ledger.Value.TokenName
                                       -> Plutus.V1.Ledger.Value.CurrencySymbol))
Context: Compiling definition of: TestContract.tokenSymbol
Context: Compiling expr: TestContract.tokenSymbol
Context: Compiling expr: TestContract.tokenSymbol oref'_a3cNp
Context: Compiling expr: TestContract.tokenSymbol
                           oref'_a3cNp tn'_a3cNq
Context: Compiling expr: TestContract.mkTestValidator
                           (TestContract.tokenSymbol oref'_a3cNp tn'_a3cNq)
Context: Compiling expr: \ (tn'_a3cNq
                              :: Plutus.V1.Ledger.Value.TokenName) ->
                           TestContract.mkTestValidator
                             (TestContract.tokenSymbol oref'_a3cNp tn'_a3cNq)
Context: Compiling expr: \ (oref'_a3cNp :: Plutus.V1.Ledger.Tx.TxOutRef)
                           (tn'_a3cNq :: Plutus.V1.Ledger.Value.TokenName) ->
                           TestContract.mkTestValidator
                             (TestContract.tokenSymbol oref'_a3cNp tn'_a3cNq)
Context: Compiling expr at "test-contract-0.1.0.0-inplace:TestContract:(116,9)-(116,94)"

Here are my imports:

{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wno-partial-type-signatures #-}
{-# OPTIONS_GHC -w #-}
-- {-# OPTIONS_GHC -fno-specialise #-}
-- {-# OPTIONS_GHC -fno-strictness #-}
-- {-# OPTIONS_GHC -fno-ignore-interface-pragmas #-}
-- {-# OPTIONS_GHC -fno-omit-interface-pragmas #-}
-- {-# OPTIONS_GHC -fobject-code #-}

module TestContract where

import Data.Kind (Type)
import Ledger.Interval qualified as Interval
import Ledger.Contexts qualified as Context
import Ledger.Crypto qualified as Crypto
import Ledger.Scripts qualified as Scripts
import Ledger.Typed.Scripts qualified as Scripts
import Ledger.Typed.Scripts.Validators qualified as Validator
import Ledger.Tx qualified as Tx
import Plutus.V1.Ledger.Ada qualified as Ada
import Plutus.V1.Ledger.Api qualified as Api
import Plutus.V1.Ledger.Address qualified as Address
import Plutus.V1.Ledger.Time qualified as Time
import Plutus.V1.Ledger.Value qualified as Value
import PlutusTx qualified
import PlutusTx.AssocMap qualified as Assoc
import PlutusTx.Prelude ((&&), (<=))
import PlutusTx.Prelude qualified as Plutus
import PlutusTx.TH qualified as PlutusTx
import Prelude (undefined, ($), (.))

Below, I've defined a policy that always returns True, the real logic is more complicated but the error message is the same. It's essentially identical to the NFT minting policy from Plutus Pioneers lecture 5 - hence TxOutRef and TokenName as inputs. As mentioned earlier, removing these 2 parameters is fine for compilation (deleting any necessary lifting).

{-# Inlineable mkTokenPolicy #-}
mkTokenPolicy :: Tx.TxOutRef
              -> Value.TokenName
              -> ()
              -> Context.ScriptContext
              -> Plutus.Bool
mkTokenPolicy oref nm ()
  scriptContext@Context.ScriptContext {scriptContextTxInfo = scriptContextTxInfo} =
    Plutus.True
   
tokenPolicy :: Tx.TxOutRef -> Value.TokenName -> Scripts.MintingPolicy
tokenPolicy oref nm =
  Scripts.mkMintingPolicyScript
    ($$(PlutusTx.compile [|| \oref' tn' -> Scripts.wrapMintingPolicy (mkTokenPolicy oref' tn') ||])
      `PlutusTx.applyCode`
    PlutusTx.liftCode oref
      `PlutusTx.applyCode`
    PlutusTx.liftCode nm)

{-# Inlineable tokenSymbol #-}
tokenSymbol :: Tx.TxOutRef -> Value.TokenName -> Value.CurrencySymbol
tokenSymbol oref nm =
  Context.scriptCurrencySymbol (tokenPolicy oref nm)

The tokenSymbol is just a parametrised CurrencySymbol of the NFT. The problematic code appears to be below when I try to compile this.

{-# Inlineable typedValidator #-}
typedValidator :: Tx.TxOutRef -> Value.TokenName -> Scripts.TypedValidator TestData
typedValidator oref nm =
  Scripts.mkTypedValidator @TestData
    ($$(PlutusTx.compile [|| \oref' tn' -> mkTestValidator (tokenSymbol oref' tn') ||])
       `PlutusTx.applyCode`
       PlutusTx.liftCode oref
       `PlutusTx.applyCode`
       PlutusTx.liftCode nm)
    $$(PlutusTx.compile [|| wrap ||])
  where
    wrap = Scripts.wrapValidator

The last line of the error:

Context: Compiling expr at "test-contract-0.1.0.0-inplace:TestContract:(116,9)-(116,94)"

is complaining about this line:

$$(PlutusTx.compile [|| \oref' tn' -> mkTestValidator (tokenSymbol oref' tn') ||])

I am defining TestData slightly differently, hence the absent type application in wrap. Prior to this bug, when my currency symbol was unparametrised, the below definition worked.

type (:--:) :: Type -> Type -> Type -> Type
newtype (redeemer :--: datum) a = Foo a

instance Scripts.ValidatorTypes ((redeemer :--: datum) a) where
  type RedeemerType ((redeemer :--: datum) a) = redeemer
  type DatumType ((redeemer :--: datum) a) = datum

data TestData
  deriving
    (Scripts.ValidatorTypes)
    via (TestAction :--: TestDatum) TestData

although this is equivalent to (with type application in wrap):

-- data TestData
-- instance Scripts.ValidatorTypes TestData where
--   type RedeemerType TestData = TestAction
--   type DatumType    TestData = TestDatum

I didn't provide any detail on mkTestValidator, nor my redeemer or datum. The reason being I only had issues after parameterising.

The error message seems to suggest the prohibited use of Natural. I'm not aware of direct usage in my code, but in https://alpha.marlowe.iohkdev.io/doc/haddock/plutus-core/html/UntypedPlutusCore-Core-Type.html Version is defined to use Natural, and Version is contained in Program. Is there a restriction on PLC when using a validator script defined above?

Plutus tag: 9879b31579d0deb863f3cdf27f93419deec3b4bb

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.