diff --git a/doc/docusaurus/docs/using-plutus-tx/producing-a-blueprint.md b/doc/docusaurus/docs/using-plutus-tx/producing-a-blueprint.md index 5a540b3af6d..a8530680125 100644 --- a/doc/docusaurus/docs/using-plutus-tx/producing-a-blueprint.md +++ b/doc/docusaurus/docs/using-plutus-tx/producing-a-blueprint.md @@ -27,9 +27,11 @@ In order to demonstrate the usage of the `writeBlueprint` function, let's consid -## Importing required functionality +## Required pragmas and imports -First of all, we need to import required functionality: +First of all, we need to specify required pragmas and import necessary modules: + + @@ -57,21 +59,7 @@ data ContractBlueprint where > > The `referencedTypes` type parameter is used to track the types used in the contract making sure their schemas are included in the blueprint and that they are referenced in a type-safe way. > -> The blueprint will contain JSON schema definitions for all the types used in the contract, including the types **nested** within the top-level types ([MyParams], [MyDatum], [MyRedeemer]): -> -> - `Integer` - nested within [MyDatum] and [MyParams]. -> - `Bool` - nested within [MyParams]. -> -> This way, the [referencedTypes] type variable is inferred to be the following list: -> -> ``` haskell -> '[ MyParams -- top-level type -> , MyDatum -- top-level type -> , MyRedeemer -- top-level type -> , Integer -- nested type -> , Bool -- nested type -> ] -> ``` +> The blueprint will contain JSON schema definitions for all the types used in the contract, including the types **nested** within the top-level types (`MyParams`, `MyDatum`, `MyRedeemer`) recursively. We can construct a value of this type in the following way: @@ -109,17 +97,25 @@ It can be constructed using the `deriveDefinitions` function which automatically Since every type in the `referencedTypes` list is going to have its derived JSON-schema in the `contractDefinitions` registry under a certain unique `DefinitionId` key, we need to make sure that it has the following instances: -- An instance of the `GHC.Generics.Generic` type class: +- `instance HasBlueprintDefinition MyType` allows to add a `MyType` schema definition to the `contractDefinitions` registry by providing a `DefinitionId` value for `MyType`, e.g. `"my-type"`. - + The good news is that most of the time these instances either already exist (for types defined in the Plutus libraries) or can be derived automatically: -- An instance of the `HasBlueprintDefinition` type class. Most of the time it could be derived generically with the `anyclass` strategy; for example: + - +- `instance HasBlueprintSchema MyType` allows to derive a JSON schema for `MyType`. -- An instance of the `HasBlueprintSchema` type class. If your validator exposes standard supported types like `Integer` or `Bool`, you don't need to define this instance. If your validator uses custom types, then you should be deriving it using the `makeIsDataSchemaIndexed` Template Haskell function, which derives it alongside with the corresponding [ToBuiltinData]/[FromBuiltinData] instances; for example: + Types that are covered by a blueprint are exposed via the validator arguments and therefore must be convertible to/from `Data` representation. The conversion is done using instances of `ToData`, `FromData` and optionally `UnsafeFromData`. + + You probably already have these instances derived with Template Haskell functions `makeIsDataIndexed` or `unstableMakeIsData` which are located in the `PlutusTx.IsData.TH` module. You can add derivation of the + `HasBlueprintSchema` instance very easily: + - Replace usages of `PlutusTx.IsData.TH.makeIsDataIndexed` with `PlutusTx.Blueprint.TH.makeIsDataSchemaIndexed`. + - Replace usages of `PlutusTx.IsData.TH.unstableMakeIsData` with `PlutusTx.Blueprint.TH.unstableMakeIsDataSchema`. + + (This way `HasBlueprintSchema` instance is guaranteed to correspond to the `ToData` and `FromData` instances which are derived with it.) - + Here is an example: + ## Defining a validator blueprint @@ -275,9 +271,7 @@ myValidator = ## Resulting full blueprint example -Here is the full [CIP-0057](https://cips.cardano.org/cip/CIP-0057) blueprint produced by this example: - - +Here is the full [CIP-0057](https://cips.cardano.org/cip/CIP-0057) blueprint produced by this example: [plutus.json](/plutus.json) > :pushpin: **NOTE** > diff --git a/doc/docusaurus/static/code/Example/Cip57/Blueprint/Main.hs b/doc/docusaurus/static/code/Example/Cip57/Blueprint/Main.hs index c8531303d50..a28dcf13af4 100644 --- a/doc/docusaurus/static/code/Example/Cip57/Blueprint/Main.hs +++ b/doc/docusaurus/static/code/Example/Cip57/Blueprint/Main.hs @@ -1,4 +1,3 @@ --- BLOCK1 -- BEGIN pragmas {-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveAnyClass #-} @@ -35,7 +34,6 @@ module Main where --- BLOCK2 -- BEGIN imports import PlutusTx.Blueprint @@ -54,14 +52,12 @@ import PlutusTx.Blueprint.TH (makeIsDataSchemaIndexed) import Paths_docusaurus_examples (getDataFileName) import Prelude (FilePath, IO) --- BLOCK3 -- BEGIN MyParams annotations {-# ANN MkMyParams (SchemaTitle "Title for the MyParams definition") #-} {-# ANN MkMyParams (SchemaDescription "Description for the MyParams definition") #-} -- END MyParams annotations --- BLOCK4 -- BEGIN MyRedeemer annotations {-# ANN R0 (SchemaComment "Redeemer 0") #-} @@ -69,7 +65,6 @@ import Prelude (FilePath, IO) {-# ANN R2 (SchemaComment "Redeemer 2") #-} -- END MyRedeemer annotations --- BLOCK5 -- BEGIN interface types type MyDatum = Integer @@ -105,28 +100,21 @@ data MyParams = MkMyParams } -- END interface types --- BLOCK6 --- BEGIN makeIsDataSchemaIndexed MyParams +-- BEGIN makeIsDataSchemaIndexed $(makeIsDataSchemaIndexed ''MyParams [('MkMyParams, 0)]) $(makeIsDataSchemaIndexed ''MyRedeemer [('R0, 0), ('R1, 1), ('R2, 2)]) --- END makeIsDataSchemaIndexed MyParams --- BLOCK7 --- BEGIN generic instances +-- END makeIsDataSchemaIndexed +-- BEGIN derived instances deriving stock instance Generic MyParams -deriving stock instance Generic MyRedeemer - --- END generic instances --- BLOCK8 --- BEGIN HasBlueprintDefinition instances - deriving anyclass instance HasBlueprintDefinition MyParams + +deriving stock instance Generic MyRedeemer deriving anyclass instance HasBlueprintDefinition MyRedeemer --- END HasBlueprintDefinition instances --- BLOCK9 +-- END derived instances -- BEGIN validator typedValidator :: MyParams -> MyDatum -> MyRedeemer -> Bool @@ -151,7 +139,6 @@ untypedValidator params scriptContext = _ -> False -- END validator --- BLOCK10 -- BEGIN contract blueprint declaration myContractBlueprint :: ContractBlueprint @@ -164,7 +151,6 @@ myContractBlueprint = } -- END contract blueprint declaration --- BLOCK11 -- BEGIN preamble declaration myPreamble :: Preamble @@ -178,7 +164,6 @@ myPreamble = } -- END preamble declaration --- BLOCK12 -- BEGIN validator blueprint declaration myValidator = @@ -212,7 +197,6 @@ myValidator = } -- END validator blueprint declaration --- BLOCK13 -- BEGIN write blueprint to file -- >>> writeBlueprintToFile "plutus.json" diff --git a/doc/docusaurus/plutus.json b/doc/docusaurus/static/plutus.json similarity index 100% rename from doc/docusaurus/plutus.json rename to doc/docusaurus/static/plutus.json