completed
Plutarch: typed eDSL in Haskell
Current Project Status
Complete
Amount
Received
$75,000
Amount
Requested
$75,000
Percentage
Received
100.00%
Solution

Typed eDSL in Haskell for writing significantly more efficient Plutus Core validators compared to the PlutusTx smart contract execution cost

Problem

Stateful Plutus smart contracts (DeFi) are difficult to implement due to Cardano’s current transaction size parameters (16kb Tx size limit).

Addresses Challenge
Feasibility
Auditability

Liqwid

3 members

Plutarch: typed eDSL in Haskell

Plutarch Overview

Plutarch User Guide:

<https://github.com/Plutonomicon/plutarch/blob/master/docs/README.md>

Plutarch Developer Guide: <https://github.com/Plutonomicon/plutarch/blob/koz/numeric/docs/DEVGUIDE.md>

Plutarch is an eDSL in Haskell for writing on-chain scripts for Cardano. With some caveats, Plutarch is a simply-typed lambda calculus (or STLC). Writing a script in Plutarch allows us to leverage the language features provided by Haskell while retaining the ability to compile to compact Untyped Plutus Core (or UPLC, which is an untyped lambda calculus).

When we talk about "Plutarch scripts," we are referring to values of type Term (s :: S) (a :: PType). Term is a newtype wrapper around a more complex type, the details of which Plutarch end-users can ignore. A Term is a typed lambda term; it can be thought of as representing a computation that, if successfully evaluated, will return a value of type a.

The two type variables of the Term s a declaration have particular kinds:

s :: S is like the s of ST s a. It represents the computation context in a manner that mimics mutable state while providing a familiar functional interface. Sections 1 through 4 of [1] give an accessible introduction to how this works. s is never instantiated with a concrete value; it is merely a type-level way to ensure that computational contexts remain properly encapsulated (i.e., different state threads don't interact). For more in-depth coverage of this and other eDSL design principles used in Plutarch, see [2].

a :: PType is short-hand for "Plutarch Type". We prefix these types with a capital P, such as PInteger, PBool, and so forth. Tagging a Term with a PType indicates the type of the Term's return value. Doing this allows us to bridge between the simple type system of Plutarch and the untyped UPLC.

In brief, when writing Plutarch scripts, we have a few tasks:

A.) Defining Plutarch Types (or PTypes). We prefix these types with a capital P, such as PInteger, PMaybe a, PBool, and so forth. As previously mentioned, these form the "tags" for Plutarch Term's, representing the type of the result of compiling and evaluating a Plutarch Script.

B.) Working with Plutarch Terms, which are values of the type Term (s :: S) (a :: PType). These are the Plutarch scripts themselves, from which we build up more complex scripts before compiling and executing them on-chain.

C.) Writing Haskell-level functions between Plutarch Terms (i.e., with types like Term s a -> Term s b). Doing so allows us to leverage Haskell's language features and ecosystem.

D.) Efficiently Converting the functions from (C.) to Plutarch-level functions, which are of the type Term s (a :–> b). We can directly convert the functions from (C.) to Plutarch-level functions at the most naive level using plam. Additional Plutarch utilities provide for optimization opportunities.

E.) Compiling and executing the functions from (D.), targeting UPLC for on-chain usage.

*There are two general categories of functions in Plutarch: "Haskell-level" functions between terms, and "Plutarch-level" functions as lambda terms. By convention, we will prefix the Haskell-level functions with h and the Plutarch-level lambdas with p, (example in attached image).

Plutarch written validators are often significantly more efficient than Plutus Tx (massive reduction in execution costs) written validators. With Plutarch, developers have much more fine gained control of the Plutus Core validator generated, without giving up any type information.

To put things into perspective, one validator script from a large production contract was rewritten in Plutarch, changed from Plutus Tx. The comparison between the Plutarch script's execution cost compared to the Plutus Tx script's execution cost (benchmark comparison of the CPU, Memory, Script Size attached). These numbers were gathered by simulating the whole contract flow on a testnet.

Plutarch provides a highly performant alternative for Haskell engineers to begin writing Plutus core validators *today* without the current limitations of PlutusTx.

An open source alternative to writing validators in PlutusTx addresses the open source development challenge in several ways. With the release of Plutarch v1.1:

Haskell developers now have the infrastructure needed to write untyped Plutus Core validators and a lower barrier to building Plutus smart contracts since no need to learn the nuances of PlutusTx.

With Plutarch as a smart contract language closer to raw Haskell new developers now gain a diverse selections of paths to build their Plutus smart contracts rather than the singular PlutusTx option.

Expanding options and lowering the barrier to entry for proficient Haskell devs who want to build Cardano smart contracts but don't want to learnt the subtleties of PlutusTx, this is how Plutarch addresses the open source development challenge.

As an open source project the main risk is linked to implementing a structure to ensure the code maintenance and feature updates continue at a predictable pace from dedicated (incentivized) core code contributors. Currently contributions come from engineers at multiple firms (with MLabs coordinating the work).

The feature updates required to bring Plutarch's contract functionality 1:1 with PlutusTx and continue maintenance into the future are the major workstreams involved in successfully delivering this proposal. This mostly involves setting up a more formal structure for prioritizing Plutarch workstreams and coordinating with the core developers at MLabs currently building out functionality/infrastructure.

Haskell developers can use Plutarch to write more efficient validators:

  1. validators that always success
  2. validators that always fail
  3. validators that check whether a value is present within signatures
  4. using custom datum/redeemers in your validators

Validator and minting policies with examples can all be found within the Plutarch developer guide: <https://github.com/Plutonomicon/plutarch/blob/master/docs/examples/VALIDATOR.md>

Budget breakdown:

Engineering hours: 1150

Total budget request: $75,000

Feature Total Time

Plutarch extended numeric hierarchy support (workstream started) …………………………………..100

Plutarch-test updates (mainly for golden testing and size checking) …………………………………..100

Enhancements to Plutarch testing and benchmark tools …………………………………..200

Implementing Plutarch helper functions …………………………………………………100

Plutarch version 1.2 updates to bring to parity with Plutus changes………………………………..200

Plutarch functionality to create/manage Stake Validators ……………………………………………150

Technical documentation and code examples………………………………………………………50

General Testing………………………………………………………………………………………..75

Security Audit………………………………………………………………………………………………..75

Technical Specification………………………………………………………………………………………………………..100

Total Time………………………………………………………………………………………………..1150 engineering hours

Total Budget request $75,000

The MLabs team is driving the Plutonomicon effort as an open source tooling for Plutus developers to leverage.

The # of commits, contributors, forks/stars on the Plutarch Github repo are the main KPIs currently being tracked to measure the project's growth.

In addition to these metrics the total number of Plutus dApp/DeFi/NFT projects using Plutarch will be a critical KPI to measure for real world impact of the project.

Success for this project:

3 months: Plutarch on-chain smart contract functions 1:1 with PlutusTx, Plutarch API/off-chain infrastructure functionality 1:1 with PlutusTx off-chain/infra.

6 months: Plutarch development extended to include latest CIPs functionality.

This is an entirely new proposal.

close

Playlist

  • EP2: epoch_length

    Authored by: Darlington Kofa

    3m 24s
    Darlington Kofa
  • EP1: 'd' parameter

    Authored by: Darlington Kofa

    4m 3s
    Darlington Kofa
  • EP3: key_deposit

    Authored by: Darlington Kofa

    3m 48s
    Darlington Kofa
  • EP4: epoch_no

    Authored by: Darlington Kofa

    2m 16s
    Darlington Kofa
  • EP5: max_block_size

    Authored by: Darlington Kofa

    3m 14s
    Darlington Kofa
  • EP6: pool_deposit

    Authored by: Darlington Kofa

    3m 19s
    Darlington Kofa
  • EP7: max_tx_size

    Authored by: Darlington Kofa

    4m 59s
    Darlington Kofa
0:00
/
~0:00