Skip to Content
Scalus Club is now open! Join us to get an early access to new features 🎉

Primitive Types

Scalus provides full support for Plutus V3 primitive types, enabling you to write Cardano smart contracts using familiar Scala syntax. These types map directly to Plutus Core primitives for efficient blockchain execution.

Type Correspondence

The following table shows how primitive types map between Plutus, Scalus, and Aiken:

Plutus V3ScalusAiken
unitUnitVoid
boolBooleanBool
integerBigIntInt
bytestringByteStringByteArray
stringStringString
dataDataData
listList[A]List<a>
pairPair[A, B]Pair<a, b>
BLS12_381_G1_ElementBLS12_381_G1_ElementG1Element
BLS12_381_G2_ElementBLS12_381_G2_ElementG2Element
BLS12_381_MlResultBLS12_381_MlResultMillerLoopResult

Scalus leverages Scala’s native types for Unit, Boolean, BigInt, and String, providing a familiar programming experience. For blockchain-specific types, Scalus offers custom implementations with convenient constructors and utility methods.

Creating Values

Unit

The unit type represents the absence of a meaningful value. It’s similar to void in other languages but is an actual value.

val unit: Unit = ()

Boolean

Boolean values are either true or false. Scalus supports all standard boolean operators.

val bool = true val and = true && false // logical AND val or = true || false // logical OR val not = !true // logical NOT val eq = true == false // equality val neq = true != false // inequality

BigInt

Arbitrary precision integers are the primary numeric type in Plutus. Scalus uses Scala’s BigInt.

val small = BigInt(123) val large = BigInt("123456789012345678901234567890") val fromInt: BigInt = 42 // automatic conversion from Int // Arithmetic operations val sum = BigInt(10) + BigInt(20) val diff = BigInt(100) - BigInt(30) val product = BigInt(5) * BigInt(7) val quotient = BigInt(20) / BigInt(4) val remainder = BigInt(17) % BigInt(5) // Comparison val greater = BigInt(10) > BigInt(5) val less = BigInt(3) < BigInt(7) val greaterOrEqual = BigInt(10) >= BigInt(10) val lessOrEqual = BigInt(5) <= BigInt(10) val equals = BigInt(42) == BigInt(42)

ByteString

ByteStrings are immutable byte arrays, commonly used for hashes, cryptographic keys, and binary data.

import scalus.builtin.ByteString import scalus.builtin.ByteString.* // Creating ByteStrings val empty = ByteString.empty val fromHex = ByteString.fromHex("deadbeef") val fromArray = ByteString.fromArray(Array[Byte](0xde.toByte, 0xad.toByte)) val fromString = ByteString.fromString("Hello") // UTF-8 encoded val utf8Literal = utf8"Привіт світ" // using utf8 string interpolator val hexLiteral = hex"deadbeef" // using hex string interpolator // Operations val concat = hex"dead" ++ hex"beef" val length = fromHex.length val take = fromHex.take(2) // first 2 bytes val drop = fromHex.drop(2) // skip first 2 bytes val slice = fromHex.slice(1, 3) // bytes from index 1 to 3 // Comparison val eq = fromHex == hex"deadbeef" val compare = fromHex < hex"ffffff"

String

Strings are Unicode text values.

val greeting = "Hello, Cardano!" val concat = "Hello" ++ " " ++ "World" val eq = "test" == "test"

Data

Data is Plutus’s universal representation type, used for serialization and interoperability. Any value can be encoded as Data, making it essential for on-chain communication.

What is Data?

Data is a tree-like structure that can represent:

  • Integers (I constructor)
  • ByteStrings (B constructor)
  • Lists of Data (List constructor)
  • Maps from Data to Data (Map constructor)
  • Constructors with an integer tag and list of Data fields (Constr constructor)

Think of Data as a universal serialization format similar to JSON, but optimized for blockchain use.

import scalus.builtin.Data import scalus.builtin.Builtins // Creating Data values val intData = Builtins.iData(42) val bytesData = Builtins.bData(hex"deadbeef") val listData = Builtins.listData(List(intData, bytesData)) val mapData = Builtins.mapData(List((intData, bytesData))) val constrData = Builtins.constrData(0, List(intData, bytesData)) // Deconstructing Data val extractedInt: BigInt = Builtins.unIData(intData) val extractedBytes: ByteString = Builtins.unBData(bytesData) val extractedList: List[Data] = Builtins.unListData(listData) val extractedMap: List[(Data, Data)] = Builtins.unMapData(mapData) val (tag, fields) = Builtins.unConstrData(constrData) // Comparison val dataEq = intData == Builtins.iData(42)

Converting to/from Data

Scalus automatically generates ToData and FromData instances for case classes and enums, enabling seamless conversion:

import scalus.builtin.Data.* case class Account(owner: ByteString, balance: BigInt) val account = Account(hex"abc123", 1000) val accountData: Data = account.toData val recovered: Account = FromData.fromData(accountData) val recovered2: Account = accountData.to[Account]

List

Immutable linked lists are the primary collection type.

// Creating lists val empty = List.empty[BigInt] val numbers = List(1, 2, 3, 4, 5) val cons = 0 :: List(1, 2, 3) // prepend element // Operations val head = numbers.head // first element (1) val tail = numbers.tail // rest of list val isEmpty = numbers.isEmpty val length = numbers.length // Higher-order functions val doubled = numbers.map(_ * 2) val evens = numbers.filter(_ % 2 == 0) val sum = numbers.foldLeft(0)(_ + _)

Pair

Pairs (2-tuples) hold exactly two values of potentially different types.

import scalus.builtin.Pair // Creating pairs val pair = Pair(BigInt(42), ByteString.fromHex("deadbeef")) val tuple: (Boolean, Unit) = (true, ()) // Accessing elements val first = pair.fst val second = pair.snd val (a, b) = tuple // destructuring

BLS12-381 Types

Cryptographic elliptic curve types for advanced cryptography and zero-knowledge proofs.

import scalus.builtin.* val g1Point: BLS12_381_G1_Element = ??? // from bytestring val g2Point: BLS12_381_G2_Element = ??? // from bytestring val mlResult: BLS12_381_MlResult = Builtins.bls12_381_millerLoop(g1Point, g2Point)

Type Safety

Scalus ensures type safety at compile time. Type mismatches are caught before deployment:

val valid: BigInt = 42 val invalid: BigInt = "not a number" // Compile error!

This prevents many common smart contract vulnerabilities by catching errors early in the development process.

Last updated on