0

Working on Week 2 Homework 1, I tried to define a new type DuBool. The following is the relevant portion of the code, with the more traditional version commented out immediately above each line that uses DuBool.

newtype DuBool = DuBool (Bool,Bool)
PlutusTx.unstableMakeIsData ''DuBool
--
--
{-# INLINABLE mkValidator #-}
-- This should validate if and only if the two Booleans in the redeemer are equal!
-- mkValidator :: () -> (Bool, Bool) -> ScriptContext -> Bool
mkValidator :: () -> DuBool -> ScriptContext -> Bool
-- mkValidator _ _ _ = True -- FIX ME!
-- mkValidator _ (a,b) _ = traceIfFalse "Bools no match" $ a == b
mkValidator _ (DuBool d) _
    | a==b = True
    | otherwise = traceIfFalse "Bools no match" $ False
  where (a,b) = d
--
--
data Typed
instance Scripts.ValidatorTypes Typed where
-- Implement the instance!
    type instance DatumType Typed = ()
--    type instance RedeemerType Typed = (Bool,Bool)
    type instance RedeemerType Typed = DuBool
--
--
typedValidator :: Scripts.TypedValidator Typed
-- typedValidator = undefined -- FIX ME!
typedValidator = Scripts.mkTypedValidator @Typed
    $$(PlutusTx.compile [|| mkValidator ||])
    $$(PlutusTx.compile [|| wrap ||])
  where
--    wrap = Scripts.wrapValidator @() @(Bool,Bool)
    wrap = Scripts.wrapValidator @() @DuBool

This does compile in the repl error-free, and does compile and run in the playground simulator, but failure occurs with evaluation when the grab validation step occurs in the simulator, with

, Slot 2: 00000000-0000-4000-8000-000000000000 {Wallet W7ce8}:
            Contract instance stopped with error: "WalletError (ValidationError (ScriptFailure (EvaluationError [\"PT1\"] \"CekEvaluationFailure\")))" ]

I went back and attempted to edit the "type GiftSchema =" section to use DuBool, as follows:

type GiftSchema =
            Endpoint "give" Integer
--      .\/ Endpoint "grab" (Bool, Bool)
        .\/ Endpoint "grab" DuBool

and then the grab definition...

-- grab :: forall w s e. AsContractError e => (Bool, Bool) -> Contract w s e ()
grab :: forall w s e. AsContractError e => DuBool -> Contract w s e ()

But now compilation in the repl fails (sorry that the color and alignment here does not match what I see in the repl).

Prelude Ledger.Scripts PlutusTx> :l src/Week02/Homework1c_jwb.hs
[1 of 1] Compiling Week02.Homework1 ( src/Week02/Homework1c_jwb.hs, /Users/jwb/plutus/plutus-pioneer-program/code/week02/dist-newstyle/build/x86_64-osx/ghc-8.10.4.20210212/plutus-pioneer-program-week02-0.1.0.0/build/Week02/Homework1.o )

src/Week02/Homework1c_jwb.hs:117:13: error: • No instance for (aeson-1.5.6.0:Data.Aeson.Types.FromJSON.FromJSON DuBool) arising from a use of ‘endpoint’ • In the expression: endpoint @"grab" grab In an equation for ‘grab'’: grab' = endpoint @"grab" grab In an equation for ‘endpoints’: endpoints = awaitPromise (give' select grab') >> endpoints where give' = endpoint @"give" give grab' = endpoint @"grab" grab | 117 | grab' = endpoint @"grab" grab | ^^^^^^^^^^^^^^^^^^^^^

src/Week02/Homework1c_jwb.hs:119:1: error: • No instance for (Schema.ToSchema DuBool) arising from a use of ‘Playground.Schema.endpointsToSchemas’ • In the expression: Playground.Schema.endpointsToSchemas @((./) (Endpoint "give" Integer) (Endpoint "grab" DuBool)) In an equation for ‘schemas’: schemas = Playground.Schema.endpointsToSchemas @((./) (Endpoint "give" Integer) (Endpoint "grab" DuBool)) | 119 | mkSchemaDefinitions ''GiftSchema | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Failed, no modules loaded. Prelude Ledger.Scripts PlutusTx>

It appears that the entire code as written (including what I am leaving out for brevity) can convert (Bool,Bool) to JSON, but not DuBool. I am wondering if there is a simple change, perhaps to the imports, {-# LANGUAGE ... #-}, instantiation, etc. that would incorporate this functionality?

Clearly this is not needed to "solve" homework 1 of week 2, but I do believe it is a valid programmatic approach that will be useful going forward. And I think I am very close. Thanks in advance!

=============================================================

Kurt Sys provided an extremely helpful partial answer. A few rounds of trial and error in the repl led me to this compiling and working-in-the-simulator solution. I've left a comment trail to help anyone else following along.

-- import           Playground.Contract  (printJson, printSchemas, ensureKnownCurrencies, stage)
import           Playground.Contract  (printJson, printSchemas, ensureKnownCurrencies, stage, Generic, FromJSON, ToJSON, ToSchema)
--
-- newtype DuBool = DuBool (Bool,Bool)
data DuBool = DuBool
  {
    b1 :: Bool
   ,b2 :: Bool
  } deriving (Generic, FromJSON, ToJSON, ToSchema)
PlutusTx.unstableMakeIsData ''DuBool
--
{-# INLINABLE mkValidator #-}
-- This should validate if and only if the two Booleans in the redeemer are equal!
-- mkValidator :: () -> (Bool, Bool) -> ScriptContext -> Bool
mkValidator :: () -> DuBool -> ScriptContext -> Bool
-- mkValidator _ _ _ = True -- FIX ME!
-- mkValidator _ (DuBool (a,b)) _ = traceIfFalse "Bools no match" $ a == b
-- mkValidator _ (a,b) _ = traceIfFalse "Bools no match" $ a == b
-- mkValidator _ (DuBool d) _
mkValidator _ (DuBool a b) _
    | a==b = True
    | otherwise = traceIfFalse "Bools no match" $ False
--  where (a,b) = d

Now I need to understand the difference between "data" and "newtype".

1
  • I believe this should be broken up into multiple questions given the guidelines in How to Ask and help center
    – gRebel
    Jan 23 at 0:41

1 Answer 1

2

For homework1, you don't need to define a new type. That's what's done in homework2 :). Now, for defining a new data type (which is what you want):

data DuBool = DuBool
  {
    b1 :: bool ,
    b2 :: bool
  }

adding some type classes (implementing functions of some type classes) to it:

data DuBool = DuBool
  {
    b1 :: bool ,
    b2 :: bool
  } deriving (Generic, FromJSON, ToJSON, ToSchema)

I think that should work fine.

4
  • VERY helpful. Thank you. See my edit to the original question. If you can somehow incorporate what I produced into your answer I will consider this "answered" but as it stands yours is incomplete. But still very helpful as it led me to the solution.
    – XiTouch
    Jan 22 at 20:51
  • I swear on MyRedeemer that I had not looked at homework 2 until now : D
    – XiTouch
    Jan 22 at 22:54
  • @XiTouch the answer should be accepted as it was sufficient to lead you to an answer and Kurt has spent the time and effort to understand your long question(s). If a better answer is provided in future, it can be voted up higher than the current one.
    – gRebel
    Jan 23 at 0:46
  • A little too brief, would benefit from a little more "why" explanation
    – gRebel
    Jan 23 at 0:48

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.