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.

Your Answer

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

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