Skip to content

Commit

Permalink
docs: update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nau committed Apr 21, 2024
1 parent 3c653be commit af02e75
Show file tree
Hide file tree
Showing 8 changed files with 431 additions and 194 deletions.
21 changes: 18 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,43 @@
# Contributing to Scalus

## Env setup
## Pre-requisites

- Java 11+, sbt 1.x
- Cardano `uplc` CLI tool

## Env setup with Nix

```bash
nix develop
```

## Build

```bash
sbt precommit
```

## Docusaurus

Run locally

```bash
cd website
yarn install
yarn run serve
```

## Deploy to GitHub Pages

```bash
cd website
USE_SSH=true yarn deploy
USE_SSH=true yarn deploy
```

## Run benchmarks

In sbt shell

```bash
jmh:run -i 1 -wi 1 -f 1 -t 1
jmh:run -i 1 -wi 1 -f 1 -t 1
```
161 changes: 126 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,51 @@
![Maven Central](https://img.shields.io/maven-central/v/org.scalus/scalus_3)
[![Discord](https://img.shields.io/discord/1105852427346911252.svg?label=&logo=discord&logoColor=ffffff&color=404244&labelColor=6A7EC2)](https://discord.gg/ygwtuBybsy)

## Vision

Scalus is a platform for developing decentralized applications (DApps) on the Cardano blockchain.

The goal is to make a full-stack development experience for Cardano DApps as smooth as possible.
Using the same language, tools and code for frontend, backend and smart contracts development.

## Write Cardano smart contracts in Scala 3

* Scala is a modern functional programming language that runs on JVM and JavaScript.
* Scala is a modern functional programming language that runs on JVM, JavaScript and natively via LLVM.
* Reuse your Scala code for your validator, frontend and backend.
* Write once, run anywhere. True full-stack development.
* Scala's powerful type system helps you write correct code.
* Benefit from a huge ecosystem of libraries and tools.
* Utilize testing frameworks like ScalaTest and ScalaCheck.
* Utilize testing frameworks like ScalaTest and ScalaCheck
for [property-based testing](https://en.wikipedia.org/wiki/Property-based_testing).
* Enjoy comprehensive IDE support: IntelliJ IDEA, VSCode.
* Advanced debugging support.
* Enhanced code formatting and linting, navigation, and refactoring.

## Roadmap

### Efficiently convert user defined data types from/to Plutus Data

Now, Scalus takes the same approach as PlutusTx.
This change makes it similar to Aiken, which will result in smaller and more efficient Plutus scripts in most cases.

### Support for Plutus V3

Plutus V3 is coming soon. Scalus will support all new built-ins and features.

### Single transaction building and signing API for backend and frontend

This will allow you to build and sign transactions in Scala and JavaScript using the same code.

### DApp development framework

A framework that will help you build DApps faster and easier.

You define your smart contracts, data types, and interaction endpoints in Scala.
The framework will generate the frontend and backend code for you.

Yes, your REST API, WebSocket, and GraphQL endpoints for your DApp.
And the JavaScript code to interact with your DApp from the browser.

## How It Works

Scalus compiles a subset of Scala code to Plutus Core, the language of Cardano smart contracts.
Expand All @@ -28,7 +61,7 @@ Write efficient and compact smart contracts and squeeze the most out of the Card
* Scala 3 to Cardano Plutus Core compiler
* Standard library for Plutus contracts development
* Plutus V1 and V2 support
* Plutus VM Interpreter
* Plutus VM Interpreter and execution budget calculation
* Property-based testing library
* Untyped Plutus Core (UPLC) data types and functions
* Flat, CBOR, JSON serialization
Expand All @@ -44,71 +77,129 @@ Clone the repository and follow the instructions in the README.

### Preimage Validator Example

Here is a simple validator that checks that an signer of `pkh` PubKeyHash provided a preimage of a `hash` in a `redeemer`.
Below example is taken from [`PreImageExampleSpec.scala`](https://github.com/nau/scalus/blob/master/jvm/src/test/scala/scalus/PreImageExampleSpec.scala)

```scala
def preimageValidator(datum: Data, redeemer: Data, ctxData: Data): Unit = {
// deserialize from Data
val (hash, pkh) = fromData[(ByteString, ByteString)](datum)
val preimage = fromData[ByteString](redeemer)
val ctx = fromData[ScriptContext](ctxData)
// get the transaction signatories
val signatories = ctx.txInfo.signatories
// check that the transaction is signed by the public key hash
List.findOrFail(signatories) { sig => sig.hash == pkh }
// check that the preimage hashes to the hash
if Builtins.sha2_256(preimage) == hash then ()
else throw new RuntimeException("Wrong preimage")
// throwing an exception compiles to UPLC error
}
// compile to Scalus Intermediate Representation, SIR
val compiled = compile(preimageValidator)
// convert SIR to UPLC
val validator = compiled.toUplc()
val plutusScript = Program((1, 0, 0), validator).doubleCborHex
Here is a simple validator that checks that an signer of `pkh` PubKeyHash provided a preimage of a `hash` in
a `redeemer`.
Below example is taken
from [`PreImageExampleSpec.scala`](https://github.com/nau/scalus/blob/master/jvm/src/test/scala/scalus/PreImageExampleSpec.scala)

```scala 3
def preimageValidator(datum: Data, redeemer: Data, ctxData: Data): Unit =
// deserialize from Data
val (hash, pkh) = fromData[(ByteString, ByteString)](datum)
val preimage = fromData[ByteString](redeemer)
val ctx = fromData[ScriptContext](ctxData)
// get the transaction signatories
val signatories = ctx.txInfo.signatories
// check that the transaction is signed by the public key hash
List.findOrFail(signatories) { sig => sig.hash == pkh }
// check that the preimage hashes to the hash
if sha2_256(preimage) == hash then ()
else throw new RuntimeException("Wrong preimage")
// throwing an exception compiles to UPLC error

// compile to Untyped Plutus Core (UPLC)
val compiled = compile(preimageValidator).toUplc()
// create a validator script, Plutus program version 1.0.0
val validator = Program((1, 0, 0), compiled.toUplc())
// HEX encoded Plutus script, ready to be used in with cardano-cli or Blockfrost
val plutusScript = validator.doubleCborHex
// Create a Cardano .plutus file for this validator
validator.writePlutusFile(path, PlutusLedgerLanguage.PlutusV2)
```

### AdaStream Example

Sources: [AdaStream Contract](https://github.com/nau/adastream/blob/main/contract.scala)

This project is a Cardano implementation of the [BitStream](https://github.com/RobinLinus/BitStream) protocol by Robin
Linus.

Original paper: [BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments
](https://robinlinus.com/bitstream.pdf)

#### TL;DR

* Alice wants to buy a file from Bob.
* Bob encrypts the file with a random key and sends it to Alice.
* Bob creates a bond contract on Cardano with a collateral and a commitment to the key and the file.
* Alice pays Bob for the file via a HTLC (Hash Time Lock Contract), using Cardano or Bitcoin Lightning Network.
* Alice decrypts the file with the key from the HTLC or takes the money back after the timeout.
* If Bob cheats, Alice can prove it and get the collateral from the bond contract.
* Bob can withdraw the collateral by revealing the key.

The project includes a bond contract and a HTLC contract for a fair exchange of files for ADA.

It's a CLI tool and a REST API server that allows you to create a bond contract, pay for a file, and decrypt it.

It has a set of tests that check the contract logic and its execution costs.

### Minting/Burning Example

Here is a full example of a token minting/burning validator that works on both JVM and JavaScript:

[MintingPolicy.scala](https://github.com/nau/scalus/blob/master/shared/src/main/scala/scalus/examples/MintingPolicy.scala)

And here is a project that uses it in web frontend:
[Scalus Minting Example](https://github.com/nau/scalus/tree/master/examples-js)

### Minimal Size Withdrawal Validator

The challenge was to create the smallest possible validator that checks a certain withdrawal exists in the transaction.

[The result is 92 bytes long script](https://gist.github.com/nau/b8996fe3e51b0e21c20479c5d8548ec7)

## Comparison to PlutusTx, Aiken, Plutarch

### PlutusTx

PlutusTx compiles almost any Haskell program to UPLC.
Cons are that you can barely understand how the UPLC is generated and how to make it smaller.
PlutusTx also tends to generate a lot of boilerplate code making the final script size bigger and more expensive to run.

### Aiken

Aiken is a new and young programming language which is a pro and a con. Can only be used for smart contracts.
Lacks property-based testing.
Aiken is a new and young programming language which is a pro and a con.
Can only be used for writing smart contracts.
Has limited support of property-based testing as you need to define custom generators in Rust.

### Plutarch

Plutarch is very low-level. Use it when you need precise control over a script generation.
It's a Haskell library so be prepared to write Haskell code with all its developer experience drawbacks.

### Plu-ts

Plu-ts is a TypeScript DSL for writing Plutus scripts.
With Scalus you can do the same and much more but in Scala, and produce JavaScript code.

### Scalus

Scalus aimes to be a better version of all the above.

* You can actually reuse Scala code for your validator, frontend and backend! The goal that PlutusTx failed to achieve.
* You can actually reuse Scala code for your validator, frontend and backend!
The goal that PlutusTx failed to achieve.

* You can use existing Scala libraries for testing, including ScalaCheck and ScalaTest.

* Scala has a powerful type system that helps you write correct code. Check out [Stainless – Formal Verification for Scala](https://stainless.epfl.ch/) for formal verification.
* Scala has a powerful type system that helps you write correct code. Check
out [Stainless – Formal Verification for Scala](https://stainless.epfl.ch/) for formal verification.

* Scalus leverages all the development tools that Scala has, including IntelliJ Idea, VSCode, sbt, even GitHub CoPilot and ChatGPT! No need to learn new tools and languages.
* Scalus leverages all the development tools that Scala has, including IntelliJ Idea, VSCode, sbt, even GitHub CoPilot
and ChatGPT! No need to learn new tools and languages.

* Debugger! It works!

* Scalus allows only a limited subset of Scala, that can be reasonably efficiently
compiled to UPLC without bloating the code.
compiled to UPLC without bloating the code.

* It's compiled to a fairly high-level human readable intermediate representation, SIR.
* It's compiled to a fairly high-level human-readable intermediate representation, SIR.

* The huge part of any usefull script is `ScriptContext` deserialization from `Data` representation.
Scalus also provides primitives to do your custom deserialization to reduce validator size.
Scalus also provides primitives to do your custom deserialization to reduce validator size.

## Support

You can ask questions on Scalus Discord: <https://discord.gg/ygwtuBybsy>
You can ask questions on Scalus Discord: https://discord.gg/ygwtuBybsy

The project is looking for funding to make it production ready.
If you are interested, please contact me at [@atlanter](https://twitter.com/atlanter) on Twitter.
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ lazy val docs = project // documentation project
publish / skip := true,
moduleName := "scalus-docs",
mdocVariables := Map(
"VERSION" -> version.value,
"VERSION" -> "0.6.1",
"SCALA3_VERSION" -> scalaVersion.value
),
PluginDependency
Expand Down
34 changes: 31 additions & 3 deletions docs/Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,38 @@ sidebar_position: 3
---
# Examples

## Validator examples
## AdaStream

## AdaStream Example

[AdaStream](https://github.com/nau/adastream) - Decentralized File Hosting Incentivised via Cardano Ada Payments

This project is a Cardano implementation of the [BitStream](https://github.com/RobinLinus/BitStream) protocol by Robin
Linus.

Original paper: [BitStream: Decentralized File Hosting Incentivised via Bitcoin Payments
](https://robinlinus.com/bitstream.pdf)

### TL;DR

* Alice wants to buy a file from Bob.
* Bob encrypts the file with a random key and sends it to Alice.
* Bob creates a bond contract on Cardano with a collateral and a commitment to the key and the file.
* Alice pays Bob for the file via a HTLC (Hash Time Lock Contract), using Cardano or Bitcoin Lightning Network.
* Alice decrypts the file with the key from the HTLC or takes the money back after the timeout.
* If Bob cheats, Alice can prove it and get the collateral from the bond contract.
* Bob can withdraw the collateral by revealing the key.

The project includes a bond contract and a HTLC contract for a fair exchange of files for ADA.

It's a CLI tool and a REST API server that allows you to create a bond contract, pay for a file, and decrypt it.

It has a set of tests that check the contract logic and its execution costs.

## PreImage Validator

[PreImage Validator](https://github.com/nau/scalus/blob/ce7a37edb06ef2e39794825ee4f81ff061198666/jvm/src/test/scala/scalus/PreImageExampleSpec.scala)

[MintingPolicy](https://github.com/nau/scalus/blob/612b4bd581c55cb6c68339247cfecfbe22e4e61d/shared/src/main/scala/scalus/examples/MintingPolicy.scala)
## Minting Policy

[AdaStream](https://github.com/nau/adastream) - Decentralized File Hosting Incentivised via Cardano Ada Payments
[MintingPolicy](https://github.com/nau/scalus/blob/612b4bd581c55cb6c68339247cfecfbe22e4e61d/shared/src/main/scala/scalus/examples/MintingPolicy.scala)
11 changes: 7 additions & 4 deletions docs/Installation.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
---
sidebar_position: 1
---
# Installation
# Quick Start

## Prerequisites

You need a usual Scala development environment: JDK, SBT, IDE.
You need a usual Scala development environment: JDK, [sbt](https://www.scala-sbt.org/), scala-cli an IDE of your choice.

You also can use [Scala CLI](https://scala-cli.virtuslab.org/) instead of SBT.
See [AdaStream](https://github.com/nau/adastream) for an example of a project that uses Scala CLI.

The easiest way to get started is to use [Nix](https://nixos.org/) package manager.

## Nix (recommended)
## Clone Scalus Starter Project

Clone the [Scalus Starter Project](https://github.com/nau/scalus-starter) to get started with Scalus.

Run `nix develop` to enter a development environment with all the required tools installed: JDK, sbt, Cardano node, cardano-cli, etc.
If you use [Nix](https://nixos.org/), we provided `flakes.nix` file to get a development environment with all the required tools installed.

```bash
git clone https://github.com/nau/scalus-starter.git
cd scalus-starter
nix develop
code .
scala-cli run .
```

## Sbt project setup
Expand All @@ -34,3 +35,5 @@ scalaVersion := "@SCALA3_VERSION@"
libraryDependencies += "org.scalus" %% "scalus" % "@VERSION@"
addCompilerPlugin("org.scalus" %% "scalus-plugin" % "@VERSION@")
```

That's it! You can now start using Scalus in your project.

0 comments on commit af02e75

Please sign in to comment.