Welcome to the Plutus development onboarding guide! This document walks you through:
- Installing Nix (with flakes +
nix-command) on Ubuntu, Fedora, Arch, Windows WSL2, and Windows native - Entering a reproducible dev shell
- Building with Cabal
- Understanding the Vesting contracts and utilities
π NOTE: Detailed tutorials live in
/code/wspace/lecture.
-
βοΈ Environment Setup (Nix + Flakes)
- 2.1 Ubuntu
- 2.2 Fedora
- 2.3 Arch
- 2.4 Windows (WSL2)
- 2.5 Windows (Native)
- 2.6 Verify Your Setup
-
π Understanding the Contracts
- 5.1 Basic Vesting
- 5.2 Parameterized Vesting
From Zero to Hero Haskell Plutus Flake.nix Template
- Git CLI
- Nix (weβll install it below with flakes enabled)
- Optional: VS Code + Haskell extension
We recommend multi-user (daemon) installs on Linux and WSL2 for Windows. Flakes are enabled via
NIX_CONFIGor/etc/nix/nix.conf.
Add to ~/.bashrc (or ~/.zshrc) to always load Nix and enable flakes:
# Nix profile (added by me)
if [ -e /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh ]; then
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
elif [ -e "$HOME/.nix-profile/etc/profile.d/nix.sh" ]; then
. "$HOME/.nix-profile/etc/profile.d/nix.sh"
fi
# Enable Nix experimental features for this shell
export NIX_CONFIG="experimental-features = nix-command flakes"β System-wide alternative (Linux/WSL): Create
/etc/nix/nix.conf(no need for theexportabove if you do this):experimental-features = nix-command flakes
Install (daemon):
sh <(curl -L https://nixos.org/nix/install) --daemon
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.shOptional system-wide flakes:
sudo mkdir -p /etc/nix
echo 'experimental-features = nix-command flakes' | sudo tee /etc/nix/nix.confSELinux is enabled by default. If the daemon wonβt start, check
journalctl -u nix-daemon.
Install (daemon):
sh <(curl -L https://nixos.org/nix/install) --daemon
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
sudo systemctl enable --now nix-daemonOptional system-wide flakes:
sudo mkdir -p /etc/nix
echo 'experimental-features = nix-command flakes' | sudo tee /etc/nix/nix.confInstall (daemon):
sh <(curl -L https://nixos.org/nix/install) --daemon
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
sudo systemctl enable --now nix-daemonOptional system-wide flakes:
sudo mkdir -p /etc/nix
echo 'experimental-features = nix-command flakes' | sudo tee /etc/nix/nix.confRecommended Windows path for Plutus dev.
Enable systemd in WSL (once):
sudo tee /etc/wsl.conf >/dev/null <<'EOF'
[boot]
systemd=true
EOFThen, in Windows PowerShell:
wsl --shutdownReopen Ubuntu (WSL).
Install (daemon) inside WSL:
sh <(curl -L https://nixos.org/nix/install) --daemon
. /nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh
sudo systemctl enable --now nix-daemonOptional system-wide flakes (inside WSL):
sudo mkdir -p /etc/nix
echo 'experimental-features = nix-command flakes' | sudo tee /etc/nix/nix.confNative Nix on Windows is evolving. Prefer WSL2 if possible. If you proceed natively, enable flakes via PowerShell:
User-level persistent env:
setx NIX_CONFIG "experimental-features = nix-command flakes"(Reopen PowerShell.)
Optional profile for immediate effect:
if (!(Test-Path $PROFILE)) { New-Item -Type File -Path $PROFILE -Force | Out-Null }
Add-Content $PROFILE '$env:NIX_CONFIG = "experimental-features = nix-command flakes"'If you use Git Bash/MSYS, you can add the same Linux snippet to ~/.bashrc and adjust any profile paths installed by the native Nix package.
nix --version
nix flake --help
nix doctorOn Linux/WSL:
systemctl status nix-daemongit clone <your-repo-url>
cd plutus-nixnix developIf not using flakes:
nix-shellcabal update
cabal build allThis builds both the Utilities library and the wspace smart contract/test modules.
plutus-nix/
βββ .devcontainer/
βββ .vscode/
βββ code/
β βββ dist-newstyle/
β βββ nix/
β βββ Utilities/
β β βββ src/
β β β βββ Utilities/
β β β βββ Conversions.hs
β β β βββ PlutusTx.hs
β β β βββ Serialise.hs
β β β βββ Utilities.hs
β β βββ Utilities.cabal
β β βββ hie.yaml
β βββ wspace/
β β βββ assets/
β β βββ lecture/
β β β βββ CGPlutusUtilsv1.hs
β β β βββ CGTime.hs
β β β βββ ParameterizedVesting.hs
β β β βββ Vesting.hs
β β βββ test/
β β β βββ CGPlutusUtilsSpec.hs
β β β βββ CGTimeSpec.hs
β β β βββ VestingSpec.hs
β β β βββ ParameterizedVestingSpec.hs
β β β βββ Spec.hs
β β β βββ Main.hs
β β βββ docs/
β β βββ Tutorials.md
β β βββ cabal.project
β β βββ wspace.cabal
βββ .gitignore
βββ flake.nix
βββ README.md
-
File:
lecture/Vesting.hs -
Validates that:
- A transaction is signed by the beneficiary
- The deadline has been reached
-
File:
lecture/ParameterizedVesting.hs -
Accepts:
beneficiary :: PubKeyHashdeadline :: POSIXTime
-
Uses
liftCodeto embed these at compile time
-
File:
lecture/CGPlutusUtilsv1.hs- Decode Bech32 β PubKeyHash
- Encode PubKeyHash β Bech32 (mainnet/testnet)
-
File:
lecture/CGTime.hs- POSIX, ISO8601, UTC conversions
- Time arithmetic: add/diff/getNow
main :: IO ()
main = defaultMain teststest/
βββ CGPlutusUtilsSpec.hs
βββ CGTimeSpec.hs
βββ VestingSpec.hs
βββ ParameterizedVestingSpec.hs
βββ Spec.hs
βββ Main.hs
Run tests via:
cabal test all| Term | Description |
|---|---|
| POSIXTime | Seconds since the Unix epoch |
| PubKeyHash (PKH) | Hash of a wallet's public key |
| Validator | The on-chain logic for validation |
| ScriptContext | Transaction context during validation |
| liftCode / applyCode | Embeds values directly into compiled code |
| Bech32 | Human-readable address format for Cardano |
| txSignedBy | Checks if a transaction is signed by a specific PKH |
| Utilities Library | Helper functions for off-chain dev/test |
| Cabal / Nix | Build and environment tools for Haskell & Plutus |
| Term | Description |
|---|---|
| UTxO | Unspent transaction output, Cardanoβs accounting model |
| Datum | On-chain data attached to UTxOs |
| GADT | Generalized Algebraic Data Type in Haskell |
| HRP | Human-Readable Part of a Bech32 string |
MIT License
Copyright (c) 2025 Women In Move Solutions (Pty) Ltd & Coxygen Global (Pty) Ltd
...
- Author: Bernard Sibanda
- Company: Coxygen Global (Pty) Ltd
- Date: 27 September, 2025
Who is Bernard Sibanda? (Professional Intro omitted here for brevity; keep your original βProfessional Introductionβ section beneath this license block as-is.)
-
nix flakeunknown: Ensure your shell loaded the snippet or/etc/nix/nix.confhasexperimental-features = nix-command flakes. -
Daemon issues (Linux/WSL):
sudo systemctl status nix-daemon journalctl -u nix-daemon -e
On WSL, confirm
/etc/wsl.confhassystemd=trueand you ranwsl --shutdown. -
nix developnot found: Youβre not on flakes; either enable flakes or usenix-shell. -
Cabal canβt find GHC: Enter the Nix dev shell first (
nix develop) so toolchains are pinned.

