Compiling Smart Contracts
Basic Compilation
Use PlutusV3.compile to transform your Scala validator into a Plutus script:
import scalus.compiler.Options
import scalus.uplc.PlutusV3
// Compile your validator to Plutus V3
val compiled = PlutusV3.compile(MyValidator.validate)
// Get the script for use in transactions
val script = compiled.script
val scriptHex = compiled.program.doubleCborHexThe compilation flow: PlutusV3.compile takes a validator entry point and produces a PlutusV3[A] object containing the script, its hash, and address.
Choosing a Plutus Version
Select the appropriate version for your use case:
import scalus.uplc.{PlutusV1, PlutusV2, PlutusV3}
// Plutus V3 (recommended for new validators)
val compiledV3 = PlutusV3.compile(MyValidator.validate)
// Plutus V2 (for reference inputs, inline datums)
val compiledV2 = PlutusV2.compile(MyValidator.validate)
// Plutus V1 (legacy)
val compiledV1 = PlutusV1.compile(MyValidator.validate)Compilation Options
Control error traces and optimizations via Options:
import scalus.compiler.Options
// Development: Include error traces for debugging
given Options = Options.debug
// Production: Minimal script size
given Options = Options.releaseOptions.debug: Adds error location information (easier debugging, larger script)Options.release: Minimal script size (for production)
You can also enable error traces on a compiled validator:
val compiled = PlutusV3.compile(MyValidator.validate)
// Add error traces for debugging
val withTraces = compiled.withErrorTracesComplete Example
import scalus.*
import scalus.uplc.builtin.Data
import scalus.compiler.Options
import scalus.cardano.onchain.plutus.v3.*
import scalus.uplc.PlutusV3
@Compile
object MyValidator {
inline def validate(scData: Data): Unit = {
val ctx = scData.to[ScriptContext]
ctx.scriptInfo match
case ScriptInfo.SpendingScript(_, datum) =>
require(ctx.txInfo.signatories.nonEmpty, "No signatories")
case _ => fail("Must be spending")
}
}
object MyContract {
private given Options = Options.release
lazy val compiled = PlutusV3.compile(MyValidator.validate)
}
// Get hex for use in transactions
val scriptHex = MyContract.compiled.program.doubleCborHexEncoding Options
UPLC programs can be encoded in several formats:
val program = compiled.program
// Flat encoding (binary format)
val flatEncoded = program.flatEncoded
// CBOR encoding (wraps Flat)
val cborEncoded = program.cborEncoded
// Double CBOR encoding (standard for Cardano transactions)
val doubleCborEncoded = program.doubleCborEncoded
// Hex string of double CBOR (most commonly used in APIs)
val hexString = program.doubleCborHexWhat’s Next?
Once your validator compiles, you’re ready to use it in a DApp:
- Working with Contract — Set compilation options, generate CIP-57 blueprints, and get script addresses
- First Contract Transaction — Lock funds at a script address and spend them with a redeemer
- Building Transactions — Build and submit simple ADA transfers using TxBuilder
- HTLC Tutorial — End-to-end example: contract, transactions, testing, and deployment
Last updated on