Skip to content

Commit

Permalink
feat(#98): update to Atlas version v0.6.2, updated contract & operati…
Browse files Browse the repository at this point in the history
…ons documentation
  • Loading branch information
sourabhxyz committed Dec 11, 2024
1 parent f8fe81f commit 7f4d5ad
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 42 deletions.
6 changes: 3 additions & 3 deletions src/module/home/components/DescriptionSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const DescriptionSection: FC = () => (
<FirstColumn container display="flex" flexDirection="row" maxWidth="1464px" padding="50px" overflow="hidden">
<TextWithIcon
title="Always up to date"
subtitle="Benefit from Cardano's latest innovations such as Reference Inputs, Inline Datum and Reference Scripts."
subtitle="Benefit from Cardano's latest innovations such as Reference Inputs, Governance actions and so on."
image={
<img className="blueLogo" alt="alwaysUpToDate" src={"/images/descriptionSection/AlwaysUpToDate.png"} />
}
Expand Down Expand Up @@ -80,7 +80,7 @@ const DescriptionSection: FC = () => (

<TextWithIcon
title="Unit tests"
subtitle="Write realistic tests true to onchain behavior with Atlas' test harness framework based on Plutus Simple Model."
subtitle="Write realistic tests true to onchain behavior utilizing Cardano ledger backend."
image={
<img
className="blueLogo"
Expand Down Expand Up @@ -234,7 +234,7 @@ const RightRow = styled(Grid)(({ theme }) => ({
},
}));

const IllustrationWrapper = styled(Grid)(({}) => ({
const IllustrationWrapper = styled(Grid)(({ }) => ({
margin: "0 auto",
}));

Expand Down
53 changes: 22 additions & 31 deletions src/pages/getting-started/operations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,10 @@ betRefValidator betRefParams =
$$(PlutusTx.compile [|| mkBetRefValidator||]) `PlutusTx.unsafeApplyCode` PlutusTx.liftCode plcVersion100 betRefParams
```

Note that since spending validator takes in a datum, redeemer and a script context and thus it's type signature, `PlutusTx.CompiledCode (PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> ())` takes three `PlutusTx.BuiltinData`. We encapsulate it with `GYValidator` inside framework.
Inside Atlas, Plutus scripts are represented as [`GYScript (v :: PlutusVersion)`](https://haddock.atlas-app.io/GeniusYield-Types-Script.html#t:GYScript).
The mentioned [`GeniusYield.Types.Script`](https://haddock.atlas-app.io/GeniusYield-Types-Script.html) module contains a lot of helper utilities such as `scriptFromPlutus` which takes in Plutus's `PlutusTx.CompiledCode a` type to give out `GYScript v` where type variable `v` is of _kind_ `PlutusVersion` which is defined in [`GeniusYield.Types.PlutusVersion`](https://haddock.atlas-app.io/GeniusYield-Types-PlutusVersion.html) module and is used to tag plutus ledger version of our validator script[^1].

Likewise minting policies and stake validators take in only redeemer and script context, thus having type `PlutusTx.CompiledCode (PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> ())` which is represented in Atlas as `GYMintingPolicy` and `GYStakeValidator` respectively.

`GYValidator`, `GYMintingPolicy` and `GYStakeValidator` are nothing but `newtype` wrapper around `GYScript` where `GYScript` holds information of raw serialized Plutus script, [version of Plutus ledger language](https://plutus.readthedocs.io/en/latest/explanations/language-versions.html#what-are-plutus-language-versions) and script's hash.

Thus encapsulating `GYScript` under say `GYValidator` gives us additional context regarding script's purpose.

<Callout type="info">
Checkout [`GeniusYield.Types.Script`](https://haddock.atlas-app.io/GeniusYield-Types-Script.html) module for definitions of these types and corresponding helper utilities.
</Callout>

The mentioned `GeniusYield.Types.Script` module contains a lot of helper utilities such as `validatorFromPlutus` which takes in Plutus's `PlutusTx.CompiledCode (PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> ())` type to give out `GYValidator`. Though there has been slight abuse in mentioning type here as what is actually given out is `GYValidator v` where type variable `v` is of _kind_ `PlutusVersion` which is defined in [`GeniusYield.Types.PlutusVersion`](https://haddock.atlas-app.io/GeniusYield-Types-PlutusVersion.html) module and is used to tag plutus ledger version of our validator script[^1].

If we look at the type signature of `validatorFromPlutus`, we see: `validatorFromPlutus :: forall v. SingPlutusVersionI v => PlutusTx.CompiledCode (PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> ()) -> GYValidator v` where for the time being we can ignore the description of the typeclass `SingPlutusVersionI`[^1] besides noting the fact that only types (currently `'PlutusV1` & `'PlutusV2`) of kind `PlutusVersion` have an instance for it. So here, our function `validatorFromPlutus` works for all type variable `v` which have an instance of `SingPlutusVersionI` but there is no way to learn what this `v` is based solely on the input `PlutusTx.CompiledCode (PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> PlutusTx.BuiltinData -> ())` and therefore, caller must specify it, either by providing type signature (of callee or caller due to type inference) or by using [visible type application](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/type_applications.html). Our first operation does make use of it but before looking at it, we need to understand about `GYTxQueryMonad`.
If we look at the type signature of `scriptFromPlutus`, we see: `scriptFromPlutus :: forall v a. SingPlutusVersionI v => PlutusTx.CompiledCode a -> GYScript v` where for the time being we can ignore the description of the typeclass `SingPlutusVersionI`[^1] besides noting the fact that only types (currently `'PlutusV1`, `'PlutusV2` & `'PlutusV3`) of kind `PlutusVersion` have an instance for it. So here, our function `scriptFromPlutus` works for all type variable `v` which have an instance of `SingPlutusVersionI` but there is no way to learn what this `v` is based solely on the input `PlutusTx.CompiledCode a` and therefore, caller must specify it, either by providing type signature (of callee or caller due to type inference) or by using [visible type application](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/type_applications.html). Our first operation does make use of it but before looking at it, we need to understand about `GYTxQueryMonad`.

### Interlude - `GYTxQueryMonad`

Expand All @@ -66,7 +55,7 @@ So, if we are working inside a monad which happens to also provide an instance f
In this operation, we only need to obtain network details with the help of this monad. Here is the code to obtain address (notice that we have provided multiple versions of the same code here):

<Callout type="info">
Type of [`scriptAddress`](https://haddock.atlas-app.io/GeniusYield-TxBuilder-Class.html#v:scriptAddress) used below is `scriptAddress :: forall (m :: * -> *) (v :: PlutusVersion). GYTxQueryMonad m => GYValidator v -> m GYAddress`. Thus with respect to type application, the first parameter is for monad and second one is `PlutusVersion` kinded.
Type of [`scriptAddress`](https://haddock.atlas-app.io/GeniusYield-TxBuilder-Class.html#v:scriptAddress) used below is `scriptAddress :: forall (m :: * -> *) (v :: PlutusVersion). GYTxQueryMonad m => GYScript v -> m GYAddress`. Thus with respect to type application, the first parameter is for monad and second one is `PlutusVersion` kinded.

Internally this function queries for network details.
</Callout>
Expand All @@ -77,8 +66,8 @@ In this operation, we only need to obtain network details with the help of this
-- A. Type is given by `scriptAddress`.

-- | Validator in question, obtained after giving required parameters.
betRefValidator' :: SingPlutusVersionI v => BetRefParams -> GYValidator v
betRefValidator' brp = validatorFromPlutus $ betRefValidator brp
betRefValidator' :: SingPlutusVersionI v => BetRefParams -> GYScript v
betRefValidator' brp = scriptFromPlutus $ betRefValidator brp

-- | Address of the validator, given params.
betRefAddress :: (HasCallStack, GYTxQueryMonad m) => BetRefParams -> m GYAddress
Expand All @@ -87,10 +76,10 @@ In this operation, we only need to obtain network details with the help of this
</Tab>
<Tab>
```haskell
-- B. Type is given by `validatorFromPlutus` using type application.
-- B. Type is given by `scriptFromPlutus` using type application.

-- | Validator in question, obtained after giving required parameters.
betRefValidator' brp = validatorFromPlutus @'PlutusV2 $ betRefValidator brp
betRefValidator' brp = scriptFromPlutus @'PlutusV2 $ betRefValidator brp

-- | Address of the validator, given params.
betRefAddress :: (HasCallStack, GYTxQueryMonad m) => BetRefParams -> m GYAddress
Expand All @@ -102,8 +91,8 @@ In this operation, we only need to obtain network details with the help of this
-- C. Type is specified using signature.

-- | Validator in question, obtained after giving required parameters.
betRefValidator' :: BetRefParams -> GYValidator 'PlutusV2
betRefValidator' brp = validatorFromPlutus $ betRefValidator brp
betRefValidator' :: BetRefParams -> GYScript 'PlutusV2
betRefValidator' brp = scriptFromPlutus $ betRefValidator brp

-- | Address of the validator, given params.
betRefAddress :: (HasCallStack, GYTxQueryMonad m) => BetRefParams -> m GYAddress
Expand Down Expand Up @@ -190,7 +179,7 @@ Note that we have mentioned the value as empty for this UTxO and this is one of

<details>
<summary> Toggle Answer </summary>
Given the output address `addr :: GYAddress{:haskell}` and the Plutus V2 validator `script :: GYValidator 'PlutusV2{:haskell}`, we can write `mustHaveOutput $ GYTxOut addr mempty (Just (datumFromPlutusData (), GYTxOutDontUseInlineDatum)) (Just $ validatorToScript script){:haskell}`
Given the output address `addr :: GYAddress{:haskell}` and the Plutus V2 validator `script :: GYScript 'PlutusV2{:haskell}`, we can write `mustHaveOutput $ GYTxOut addr mempty (Just (datumFromPlutusData (), GYTxOutDontUseInlineDatum)) (Just script){:haskell}`
</details>

## Operation _3_: Placing a bet
Expand Down Expand Up @@ -239,22 +228,24 @@ Thus, we have its definition as:

```haskell
-- | Utility function to consume script UTxO.
input :: BetRefParams -> GYTxOutRef -> GYTxOutRef -> BetRefDatum -> BetRefAction -> GYTxSkeleton 'PlutusV2
input :: BetRefParams -> GYTxOutRef -> GYTxOutRef -> BetRefDatum -> BetRefAction -> GYTxSkeleton 'PlutusV3
input brp refScript inputRef dat red =
mustHaveInput GYTxIn
{ gyTxInTxOutRef = inputRef
, gyTxInWitness = GYTxInWitnessScript
(GYInReference refScript $ validatorToScript $ betRefValidator' brp)
(datumFromPlutusData dat)
(redeemerFromPlutusData red)
}
mustHaveInput
GYTxIn
{ gyTxInTxOutRef = inputRef
, gyTxInWitness =
GYTxInWitnessScript
(GYInReference refScript $ betRefValidator' brp)
(datumFromPlutusData dat)
(redeemerFromPlutusData red)
}
```

<Callout type="info">
In case we didn't want to use reference script, we would write `gyTxInWitness` as:
```haskell
gyTxInWitness = GYTxInWitnessScript
(GYInScript (validatorToScript $ betRefValidator' brp))
(GYInScript (betRefValidator' brp))
(datumFromPlutusData dat)
(redeemerFromPlutusData red)
```
Expand Down
14 changes: 11 additions & 3 deletions src/pages/getting-started/smart-contract-intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,18 @@ Let's now start by writing a smart contract that we will use to convey framework

<Callout>

Here we'll be writing our smart contract in Haskell but do note that we are not limited to it. You for instance could write your smart contract in any language of your choice and read the compiled CBOR using `scriptFromCBOR` function defined [here](https://github.com/geniusyield/atlas/tree/main/src/GeniusYield/Types/Script.hs) ([Operations over Contract](./operations.mdx) chapter explains about types such as `GYScript`, `PlutusVersion` which are used in this function). Similarly, there is `readScript` defined in the [same](https://github.com/geniusyield/atlas/tree/main/src/GeniusYield/Types/Script.hs) file to read from the compiled [text envelope](https://cardano-api.cardano.intersectmbo.org/cardano-api/Cardano-Api-SerialiseTextEnvelope.html#t:TextEnvelope) file.
Here we'll be writing our smart contract in Plutus-tx (aka Plinth) but do note that we are not limited to it. If you are using [Aiken](https://aiken-lang.org/), check out our [Blueprint](./../additional-features/blueprint) section to see how easily Aiken validators can be plugged into Atlas, also supporting creation of high level Haskell types corresponding to blueprint schema.

And in general, one can read the compiled validator's CBOR using `scriptFromCBOR` function defined [here](https://github.com/geniusyield/atlas/tree/main/src/GeniusYield/Types/Script.hs) ([Operations over Contract](./operations.mdx) chapter explains about types such as `GYScript`, `PlutusVersion` which are used in this function). Similarly, there is `readScript` defined in the [same](https://github.com/geniusyield/atlas/tree/main/src/GeniusYield/Types/Script.hs) file to read from the compiled [text envelope](https://cardano-api.cardano.intersectmbo.org/cardano-api/Cardano-Api-SerialiseTextEnvelope.html#t:TextEnvelope) file.

Note that if your validator is written in Plutarch, we recommend [Ply](https://github.com/geniusyield/ply) to read Plutarch compiled scripts. In particular, check out [this](https://github.com/geniusyield/dex-contracts-api/blob/main/geniusyield-dex-api/src/GeniusYield/Scripts/Common.hs) example where GeniusYield reads it's plutarch validators into Atlas.

</Callout>

<Callout type="info">
Besides Plutus scripts, Atlas also supports Simple scripts. Check out [Simple Scripts](../additional-features/simple-scripts) section to learn more!
</Callout>

## Contract Description

A setting here is that we have a sport match happening and a group of friends want to bet on the number of goals scored by their favorite team in it.
Expand All @@ -26,7 +34,7 @@ The smart contract code is available [here](https://github.com/geniusyield/atlas

<Callout type="info">

Since the underlying version of `plutus` library we are using defaults to version 1.1.0 of plutus core, we need to explicitly set [`target-version`](https://plutus.readthedocs.io/en/latest/reference/writing-scripts/compiler-options.html) to 1.0.0, and that is why there is `ghc-options: -fplugin-opt PlutusTx.Plugin:target-version=1.0.0` in [our cabal file](https://github.com/geniusyield/atlas-examples/blob/main/bet-ref/betref.cabal).
Since the underlying version of `plutus` library we are using defaults to version 1.1.0 of plutus core, we need to explicitly set [`target-version`](https://plutus.readthedocs.io/en/latest/reference/writing-scripts/compiler-options.html) to 1.0.0 (as this example uses Plutus V2 ledger version, but Atlas also supports Plutus V3), and that is why there is `ghc-options: -fplugin-opt PlutusTx.Plugin:target-version=1.0.0` in [our cabal file](https://github.com/geniusyield/atlas-examples/blob/main/bet-ref/betref.cabal).

</Callout>

Expand All @@ -47,7 +55,7 @@ data BetRefParams = BetRefParams
, brpBetReveal :: POSIXTime -- ^ Time at which Oracle will reveal the correct match result.
, brpBetStep :: Value -- ^ Each newly placed bet must be more than previous bet by `brpBetStep` amount.
}
PlutusTx.makeLift ''BetRefParams
PlutusTx.unstableMakeIsData ''BetRefParams
```

### Reference Input Datum
Expand Down
10 changes: 5 additions & 5 deletions src/pages/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@ Atlas is an all-in-one, Haskell-native application backend for writing off-chain
Use an intuitive API to abstract away the complexity around building transactions, balancing UTxOs, and interfacing with Plutus smart contracts.

### Leverage first-class Haskell
Avoid code duplication between on-chain and off-chain code, interoperate with advanced functionalities offered by IOG's Cardano/Plutus libraries, and easily convert between Atlas and [Cardano API](https://github.com/IntersectMBO/cardano-api)/[Plutus Ledger API](https://github.com/IntersectMBO/plutus/tree/master/plutus-ledger-api) types.
Write type-safe abstractions, harnessing the power & security of Haskell.

### Utilize modular data providers
Query ledger state information from remote provider such as [Maestro](https://www.gomaestro.org/dapp-platform), [Blockfrost](https://blockfrost.io/) or from your own node with the help of [Kupo](https://cardanosolutions.github.io/kupo/). You can also build and contribute your own data provider!

### Test extensively
Use Atlas' test harness to write realistic [tests](./getting-started/testing)
that can be run against an emulator or a private Cardano network.
Use Atlas' test harness to write realistic [test](./getting-started/testing) harness,
which can be run against either an emulator or a private Cardano network. Atlas offers a unified testing approach and the same test code can seamlessly execute on both an emulated mock ledger and an actual private Cardano test network.

### Stay up to date
Benefit from Cardano's latest innovations such as **Reference Inputs**, **Inline Datums** and **Reference Scripts**. Conway we are looking at you 👀.
Benefit from Cardano's latest innovations such as **Reference Inputs**, **Inline Datums**, **Reference Scripts**, governance actions and so on.

## Where to next?
Work through an end-to-end example here: [Getting Started](./getting-started).

<Callout>

This guide tracks the latest commit of Atlas. We bring changes into Atlas, only when corresponding updates have been made into the documentation as well.
This guide tracks the Atlas version [0.6.2](https://github.com/geniusyield/atlas/releases/tag/v0.6.2).

</Callout>

0 comments on commit 7f4d5ad

Please sign in to comment.