1

I want to check on-chain if a given TokenName is of a specific pattern, for example:

  • aaa1
  • aaa2
  • aaa3

I have something like this, but it throws an interpreter exception:

checkValidMint :: TokenName -> Integer -> Bool
checkValidMint tn count  = tn == (TokenName $ "aaa" <> (integerToByteString count))

integerToByteString :: Integer -> BuiltinByteString
integerToByteString n
    | n == 0 = "0"
    | n == 1 = "1"
    | n == 2 = "2"
    | n == 3 = "3"
    | n == 4 = "4"
    | n == 5 = "5"
    | n == 6 = "6"
    | n == 7 = "7"
    | n == 8 = "8"
    | n == 9 = "9"
    | otherwise = integerToByteString (n `P.divide` 10) P.<> integerToByteString (n `P.modulo` 10)

Update 2 Also tried:

integerToByteString n
            | (Builtins.equalsInteger n 0) = "0"
            | (Builtins.equalsInteger n 1) = "1"
            | (Builtins.equalsInteger n 2) = "2"
            | (Builtins.equalsInteger n 3) = "3"
            | (Builtins.equalsInteger n 4) = "4"
            | (Builtins.equalsInteger n 5) = "5"
            | (Builtins.equalsInteger n 6) = "6"
            | (Builtins.equalsInteger n 7) = "7"
            | (Builtins.equalsInteger n 8) = "8"
            | (Builtins.equalsInteger n 9) = "9"
            | otherwise = integerToByteString (n `PlutusTx.Prelude.divide` 10) PP.<> integerToByteString (n `PlutusTx.Prelude.modulo` 10)

I keep getting an interpreter error:

GHC Core to PLC plugin: E042:Error: Unsupported feature: Use of Haskell Integer equality, possibly via the Haskell Eq typeclass Context: Compiling expr: GHC.Integer.Type.eqInteger# Context: Compiling expr: GHC.Integer.Type.eqInteger# x Context: Compiling expr: GHC.Integer.Type.eqInteger# x y Context: Compiling expr: case GHC.Integer.Type.eqInteger# x y of wild [Occ=Once] { __DEFAULT -> GHC.Prim.tagToEnum# @ GHC.Types.Bool wild } Context: Compiling expr: \ (y [Occ=Once] :: GHC.Integer.Type.Integer) -> case GHC.Integer.Type.eqInteger# x y of ...

3 Answers 3

1

This is how I've done the integer conversion in the past. Might need some minor updating:

{-# INLINEABLE intToString #-}
intToString :: Integer -> Builtins.String
intToString i = Prelude.foldr Builtins.appendString "" strings
  where
    ints = intToInts i
    strings = map (Builtins.charToString . intToChar) ints


{-# INLINEABLE intToChar #-}
intToChar :: Integer -> Haskell.Char
intToChar i
  | (Builtins.equalsInteger i 0) = '0'
  | (Builtins.equalsInteger i 1) = '1'
  | (Builtins.equalsInteger i 2) = '2'
  | (Builtins.equalsInteger i 3) = '3'
  | (Builtins.equalsInteger i 4) = '4'
  | (Builtins.equalsInteger i 5) = '5'
  | (Builtins.equalsInteger i 6) = '6'
  | (Builtins.equalsInteger i 7) = '7'
  | (Builtins.equalsInteger i 8) = '8'
  | (Builtins.equalsInteger i 9) = '9'
  | otherwise = '0' -- Fix this

Then instead of checkValidMint, you can just check that the expected amount of your new token is included in the output value in the policy ctx, like here in the Uniswap example.

2
  • Unfortunately, I cannot get this code to run. It seems like charToString is not part of the API anymore. And String has been replaced with BuiltinString. I am not sure how to make use of this code. Any other suggestions?
    – Will
    Commented May 30, 2022 at 18:16
  • Make sure you are using INLINEABLE on your code, try using equalsInteger instead of ==, and see where that lands you. You might need to dig and see what methods on char there are instead of charToString. I'd need to do some digging to say for sure what all has changed. Commented May 30, 2022 at 22:25
0

You may want to checkout the utils package I used for the open source cardano lottery located here: https://github.com/lley154/cardano-lottery/blob/main/src/Utils.hs. This code has been tested and works on the testnet.

Also, there was a similar post that may help if you having issues and need to be aware of the encoding of builtinbytestrings in plutus. How to get a base 16 hex BuiltinString from getTxId

0

After testing out many different variations, changing imports to make sure the correct functions of Prelude and PlutusTx.Prelude are used, I've found the problem:

  1. I made sure this pragma is present: {-# LANGUAGE NoImplicitPrelude #-}
  2. I imported both Preludes in a qualified way:
import           PlutusTx.Prelude as PP
import           Prelude          as P

which let's me clearly distinguish what operators to use when it comes to Integer comparisons. I subsequently replaces all == with either PP.== for on-chain and P.== for off-chain code.

  1. Lastly, I found one more error where I used Integer pattern matching on-chain like so:
checkMint :: String -> Integer -> Bool
checkMint s (1)  = ...
checkMint s (-1) = ...
checkMint _ _    = False

The pattern matching seems to default to P.== for this on-chain code, so I replace it with an if-then-else and it worked fine.

checkMint s amt = 
    if amt PP.== 1 then ... 
    else if amt PP.== -1 then ... 
    else ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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