OpShin / opshin-pioneer-program

This repository hosts an opshin/python implementation of the lectures of the Plutus Pioneers Program, a training course for Cardano Smart Contract Engineers.
MIT License
43 stars 11 forks source link

Bug: Need to assert in last line #7

Closed nielstron closed 1 year ago

nielstron commented 1 year ago

Eopsin has a nuanced difference to PlutusTx: it gives you full control over what your contract returns. Unfortunately (and maybe not very intuitively) the node interprets anything that is returned as "validation". To actually fail, you must throw an error.

Hence if you want to control the contract by setting booleans, the last line should be an assert. In this case it doesn't make a difference... but I usually just type the validator as returning None and ommiting the return statement .

https://github.com/juliusfrost/eopsin-pioneer-program/blob/3d57101ef7b326951b703290384e8d485d256ece/src/week03/lecture/parameterized_vesting.py#L22

juliusfrost commented 1 year ago

Thanks for that insight! I was trying to imitate the traceIfFalse "message" Bool behavior in PlutusTx (below). What do you think would be the closest implementation to that? It would be nice if it could also return a bool for testing purposes, but I'm not sure how to balance that with throwing errors.

https://github.com/input-output-hk/plutus-pioneer-program/blob/f26d92cd84ff1e43948566ab1ff1d32699485031/code/Week03/lecture/Vesting.hs#L34-L36

nielstron commented 1 year ago

You can just write a small function

def trace_if_false(x: bool, s: str) -> x:
   if not x:
     print(s)
   return x

But the existence of trace if false is more reminiscent of the lack of imperative constructs in plutus. The pythonic way would be

  ...
  x: bool = foo()
  if not x:
    print(s)
  ...

or even

  ...
  x: bool = foo()
  assert x, s
  ...
nielstron commented 1 year ago

So essentially the way you did it. The fact that plutus always wants to return something (usually a bool) is again just a symptom of functional programming because they don't know/use precedures.

Plutus core validators are actually procedures though, their return value is discarded by the node, it only fails by throwing an error. PlutusTx wraps validator code in assert(validator) to make you feel like returning a bool makes a difference.

juliusfrost commented 1 year ago

That makes sense. Then I think I'll just keep all validator scripts to return None type. I've updated the code to reflect this. Thanks!