Cabal setup
Let us organise our code for this course project. We will be writing a number of Plutus validators and our project can have the same structure as plutus-scripts.
The .cabal file
We start off by creating a new directory and initialising a cabal project.
mkdir hpm-validators && cd hpm-validators
cabal initThis will create a default cabal project structure for us that looks like this:
├── app
│   └── Main.hs
├── CHANGELOG.md
└── hpm-validators.cabalWe will place all our source code in the src/ directory so let's rename the app directory to src. Inspecting the hpm-validators.cabal file shows that the project was initialised as an executable, but we will be building a library of validators so we can change that to a library and specify the hs-source-dirs to src. The rest of the file we can simply copy from the plutus-scripts.cabal template (most notably the build-depends section). Our complete hpm-validators.cabal file looks like this:
cabal-version:      2.4
name:               hpm-validators
version:            0.1.0.0
-- A short (one-line) description of the package.
-- synopsis:
-- A longer description of the package.
-- description:
-- A URL where users can report bugs.
-- bug-reports:
-- The license under which the package is released.
-- license:
-- The package author(s).
-- author:
-- An email address to which users can send suggestions, bug reports, and patches.
-- maintainer:
-- A copyright notice.
-- copyright:
-- category:
extra-source-files: CHANGELOG.md
library
    hs-source-dirs:      src
    exposed-modules:     SimplestSuccess
    build-depends:       aeson
                        , base ^>=4.14.1.0
                        , bytestring
                        , containers
                        , cardano-api
                        , data-default
                        , freer-extras
                        , plutus-contract
                        , plutus-ledger
                        , plutus-ledger-api
                        , plutus-ledger-constraints
                        , plutus-script-utils
                        , plutus-tx-plugin
                        , plutus-tx
                        , text
                        , serialise
  default-language:    Haskell2010
  ghc-options:         -Wall -fobject-code -fno-ignore-interface-pragmas -fno-omit-interface-pragmas -fno-strictness -fno-spec-constr -fno-specialise
Our exposed-modules: exposes SimplestSuccess as that will be the first validator script we write.
The cabal.project file
We do not need to think too much about the cabal.project file. Simply copy the full file from plutus-scripts/cabal.project as it contains all the dependencies we need. For reference, the full file looks like this:
-- Custom repository for cardano haskell packages
-- See https://github.com/IntersectMBO/cardano-haskell-packages on how to use CHaP in a Haskell project.
repository cardano-haskell-packages
  url: https://chap.intersectmbo.org
  secure: True
  root-keys:
    3e0cce471cf09815f930210f7827266fd09045445d65923e6d0238a6cd15126f
    443abb7fb497a134c343faf52f0b659bd7999bc06b7f63fa76dc99d631f9bea1
    a86a1f6ce86c449c46666bda44268677abf29b5b2d2eb5ec7af903ec2f117a82
    bcec67e8e99cabfa7764d75ad9b158d72bfacf70ca1d0ec8bc6b4406d1bf8413
    c00aae8461a256275598500ea0e187588c35a5d5d7454fb57eac18d9edb86a56
    d4a35cd3121aa00d18544bb0ac01c3e1691d618f462c46129271bccf39f7e8ee
packages: hpm-validators.cabal
index-state: 2022-11-14T00:20:02Z
index-state:
  , hackage.haskell.org 2022-11-14T00:20:02Z
  , cardano-haskell-packages 2022-11-17T04:56:26Z
-- We never, ever, want this.
write-ghc-environment-files: never
allow-newer:
  -- cardano-ledger packages need aeson >2, the following packages have a
  -- too restictive upper bounds on aeson, so we relax them here. The hackage
  -- trustees can make a revision to these packages cabal file to solve the
  -- issue permanently.
  , ekg:aeson
  , ekg-json:aeson
  , openapi3:aeson
  , servant:aeson
  , servant-client-core:aeson
  , servant-server:aeson
constraints:
  -- cardano-prelude-0.1.0.0 needs
  , protolude <0.3.1
  -- cardano-ledger-byron-0.1.0.0 needs
  , cardano-binary <1.5.0.1
  -- plutus-core-1.0.0.1 needs
  , cardano-crypto-class >2.0.0.0
  , algebraic-graphs <0.7
  -- cardano-ledger-core-0.1.0.0 needs
  , cardano-crypto-class <2.0.0.1
  -- cardano-crypto-class-2.0.0.0.1 needs
  , cardano-prelude <0.1.0.1
  -- dbvar from cardano-wallet needs
  , io-classes <0.3.0.0
  -- newer typed-protocols need io-classes>=0.3.0.0 which is incompatible with dbvar's constraint above
  , typed-protocols==0.1.0.0
-- DELETE
-- The plugin will typically fail when producing Haddock documentation. However,
-- in this instance you can simply tell it to defer any errors to runtime (which
-- will never happen since you're building documentation).
--
-- So, any package using 'PlutusTx.compile' in the code for which you need to
-- generate haddock documentation should use the following 'haddock-options'.
--package plutus-ledger
--  haddock-options: "--optghc=-fplugin-opt PlutusTx.Plugin:defer-errors"
--package plutus-script-utils
--  haddock-options: "--optghc=-fplugin-opt PlutusTx.Plugin:defer-errors"
--package plutus-contract
--  haddock-options: "--optghc=-fplugin-opt PlutusTx.Plugin:defer-errors"
-- These packages appear in our dependency tree and are very slow to build.
-- Empirically, turning off optimization shaves off ~50% build time.
-- It also mildly improves recompilation avoidance.
-- For dev work we don't care about performance so much, so this is okay.
-- package cardano-ledger-alonzo
--   optimization: False
-- package ouroboros-consensus-shelley
--   optimization: False
-- package ouroboros-consensus-cardano
--   optimization: False
-- package cardano-api
--   optimization: False
-- package cardano-wallet
--   optimization: False
-- package cardano-wallet-core
--   optimization: False
-- package cardano-wallet-cli
--   optimization: False
-- package cardano-wallet-launcher
--   optimization: False
-- package cardano-wallet-core-integration
--   optimization: False
-- Waiting for plutus-apps CHaP to be published
source-repository-package
  type: git
  location: https://github.com/intersectMBO/plutus-apps.git
  tag: 65ddfa5d467ed64f8709d7db9faf96151942da82
  subdir:
    cardano-streaming
    doc
    freer-extras
    marconi
    marconi-mamba
    playground-common
    pab-blockfrost
    plutus-chain-index
    plutus-chain-index-core
    plutus-contract
    plutus-contract-certification
    plutus-example
    plutus-ledger
    plutus-ledger-constraints
    plutus-pab
    plutus-pab-executables
    plutus-script-utils
    plutus-tx-constraints
    plutus-use-cases
    rewindable-index
-- Direct dependency.
source-repository-package
    type: git
    location: https://github.com/intersectMBO/quickcheck-dynamic
    tag: c272906361471d684440f76c297e29ab760f6a1e
-- Should follow cardano-wallet.
source-repository-package
    type: git
    location: https://github.com/intersectMBO/cardano-addresses
    tag: b7273a5d3c21f1a003595ebf1e1f79c28cd72513
    subdir:
      -- cardano-addresses-cli
      command-line
      -- cardano-addresses
      core
-- Direct dependency.
-- Compared to others, cardano-wallet doesn't bump dependencies very often.
-- Making it a good place to start when bumping dependencies.
-- As, for example, bumping the node first highly risks breaking API with the wallet.
-- Unless early bug fixes are required, this is fine as the wallet tracks stable releases of the node.
-- And it is indeed nice for plutus-apps to track stable releases of the node too.
--
-- The current version is dated 2022/08/10
source-repository-package
    type: git
    location: https://github.com/intersectMBO/cardano-wallet
    tag: 18a931648550246695c790578d4a55ee2f10463e
    subdir:
      lib/cli
      lib/core
      lib/core-integration
      lib/dbvar
      lib/launcher
      lib/numeric
      lib/shelley
      lib/strict-non-empty-containers
      lib/test-utils
      lib/text-class
-- This is needed because we rely on an unreleased feature
-- https://github.com/intersectMBO/cardano-ledger/pull/3111
source-repository-package
    type: git
    location: https://github.com/intersectMBO/cardano-ledger
    tag: da3e9ae10cf9ef0b805a046c84745f06643583c2
    subdir:
      eras/alonzo/impl
      eras/alonzo/test-suite
      eras/babbage/impl
      eras/babbage/test-suite
      eras/byron/chain/executable-spec
      eras/byron/crypto
      eras/byron/crypto/test
      eras/byron/ledger/executable-spec
      eras/byron/ledger/impl
      eras/byron/ledger/impl/test
      eras/shelley/impl
      eras/shelley/test-suite
      eras/shelley-ma/impl
      eras/shelley-ma/test-suite
      libs/cardano-ledger-core
      libs/cardano-ledger-pretty
      libs/cardano-protocol-tpraos
      libs/cardano-data
      libs/vector-map
      libs/set-algebra
      libs/small-steps
      libs/small-steps-test
      libs/non-integralThe project structure that we will create in this course looks like this:
hpm-validators
├── cabal.project 
├── CHANGELOG.md
├── compiled                        # Compiled assets and validators 
├── dist-newstyle
├── hpm-validators.cabal
├── src/                            # Haskell source code
│   ├── DeadlineParam.hs
│   ├── ExploringScriptContext.hs
│   ├── GuessingGame.hs
│   ├── Helpers/
│   ├── MintingPolicy.hs
│   ├── SharedWallet.hs
│   ├── SharedWalletParam.hs
│   ├── SimplestSuccess.hs
│   └── StakingValidator.hs
└── testnet/                        # Scripts and files for testing validators
    ├── address/
    ├── build-addresses.sh
    ├── DeadlineParam/
    ├── ExploringScriptContext/
    ├── GuessingGame/
    ├── MintingPolicy/
    ├── SharedWallet/
    ├── SharedWalletParam/
    ├── SimplestSuccess/
    └── StakingValidator/Last updated