<p>After digging into Plutus source, I think I've found why <code>tn == &quot;&quot;</code> crashes at runtime.</p>
<p>The problem might be that the instance of <code>TokenName IsString</code> doesn't use the <strong>INLINABLE</strong> pragma in the function <strong>fromString</strong>. Due to this, Plutus core crashes. (As a reminder, every function in order to compiles to Plutus core must have the <strong>INLINABLE</strong> pragma).</p>
<p>[source: <strong>Plutus.V1.Ledger.Value</strong>]</p>
<pre><code>instance IsString TokenName where
    fromString = fromText . Text.pack

</code></pre>
<p>On other hand, for example <code>traceIfFalse &quot;UTxO not consumed&quot; hasUTxO</code> is resolved properly because the function <strong>fromString</strong> in <code>IsString BuiltinString</code> uses the <strong>INLINABLE</strong> mechanism.</p>
<p>[source: <strong>PlutusTx.Builtins.Class</strong>]</p>
<pre><code>-- We can't put this in `Builtins.hs`, since that force `O0` deliberately, which prevents
-- the unfoldings from going in. So we just stick it here. Fiddly.
instance IsString BuiltinString where
    -- Try and make sure the dictionary selector goes away, it's simpler to match on
    -- the application of 'stringToBuiltinString'
    {-# INLINE fromString #-}
    -- See Note [noinline hack]
    fromString = Magic.noinline stringToBuiltinString

{-# INLINABLE stringToBuiltinString #-}
stringToBuiltinString :: Haskell.String -&gt; BuiltinString
-- To explain why the obfuscatedId is here
-- See Note [noinline hack]
stringToBuiltinString str = obfuscatedId (BuiltinString $ pack str)

</code></pre>
<p>Why don't Plutus team use <strong>INLINABLE</strong> mechanism in the function <strong>fromString</strong> for <strong>TokenName</strong>? I don't know, it might be a bug.</p>
<p><strong>EDIT 1</strong></p>
<p>I've raised an issue on <strong>Plutus</strong> repo.</p>
<p><a href="https://github.com/input-output-hk/plutus/issues/4404" rel="nofollow noreferrer">https://github.com/input-output-hk/plutus/issues/4404</a></p>
<p><strong>EDIT 2</strong></p>
<p>The issue is (see Plutus team's answer <a href="https://github.com/input-output-hk/plutus/issues/4404" rel="nofollow noreferrer">https://github.com/input-output-hk/plutus/issues/4404</a>)</p>
<blockquote>
<p>Unfortunately, due to the technical reasons plutus plugin doesn't
support OverloadedStrings with newtypes.</p>
</blockquote>
<p>Notice the same thing happens with <strong>PubKeyHash</strong> (it's a <strong>newtype</strong>)</p>

CC BY-SA 4.0
2022-02-10T20:39:29.307Z
2022-02-14T12:07:00.030Z
2022-02-14T12:07:00.030Z
kindofdev
<p>The problem is you don't have <strong>IsString</strong> in scope. If you add <code>import Data.String</code> should work. Here you can see it in the repl.</p>
<p><a href="https://i.sstatic.net/8VTJT.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/8VTJT.png" alt="enter image description here" /></a></p>
<p><strong>EDIT 1</strong></p>
<p>( First part of the answer referred to how to bring into scope <strong>IsString</strong> for <strong>TokenName</strong> in the repl. )</p>
<p>Additionally, I've tried to compile your code with the imports and pragmas that you can see in the following code snippet and the result of compiling has been successful. Probably, you have something wrong with imports.</p>
<pre><code>{-# LANGUAGE NoImplicitPrelude  #-}
{-# LANGUAGE OverloadedStrings  #-}

module Plutus.Contracts.Currency( mkPolicy ) where

import Ledger.Value ( flattenValue )
import Ledger.Contexts
    ( ScriptContext(scriptContextTxInfo),
      TxOutRef,
      TxInfo(txInfoInputs, txInfoMint),
      TxInInfo(txInInfoOutRef) )
import PlutusTx.Prelude
    ( Bool(False), Eq((==)), ($), (&amp;&amp;), any, traceIfFalse )

mkPolicy :: TxOutRef -&gt; () -&gt; ScriptContext -&gt; Bool
mkPolicy oref () ctx = traceIfFalse &quot;UTxO not consumed&quot;   hasUTxO           &amp;&amp;
                       traceIfFalse &quot;wrong amount minted&quot; checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    hasUTxO :: Bool
    hasUTxO = any (\i -&gt; txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -&gt; tn == &quot;&quot; &amp;&amp; amt == 1
        _               -&gt; False    
</code></pre>

CC BY-SA 4.0
2022-02-10T11:23:32.217Z
But in week01 [here](https://github.com/input-output-hk/plutus-pioneer-program/blob/79b0816b6f84f171c8f01073e5445033869c41b7/code/week01/src/Week01/EnglishAuction.hs#L363) there was no such import yet it still overloaded the string. Is there a special case for BuiltinByteString? I remember this because I didn't about the Overloaded String pragma (`{-# LANGUAGE OverloadedStrings          #-}`).
Roofi
CC BY-SA 4.0
2022-02-10T11:51:04.437Z
@Roofi, you are right, maybe for BuiltinByteString is different. Just curious, Does it work your code by importing Data.String?
kindofdev
CC BY-SA 4.0
2022-02-10T12:08:59.687Z
Sorry, it doesn't.
At line 30 I changed 

```import           Data.String( IsString(..) )```  
to  

```import           Data.String``` and then tried the first code block in my question.

Also in my previous comment, I meant "didn't know about" instead of "didn't about".
Roofi
CC BY-SA 4.0
2022-02-10T12:34:55.520Z
@Roofi, I've just edited my answer. Please, take a look.
kindofdev
CC BY-SA 4.0
2022-02-10T14:35:40.820Z
I think the code you provided may not raise that error as the error stems from the usage of `wrapMintingPolicy`. I inferred this by looking at the last line of the error block. I just edited my question to add a link to the complete code.
Roofi
CC BY-SA 4.0
2022-02-10T20:42:06.447Z
@Roofi, I've just added a new answer instead of  editing again my first question. (I think it will be more readable for the future)
kindofdev
CC BY-SA 4.0
2022-02-10T11:01:03.030Z
2022-02-10T12:42:21.817Z
2022-02-10T12:42:21.817Z
kindofdev
<p>This doesn't work</p>
<pre><code>mkPolicy oref () ctx = traceIfFalse &quot;UTxO not consumed&quot;   hasUTxO           &amp;&amp;
                       traceIfFalse &quot;wrong amount minted&quot; checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    hasUTxO :: Bool
    hasUTxO = any (\i -&gt; txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -&gt; tn == &quot;&quot; &amp;&amp; amt == 1
        _               -&gt; False
</code></pre>
<p>and throws</p>
<pre><code>GHC Core to PLC plugin: E042:Error: Unsupported feature: Type constructor: GHC.Prim.Char#
Context: Compiling type: GHC.Prim.Char#
Context: Compiling data constructor type: GHC.Types.C#
Context: Compiling type: GHC.Types.Char
Context: Compiling type: GHC.Base.String
Context: Compiling type: GHC.Base.String
                         -&gt; Data.ByteString.Internal.ByteString
Context: Compiling definition of: Plutus.V1.Ledger.Value.$fIsStringTokenName1
Context: Compiling expr: Plutus.V1.Ledger.Value.$fIsStringTokenName1
Context: Compiling expr: Plutus.V1.Ledger.Value.$fIsStringTokenName1
                           ((GHC.Types.[] @ GHC.Types.Char)
                            `cast` (Sym (Nth:2
                                             (((&lt;GHC.Base.String&gt;_R
                                                -&gt;_R Sym (PlutusTx.Builtins.Internal.N:BuiltinByteString[0]) ; Sym (Plutus.V1.Ledger.Value.N:TokenName[0])) ; Sym (Data.String.N:IsString[0]) &lt;Plutus.V1.Ledger.Value.TokenName&gt;_N) ; Data.String.N:IsString[0] &lt;Plutus.V1.Ledger.Value.TokenName&gt;_N))
                                    :: GHC.Types.Coercible GHC.Base.String GHC.Base.String))
... (a lot of lines skipped here)
Context: Compiling definition of: Week05.Homework2.mkPolicy
Context: Compiling expr: Week05.Homework2.mkPolicy
Context: Compiling expr: Week05.Homework2.mkPolicy oref'_axTu
Context: Compiling expr: PlutusTx.Base.$
                           @ (() -&gt; Plutus.V1.Ledger.Contexts.ScriptContext -&gt; GHC.Types.Bool)
                           @ Ledger.Typed.Scripts.MonetaryPolicies.WrappedMintingPolicyType
                           (Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                              @ () PlutusTx.IsData.Instances.$fUnsafeFromData())
                           (Week05.Homework2.mkPolicy oref'_axTu)
Context: Compiling expr: \ (oref'_axTu :: Plutus.V1.Ledger.Tx.TxOutRef) -&gt;
                           PlutusTx.Base.$
                             @ (() -&gt; Plutus.V1.Ledger.Contexts.ScriptContext -&gt; GHC.Types.Bool)
                             @ Ledger.Typed.Scripts.MonetaryPolicies.WrappedMintingPolicyType
                             (Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                                @ () PlutusTx.IsData.Instances.$fUnsafeFromData())
                             (Week05.Homework2.mkPolicy oref'_axTu)
Context: Compiling expr at &quot;plutus-pioneer-program-week05-0.1.0.0-inplace:Week05.Homework2:(55,8)-(55,85)&quot;
</code></pre>
<p>but this works</p>
<pre><code>mkPolicy oref () ctx = traceIfFalse &quot;UTxO not consumed&quot;   hasUTxO           &amp;&amp;
                       traceIfFalse &quot;wrong amount minted&quot; checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    emptyToken :: TokenName
    emptyToken = TokenName &quot;&quot;

    hasUTxO :: Bool
    hasUTxO = any (\i -&gt; txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -&gt; tn == emptyToken &amp;&amp; amt == 1
        _               -&gt; False
</code></pre>
<p>I assumed that <code>{-# LANGUAGE OverloadedStrings   #-}</code> would work as <code>TokenName</code> is just a <code>newtype</code> for <code>PlutusTx.Builtins.Internal.BuiltinByteString</code>. From the repl</p>
<pre><code>Prelude Week05.Homework2&gt; :t Plutus.V1.Ledger.Value.TokenName
Plutus.V1.Ledger.Value.TokenName
  :: PlutusTx.Builtins.Internal.BuiltinByteString
     -&gt; Plutus.V1.Ledger.Value.TokenName
Prelude Week05.Homework2&gt; :i Plutus.V1.Ledger.Value.TokenName
type Plutus.V1.Ledger.Value.TokenName :: *
newtype Plutus.V1.Ledger.Value.TokenName
  = Plutus.V1.Ledger.Value.TokenName {Plutus.V1.Ledger.Value.unTokenName :: PlutusTx.Builtins.Internal.BuiltinByteString}
    -- Defined in `Plutus.V1.Ledger.Value'
instance Eq Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'
instance Ord Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'
instance Show Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'
</code></pre>
<hr />
<h2>Edit #1</h2>
<p>On reading <a href="https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/overloaded_strings.html" rel="nofollow noreferrer">this doc</a> I realised that maybe <code>TokenName</code> is not an instance of <code>IsString</code>. I tried to implement it using:</p>
<pre><code>instance IsString TokenName where
        fromString = unTokenName
</code></pre>
<p>but I got this error</p>
<pre><code>src/Week05/Homework2.hs:32:10: error:
    Duplicate instance declarations:
      instance IsString TokenName
        -- Defined at src/Week05/Homework2.hs:32:10
      instance IsString TokenName -- Defined in `Plutus.V1.Ledger.Value'
   |
32 | instance IsString TokenName where
   |          ^^^^^^^^^^^^^^^^^^
</code></pre>
<hr />
<h2>Edit #2</h2>
<p>The complete Homework file is <a href="https://pastebin.com/8d822sWr" rel="nofollow noreferrer">here</a>.</p>

CC BY-SA 4.0
2022-02-10T10:22:52.830Z
In plutus docs I see that TokenName is an instance of IsString.  http://0.0.0.0:8002/haddock/plutus-ledger-api/html/Plutus-V1-Ledger-Value.html#t:TokenName
kindofdev
<plutus><plutus-pioneer-program><haskell><week05>
Empty TokenName Literal Overloading in Week05 Homework2
# Empty TokenName Literal Overloading in Week05 Homework2

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

This doesn't work
mkPolicy oref () ctx = traceIfFalse "UTxO not consumed"   hasUTxO           &&
                       traceIfFalse "wrong amount minted" checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    hasUTxO :: Bool
    hasUTxO = any (\i -> txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -> tn == "" && amt == 1
        _               -> False

and throws
GHC Core to PLC plugin: E042:Error: Unsupported feature: Type constructor: GHC.Prim.Char#
Context: Compiling type: GHC.Prim.Char#
Context: Compiling data constructor type: GHC.Types.C#
Context: Compiling type: GHC.Types.Char
Context: Compiling type: GHC.Base.String
Context: Compiling type: GHC.Base.String
                         -> Data.ByteString.Internal.ByteString
Context: Compiling definition of: Plutus.V1.Ledger.Value.$fIsStringTokenName1
Context: Compiling expr: Plutus.V1.Ledger.Value.$fIsStringTokenName1
Context: Compiling expr: Plutus.V1.Ledger.Value.$fIsStringTokenName1
                           ((GHC.Types.[] @ GHC.Types.Char)
                            `cast` (Sym (Nth:2
                                             (((_R
                                                ->_R Sym (PlutusTx.Builtins.Internal.N:BuiltinByteString[0]) ; Sym (Plutus.V1.Ledger.Value.N:TokenName[0])) ; Sym (Data.String.N:IsString[0]) _N) ; Data.String.N:IsString[0] _N))
                                    :: GHC.Types.Coercible GHC.Base.String GHC.Base.String))
... (a lot of lines skipped here)
Context: Compiling definition of: Week05.Homework2.mkPolicy
Context: Compiling expr: Week05.Homework2.mkPolicy
Context: Compiling expr: Week05.Homework2.mkPolicy oref'_axTu
Context: Compiling expr: PlutusTx.Base.$
                           @ (() -> Plutus.V1.Ledger.Contexts.ScriptContext -> GHC.Types.Bool)
                           @ Ledger.Typed.Scripts.MonetaryPolicies.WrappedMintingPolicyType
                           (Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                              @ () PlutusTx.IsData.Instances.$fUnsafeFromData())
                           (Week05.Homework2.mkPolicy oref'_axTu)
Context: Compiling expr: \ (oref'_axTu :: Plutus.V1.Ledger.Tx.TxOutRef) ->
                           PlutusTx.Base.$
                             @ (() -> Plutus.V1.Ledger.Contexts.ScriptContext -> GHC.Types.Bool)
                             @ Ledger.Typed.Scripts.MonetaryPolicies.WrappedMintingPolicyType
                             (Ledger.Typed.Scripts.MonetaryPolicies.wrapMintingPolicy
                                @ () PlutusTx.IsData.Instances.$fUnsafeFromData())
                             (Week05.Homework2.mkPolicy oref'_axTu)
Context: Compiling expr at "plutus-pioneer-program-week05-0.1.0.0-inplace:Week05.Homework2:(55,8)-(55,85)"

but this works
mkPolicy oref () ctx = traceIfFalse "UTxO not consumed"   hasUTxO           &&
                       traceIfFalse "wrong amount minted" checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    emptyToken :: TokenName
    emptyToken = TokenName ""

    hasUTxO :: Bool
    hasUTxO = any (\i -> txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -> tn == emptyToken && amt == 1
        _               -> False

I assumed that {-# LANGUAGE OverloadedStrings   #-} would work as TokenName is just a newtype for PlutusTx.Builtins.Internal.BuiltinByteString. From the repl
Prelude Week05.Homework2> :t Plutus.V1.Ledger.Value.TokenName
Plutus.V1.Ledger.Value.TokenName
  :: PlutusTx.Builtins.Internal.BuiltinByteString
     -> Plutus.V1.Ledger.Value.TokenName
Prelude Week05.Homework2> :i Plutus.V1.Ledger.Value.TokenName
type Plutus.V1.Ledger.Value.TokenName :: *
newtype Plutus.V1.Ledger.Value.TokenName
  = Plutus.V1.Ledger.Value.TokenName {Plutus.V1.Ledger.Value.unTokenName :: PlutusTx.Builtins.Internal.BuiltinByteString}
    -- Defined in `Plutus.V1.Ledger.Value'
instance Eq Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'
instance Ord Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'
instance Show Plutus.V1.Ledger.Value.TokenName
  -- Defined in `Plutus.V1.Ledger.Value'


Edit #1
On reading this doc I realised that maybe TokenName is not an instance of IsString. I tried to implement it using:
instance IsString TokenName where
        fromString = unTokenName

but I got this error
src/Week05/Homework2.hs:32:10: error:
    Duplicate instance declarations:
      instance IsString TokenName
        -- Defined at src/Week05/Homework2.hs:32:10
      instance IsString TokenName -- Defined in `Plutus.V1.Ledger.Value'
   |
32 | instance IsString TokenName where
   |          ^^^^^^^^^^^^^^^^^^


Edit #2
The complete Homework file is here.

**Tags:** plutus, plutus-pioneer-program, haskell, week05
> **Comments:**
> **username_1**: In plutus docs I see that TokenName is an instance of IsString.  http://0.0.0.0:8002/haddock/plutus-ledger-api/html/Plutus-V1-Ledger-Value.html#t:TokenName  

---

## 2 answers

### Answer by username_1 on 2022-02-10. Score: 3 | Accepted answer

After digging into Plutus source, I think I've found why tn == "" crashes at runtime.
The problem might be that the instance of TokenName IsString doesn't use the INLINABLE pragma in the function fromString. Due to this, Plutus core crashes. (As a reminder, every function in order to compiles to Plutus core must have the INLINABLE pragma).
[source: Plutus.V1.Ledger.Value]
instance IsString TokenName where
    fromString = fromText . Text.pack


On other hand, for example traceIfFalse "UTxO not consumed" hasUTxO is resolved properly because the function fromString in IsString BuiltinString uses the INLINABLE mechanism.
[source: PlutusTx.Builtins.Class]
-- We can't put this in `Builtins.hs`, since that force `O0` deliberately, which prevents
-- the unfoldings from going in. So we just stick it here. Fiddly.
instance IsString BuiltinString where
    -- Try and make sure the dictionary selector goes away, it's simpler to match on
    -- the application of 'stringToBuiltinString'
    {-# INLINE fromString #-}
    -- See Note [noinline hack]
    fromString = Magic.noinline stringToBuiltinString

{-# INLINABLE stringToBuiltinString #-}
stringToBuiltinString :: Haskell.String -> BuiltinString
-- To explain why the obfuscatedId is here
-- See Note [noinline hack]
stringToBuiltinString str = obfuscatedId (BuiltinString $ pack str)


Why don't Plutus team use INLINABLE mechanism in the function fromString for TokenName? I don't know, it might be a bug.
EDIT 1
I've raised an issue on Plutus repo.
https://github.com/input-output-hk/plutus/issues/4404
EDIT 2
The issue is (see Plutus team's answer https://github.com/input-output-hk/plutus/issues/4404)

Unfortunately, due to the technical reasons plutus plugin doesn't
support OverloadedStrings with newtypes.

Notice the same thing happens with PubKeyHash (it's a newtype)


---

### Answer by username_1 on 2022-02-10. Score: 0

The problem is you don't have IsString in scope. If you add import Data.String should work. Here you can see it in the repl.

EDIT 1
( First part of the answer referred to how to bring into scope IsString for TokenName in the repl. )
Additionally, I've tried to compile your code with the imports and pragmas that you can see in the following code snippet and the result of compiling has been successful. Probably, you have something wrong with imports.
{-# LANGUAGE NoImplicitPrelude  #-}
{-# LANGUAGE OverloadedStrings  #-}

module Plutus.Contracts.Currency( mkPolicy ) where

import Ledger.Value ( flattenValue )
import Ledger.Contexts
    ( ScriptContext(scriptContextTxInfo),
      TxOutRef,
      TxInfo(txInfoInputs, txInfoMint),
      TxInInfo(txInInfoOutRef) )
import PlutusTx.Prelude
    ( Bool(False), Eq((==)), ($), (&&), any, traceIfFalse )

mkPolicy :: TxOutRef -> () -> ScriptContext -> Bool
mkPolicy oref () ctx = traceIfFalse "UTxO not consumed"   hasUTxO           &&
                       traceIfFalse "wrong amount minted" checkMintedAmount
  where
    info :: TxInfo
    info = scriptContextTxInfo ctx

    hasUTxO :: Bool
    hasUTxO = any (\i -> txInInfoOutRef i == oref) $ txInfoInputs info

    checkMintedAmount :: Bool
    checkMintedAmount = case flattenValue (txInfoMint info) of
        [(_, tn, amt)]  -> tn == "" && amt == 1
        _               -> False

> **Comments:**
> **username_0**: But in week01 [here](https://github.com/input-output-hk/plutus-pioneer-program/blob/79b0816b6f84f171c8f01073e5445033869c41b7/code/week01/src/Week01/EnglishAuction.hs#L363) there was no such import yet it still overloaded the string. Is there a special case for BuiltinByteString? I remember this because I didn't about the Overloaded String pragma (`{-# LANGUAGE OverloadedStrings          #-}`).  
> **username_1**: @Roofi, you are right, maybe for BuiltinByteString is different. Just curious, Does it work your code by importing Data.String?  
> **username_0**: Sorry, it doesn't. At line 30 I changed   ```import           Data.String( IsString(..) )```   to    ```import           Data.String``` and then tried the first code block in my question.  Also in my previous comment, I meant "didn't know about" instead of "didn't about".  
> **username_1**: @Roofi, I've just edited my answer. Please, take a look.  
> **username_0**: I think the code you provided may not raise that error as the error stems from the usage of `wrapMintingPolicy`. I inferred this by looking at the last line of the error block. I just edited my question to add a link to the complete code.  
> **username_1**: @Roofi, I've just added a new answer instead of  editing again my first question. (I think it will be more readable for the future)  

---

