0

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

1 Answer 1

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.

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