Plutus Pioneers第1次作业(第2周)类型化版本代码编译正常但Playground渲染失败求助
解决Plutus Playground中“Unsupported non record constructor”错误
你碰到的这个问题确实和DuoBoolRedeemer的ToSchema实例有关。Plutus Playground的JSON序列化机制对非记录风格的自定义类型支持有限,虽然代码能正常编译,但在解析用户输入时会因为无法识别非记录构造函数而报错。
核心原因
你定义的DuoBoolRedeemer是非记录形式的newtype:
newtype DuoBoolRedeemer = DuoBoolRedeemer (Bool, Bool) deriving (Generic, ToSchema)
Playground的ToSchema生成逻辑没法很好地处理这种构造方式,导致生成的JSON schema不符合预期,最终触发“Unsupported non record constructor”错误。
解决方案:改成记录类型
咱们只需要把DuoBoolRedeemer改成记录风格的定义,就能让ToSchema正常工作,具体步骤如下:
1. 修改Redeemer类型定义
把原来的非记录构造改成记录形式:
newtype DuoBoolRedeemer = DuoBoolRedeemer { getBools :: (Bool, Bool) } deriving (Generic, ToSchema)
这里用getBools作为记录字段名,用来访问内部的布尔对。
2. 调整验证器中的模式匹配
因为类型结构变了,需要更新mkValidator里的匹配逻辑(其实不改也能匹配,但用记录字段更清晰):
{-# INLINABLE mkValidator #-} mkValidator :: () -> DuoBoolRedeemer -> ValidatorCtx -> Bool mkValidator _ (DuoBoolRedeemer { getBools = (b1,b2) }) _ = traceIfFalse "wrong redeemer" $ b1 == b2
3. Playground输入适配
修改后,Playground会自动生成符合记录结构的输入表单,你不需要手动写JSON,只需要在表单里填写两个布尔值即可,对应的JSON格式会是:
{ "getBools": [true, false] }
完整修改后的核心代码
替换原代码中对应的部分即可:
newtype DuoBoolRedeemer = DuoBoolRedeemer { getBools :: (Bool, Bool) } deriving (Generic, ToSchema) PlutusTx.unstableMakeIsData ''DuoBoolRedeemer {-# INLINABLE mkValidator #-} mkValidator :: () -> DuoBoolRedeemer -> ValidatorCtx -> Bool mkValidator _ (DuoBoolRedeemer { getBools = (b1,b2) }) _ = traceIfFalse "wrong redeemer" $ b1 == b2
这样修改后,你的合约就能在Plutus Playground中正常渲染,执行grab操作也不会再报错了。
内容的提问来源于stack exchange,提问作者regisg
相关产品推荐
相关产品推荐

