<p>I do not think you do anything wrong. I expected to &quot;resolve&quot; this issue by either inlining <code>whitelist</code>, manually marking it <code>INLINEABLE</code> or enabling <code>-fexpose-all-unfoldings</code>. But none of the above worked. I then took a close look at the PLC output and saw explicit references to</p>
<pre><code>Whitelist.$s$fFoldable[]_$cfoldMap
</code></pre>
<p>And thought that this is odd, since it seems like it is trying to reference a <code>foldMap</code> implementation from the <code>Whitelist</code> module itself, which of course does not exist. So I went ahead and added an import:</p>
<pre><code>import Data.Foldable (foldMap)
</code></pre>
<p>GHC marks this import as redundant, but the PLC plugin does not complain anymore... and it seems to work. I did not test it rigorously though, so take this with a grain of salt.</p>

CC BY-SA 4.0
2022-11-15T17:28:31.840Z
2022-11-15T17:28:31.840Z
ndzik
<p>I want to write a PlutusTx validator which just checks if a transaction was signed by one of the whitelisted public keys.</p>
<p>This would be a first, naiive implementation:</p>
<pre><code>-- | The whitelist used by 'signedByOneOfWhitelist'.
whitelist :: [PubKeyHash]
whitelist = []

-- | Check whether a transaction was signed by one of the 'whitelist' keys.
{-# INLINEABLE signedByOneOfWhitelist #-}
signedByOneOfWhitelist :: ScriptContext -&gt; Bool
signedByOneOfWhitelist context =
  any (`elem` whitelist) txInfoSignatories
 where
  TxInfo{txInfoSignatories} = txInfo

  ScriptContext{scriptContextTxInfo = txInfo} = context
</code></pre>
<p>This works fine if I put this next to my <code>validator</code> / in the same module as `$$compile.</p>
<p><strong>However</strong>, if I want to make this re-usable and put it into a dedicated module, say <code>Whitelist</code> with the right imports <code>import Whitelist (signedByOneOfWhitelist)</code> I get the following error by the plutus-tx compiler:</p>
<pre><code>GHC Core to PLC plugin: E043:Error: Reference to a name which is not a local, a builtin, or an external INLINABLE function: Variable Whitelist.$s$fFoldable[]_$cfoldMap
            No unfolding
</code></pre>
<p>Full gist for context: <a href="https://gist.github.com/ch1bo/a248087241a0a1690fba41936da45bc9" rel="nofollow noreferrer">https://gist.github.com/ch1bo/a248087241a0a1690fba41936da45bc9</a></p>
<p><strong>What am I doing wrong?</strong></p>
<hr />
<p>A workaround is to not use <code>Foldable</code> by instantiating it and an explicit fold:</p>
<pre><code>{-# INLINEABLE signedByOneOfWhitelist #-}
signedByOneOfWhitelist :: ScriptContext -&gt; Bool
signedByOneOfWhitelist context =
  myAny (`myElem` whitelist) txInfoSignatories
 where
  myAny :: (a -&gt; Bool) -&gt; [a] -&gt; Bool
  myAny fn = \case
    [] -&gt; False
    (x : xs)
      | fn x -&gt; True
      | otherwise -&gt; myAny fn xs

  myElem :: Eq a =&gt; a -&gt; [a] -&gt; Bool
  myElem x = myAny (x ==)

  TxInfo{txInfoSignatories} = txInfo

  ScriptContext{scriptContextTxInfo = txInfo} = context
</code></pre>

<plutus><plutustx>
Can't use PlutusTx.Foldable from other module
# Can't use PlutusTx.Foldable from other module

(Asked by: username_0 on 2022-11-13)

I want to write a PlutusTx validator which just checks if a transaction was signed by one of the whitelisted public keys.
This would be a first, naiive implementation:
-- | The whitelist used by 'signedByOneOfWhitelist'.
whitelist :: [PubKeyHash]
whitelist = []

-- | Check whether a transaction was signed by one of the 'whitelist' keys.
{-# INLINEABLE signedByOneOfWhitelist #-}
signedByOneOfWhitelist :: ScriptContext -> Bool
signedByOneOfWhitelist context =
  any (`elem` whitelist) txInfoSignatories
 where
  TxInfo{txInfoSignatories} = txInfo

  ScriptContext{scriptContextTxInfo = txInfo} = context

This works fine if I put this next to my validator / in the same module as `$$compile.
However, if I want to make this re-usable and put it into a dedicated module, say Whitelist with the right imports import Whitelist (signedByOneOfWhitelist) I get the following error by the plutus-tx compiler:
GHC Core to PLC plugin: E043:Error: Reference to a name which is not a local, a builtin, or an external INLINABLE function: Variable Whitelist.$s$fFoldable[]_$cfoldMap
            No unfolding

Full gist for context: https://gist.github.com/ch1bo/a248087241a0a1690fba41936da45bc9
What am I doing wrong?

A workaround is to not use Foldable by instantiating it and an explicit fold:
{-# INLINEABLE signedByOneOfWhitelist #-}
signedByOneOfWhitelist :: ScriptContext -> Bool
signedByOneOfWhitelist context =
  myAny (`myElem` whitelist) txInfoSignatories
 where
  myAny :: (a -> Bool) -> [a] -> Bool
  myAny fn = \case
    [] -> False
    (x : xs)
      | fn x -> True
      | otherwise -> myAny fn xs

  myElem :: Eq a => a -> [a] -> Bool
  myElem x = myAny (x ==)

  TxInfo{txInfoSignatories} = txInfo

  ScriptContext{scriptContextTxInfo = txInfo} = context

**Tags:** plutus, plutustx

---

## 1 answers

### Answer by username_1 on 2022-11-15. Score: 0

I do not think you do anything wrong. I expected to "resolve" this issue by either inlining whitelist, manually marking it INLINEABLE or enabling -fexpose-all-unfoldings. But none of the above worked. I then took a close look at the PLC output and saw explicit references to
Whitelist.$s$fFoldable[]_$cfoldMap

And thought that this is odd, since it seems like it is trying to reference a foldMap implementation from the Whitelist module itself, which of course does not exist. So I went ahead and added an import:
import Data.Foldable (foldMap)

GHC marks this import as redundant, but the PLC plugin does not complain anymore... and it seems to work. I did not test it rigorously though, so take this with a grain of salt.


---

