A well formatted question deserves a well formatted answer! I will go into some depths, but also keep some things at a “magical” level. This is a long read so take your time!
Before we start, it is good to note that most of the Cardano stack is written in Haskell, and thus, managing a Plutus project is just managing a Haskell project. There are multiple ways of doing this, just a plain Cabal project or one of the many Nix ways of building (cabal2nix, Haskell.nix and many others). Now there are good reason to use these Nixs ways (most notably reproducibility and caching), but in this answer I will focus on a more understandable way of just using GHC + cabal on Ubuntu 22.04 (not the minimal install).
A disclaimer, building everything yourself requires lots of ram (you can also re-run the
cabal run command if you run out of memory mid-process). The good thing, however, once build you have these Haskell artifact locally prebuilt in your
Before we can even build a general all-purpose Haskell/plutus project, we need some basic building tools necessary to even start compiling! These mainly consist of the following tools,
- OS dependent dependencies
- GHC and Cabal
- A special version of libsodium
- A special version of libsecp256k1
OS dependent dependencies
To build everything, you at least need these dependencies
sudo apt-get update -y && sudo apt-get upgrade -y
sudo apt-get install automake build-essential pkg-config libffi-dev libgmp-dev libssl-dev libtinfo-dev libsystemd-dev zlib1g-dev make g++ tmux git jq wget libncursesw5 curl libtool postgresql libpq-dev autoconf -y
Note that translating these OS dependent dependencies to other operating systems is hard and out of the scope of this post (this is why you might want nix). They may also change in the future as the project might add new dependencies.
GHC and Cabal
It is recommended by IOG to use GHC version 8.10.7 and Cabal version 188.8.131.52. These can be installed via GHCUP via,
curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
You can press enter for all question the installer asks. Then reload your terminal (to make
ghcup appear in your path) and,
ghcup install ghc 8.10.7
ghcup set ghc 8.10.7
ghcup install cabal 184.108.40.206
ghcup set cabal 220.127.116.11
Reload your terminal again to make these appear in your path and set
cabal configure --with-compiler=ghc-8.10.7
A special version of libsodium
Libsodium is a tool chain (written for performance) for cryptographic derivatives, for example you can create signatures and hashes with it. We require a particular version of it that adds VRF cryptography to it (used for the Cardano consensus mechanism). Installing this can be done via,
git clone https://github.com/input-output-hk/libsodium
git checkout 66f017f1
sudo make install
In addition to this add the following to your
~/.bashrc and reload your terminal again to add it to your path
A special version of libsecp256k1
Since the Vasil hard fork Cardano has the secp256K1 signature scheme available in plutus. This allows for the validation of Bitcoin signatures and will make it easier to build bridges. Bitcoin is not the only blockchain that use this signature scheme, many others do. So to install this library (again a particular audited version) you use,
git clone https://github.com/bitcoin-core/secp256k1
git checkout ac83be33
./configure --enable-module-schnorrsig --enable-experimental
sudo make install
A preconfigure project
We are ready to build a Plutus project! Before I tell how you can set up such a project, I want to share an already set up example. This so that you can test that you correctly installed the dependencies above. To run this example you use
git clone https://github.com/perturbing/example-project-basic.git
I would like to reiterate, if you do not have sufficient ram available, for example because you run this example in a VM, you can
cabal run again if your memory overflows. This example ran for me in a vm with 10gb ram.
Now how is this project setup?
This project and its structure is not constructed arbitrarily. It is namely derived from the latest release of the plutus-apps repository. This repository and its management of dependencies is chosen because it imports and exposes almost all important Haskell packages written for Cardano.
Now, how to concretely set up and copy the essential bits of this repo? It consists of the following steps.
To start we execute
You could also use the flag
--interactive for a more detailed set up with
Next, we copy the
cabal.project file of plutus-apps from its latest release (do not pick the main branch, consider this is unstable). Currently, the latest version of this file is this. Next, we need to adjust some pieces of this file to make it work for us.
The first thing to change, this
cabal.project file does not import the
plutus-apps repo (since it was part of the original one). So, we need to add that by changing the code that declared the to build packages of the plutus-apps repo. It also does not declare our new build artifacts of our cabal project, we have to change the exposed packages it has to build. Both can be achieved by changing,
Next up, we can add to our executables and/or libraries on which modules they depend. For example, we might add to our
my-plutus-project.cabal file that the executable depends on
build-depends: base ^>=18.104.22.168
And lastly, we can write our
app/Main.hs file to execute some functions for us. A simple
cabal update and a
cabal run will execute your
Some last words
This is a long answer, and in no way is complete. I advise anyone who is eager to learn more about Haskell to take the Haskell course from IOG (it also covers cabal!). I hope this gets you started!