Additional Features
Blueprint

Blueprint

Plutus Contract Blueprint, as introduced by CIP-57 (opens in a new tab) is an effective way of communicating desired structure of validator's associated types such as datum and redeemer to your off-chain code.

With Atlas, you can easily have these types generated for you based on provided schema, along with useful helper utilities!

💡

If your validator is parameterised, parameters must be "data" encoded (instead of scott or sums-of-products encoding1) as blueprint notation requires it (data) to be primary binary interface. This is not an issue for datums & redeemers as they are required to be data encoded anyway.

Validators written by tools such as Aiken use data encoding for validator parameters.

Here (opens in a new tab) we have a parameterised Aiken validator. Mainly, it checks that sum of integers and length of bytestrings given in parameters, datum & redeemer sum up to a specific value.

For this validator, we have a simple off-chain code here (opens in a new tab), have a look at it and we provide some description for it below.

We first use Template Haskell to splice declarations from makeBPTypes (opens in a new tab) and uponBPTypes (opens in a new tab). makeBPTypes introduces types from definitions given in blueprint file and uponBPTypes creates data related instances such as ToData (opens in a new tab), FromData (opens in a new tab) for these types2.

It is useful to see generated Template Haskell code to know for type and provided utility names which can be done via -ddump-splices GHC flag. You may combine this with -ddump-to-file to save the output to a file. If you are using cabal, see this (opens in a new tab) answer on where one can find dumped splice files.

Now we can apply parameters (whose types have been generated by Atlas) to our validator with provided applyParamsToBPValidator_baz_baz_spend function and obtain GYScript from it using scriptFromBPSerialisedScript function. Likewise we have types generated for our datum & redeemer, sweet!

Rest of the off-chain code just tries to interact with the validator by creating a UTxO towards it and then later consuming from it.

💡

To interact with blueprint file, you'll usually just need to import GeniusYield.Types.Blueprint.TH (opens in a new tab) module (which is exposed by GeniusYield.Types module), however if you want to inspect the parsed blueprint file, you can use readBlueprint (opens in a new tab).

Footnotes

  1. See CIP-85 (opens in a new tab) to understand about different encodings used. ↩

  2. We could achieve both in single splice, however, since we are using utilities from PlutusTx to derive ToData etc. instances, they require type to be in scope first. ↩