10

I'm from ETH's ecosystem and recently just decided to get into Cardano development, specifically Plutus dev work thanks to Demeter.Run, and after going through the Plutus starters on there, I noticed there weren't any guides on how to start a fresh project from scratch. I did a speedrun through the latest iteration of the Plutus Pioneer course and found out that most of the work was either done in the Playground, the Repl, or built from the top of an existing project(which still doesn't add up to me).

Tried moving some sample .hs code from Plutus-apps and Alonzo-testnet repos hoping to compile and submit them for my own experience and only ended up fighting with GHC and Cabal errors because the sample code used other dependencies and structures different from the secondhand project I was guided to build on top of.

I don't want to start a project by piggybacking on some already existing files and .cabal and .project configs with specs I don't know/understand.

If I was starting a NodeJs project I'd begin with npm init then go from there

My question is, how can I start a new Plutus project from scratch such that I know

  1. how to setup my .cabal file dependencies
  2. how to setup what's needed for the .project file
  3. where to input my fresh code (or borrowed code from Plutus-apps samples to test) because there's the "main.hs" in the app folder which I learned from Haskell but Plutus samples put their .hs code files in the "src" folder, the "main.hs" in the app folder contains something completely different.
  4. how to compile my .hs to .plutus

Everything that comes after these 4 steps i.e. submitting that new .plutus file to the chain (serialised) and building Tx's I know how to do.

I am using Demeter.Run and working from the Terminal and Cardano-CLI from the workspaces, I am under the impression every dependency from IOHK/IOG is setup. I don't know nix and the plutus starter samples didn't need that so hope to progress that way.

I have very minimal Haskell but learning the basics hasn't been tough but I'm good with front-end Javascript and some Solidity.

Please be as detailed/technical as you like, thank you.

Note: I went through the previous questions posed in the links below but still did not get it.

Starting a new Plutus Project

How to Start a New Project

1
  • This is a great question. It would be great if there is a guide that show every step from zero to a working dapp on testnet. Plutus Pioneer Program doesn't provide the complete picture. Plutus Playground doesn't compile most of the time. I previously thought it's just me.
    – Adam
    Nov 5, 2022 at 11:54

3 Answers 3

5

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 ~/.cabal/ folder.

The dependencies

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 3.6.2.0. 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 3.6.2.0
ghcup set cabal 3.6.2.0

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
cd libsodium
git checkout 66f017f1
./autogen.sh
./configure
make
sudo make install

In addition to this add the following to your ~/.bashrc and reload your terminal again to add it to your path

export LD_LIBRARY_PATH="/usr/local/lib:$LD_LIBRARY_PATH"
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig:$PKG_CONFIG_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
cd secp256k1
git checkout ac83be33
./autogen.sh
./configure --enable-module-schnorrsig --enable-experimental
make
make check
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
cd example-project-basic
cabal update
cabal run

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

mkdir my-plutus-project
cd my-plutus-project
cabal init
touch cabal.project

You could also use the flag --interactive for a more detailed set up with cabal init.

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,

packages: 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

to

packages: ./

source-repository-package
    type: git
    location: https://github.com/input-output-hk/plutus-apps
    tag: the_latest_release_tag_used_here_CHANGE_ME!!!
    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

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 ^>=4.14.3.0
                    , aeson
                    , bytestring
                    , containers
                    , cardano-api
                    , data-default
                    , plutus-ledger
                    , plutus-ledger-api
                    , plutus-ledger-constraints
                    , plutus-script-utils
                    , plutus-tx-plugin
                    , plutus-tx
                    , text
                    , serialise

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 Main.hs executable.

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!

4

Since this question was posted Plutus-alternatives have been developed by the community that allow doing DApp development in JavaScript only. One such library is https://github.com/hyperion-bt/Helios

https://www.hyperion-bt.org/Helios-Book/api/picoswap/index.html is a step-by-step guide on how to implement a simple marketplace. The example code can be found here, and a demo is hosted here

5
  • Helios seems very interesting, although my confidence in the project decline the second I saw they chose to build Helios in JavaScript.
    – CoderMan
    Nov 28, 2022 at 4:03
  • There isn't really an alternative for javascript if you want to build pure client-side DApps Nov 28, 2022 at 6:55
  • The fact that the Helios compiler uses javascript to compile to plutus untyped core is a huge advantage and allows for the dynamic compiling to plutus core on any architecture that supports javascript (browser, mobile devices, etc). The helios language itself is a functional programming language, so you get all the benefits of a strongly typed functional programming language for writing your smart contracts, but you can compile it almost anywhere.
    – lley154
    Feb 9 at 0:43
  • doesn't answer the question
    – zing
    Apr 9 at 16:32
  • People who are struggling with Plutus should know there are easier alternatives Apr 10 at 1:13
0

You can start with cloning https://github.com/input-output-hk/plutus-starter

and follow the readme in that repo

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.