Scalus SBT Plugin
The ScalusBlueprintPlugin adds two sbt tasks to your project: blueprint for embedding
CIP-57 blueprint JSON files into JARs, and deploy
for publishing a contract as a reference script UTxO via Blockfrost.
Setup
project/plugins.sbt:
addSbtPlugin("org.scalus" % "scalus-sbt-plugin" % "<scalus-version>")build.sbt:
lazy val myProject = (project in file("."))
.enablePlugins(ScalusBlueprintPlugin)
.settings(
scalaVersion := "3.3.7",
addCompilerPlugin("org.scalus" % "scalus-plugin" % "<scalus-version>" cross CrossVersion.full),
libraryDependencies ++= Seq(
"org.scalus" %% "scalus" % "<scalus-version>",
"org.scalus" %% "scalus-cardano-ledger" % "<scalus-version>",
),
)The compiler plugin discovers objects extending Contract automatically. Each one needs
a compiled validator and a blueprint:
@Compile
object MyValidator extends Validator {
inline override def spend(
datum: Option[Data], redeemer: Data, tx: TxInfo, ownRef: TxOutRef
): Unit = {
val owner = datum.getOrFail("No datum").to[PubKeyHash]
require(tx.signatories.contains(owner), "Not signed by owner")
}
}
object MyContract extends Contract {
private given Options = Options.release
lazy val compiled = PlutusV3.compile(MyValidator.validate)
lazy val blueprint = Blueprint.plutusV3[PubKeyHash, Unit](
title = "My Validator",
description = "Owner-signed spending validator",
version = "1.0.0",
license = None,
compiled = compiled
)
}Blueprint Generation
When a Cardano smart contract is deployed on-chain, only its script hash is visible. How do you verify that a given source code produced that hash?
The verifiable artifact is the JAR. The blueprint task generates a CIP-57 blueprint JSON
for every Contract in the project and writes it to META-INF/scalus/blueprints/. Each
blueprint contains the compiledCode (CBOR hex) and hash (script hash), so anyone with the
JAR, or anyone who can build it from source, can independently confirm the on-chain script
hash.
sbt blueprint package[info] Wrote META-INF/scalus/blueprints/MyContract.jsonsbt package is the standard sbt command for producing a JAR. A JAR is just a ZIP archive, so
standard tools work to inspect it:
unzip -p my-project.jar META-INF/scalus/blueprints/MyContract.jsonThe hash field is the standard Cardano script hash: blake2b_224(0x03 || compiledCode).
If you have the JAR, you can verify that this hash matches what’s deployed on-chain.
No Scalus installation or JVM required for verification, just the JAR and a blake2b implementation.
Deploying Contracts
The deploy task creates a reference script UTxO from a Contract object. It extracts the
compiled script, attaches it to a new UTxO, builds and signs the transaction, and submits it
via Blockfrost.
sbt "deploy MyContract --network preprod --blockfrost-key <key> --mnemonic '<24 words>' --address <bech32-address>"The first argument is the simple name of your Contract object. Named flags:
| Flag | Env Variable | Default | Description |
|---|---|---|---|
--network | CARDANO_NETWORK | preview | preview, preprod, or mainnet |
--blockfrost-key | BLOCKFROST_API_KEY | — | Blockfrost API key |
--mnemonic | CARDANO_MNEMONIC | — | BIP-39 mnemonic phrase |
--address | — | — | Bech32 address for the reference script UTXO |
CLI flags take precedence over environment variables. Using env vars avoids secrets in shell history:
export BLOCKFROST_API_KEY=preprodXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
export CARDANO_MNEMONIC="word1 word2 ... word24"
export CARDANO_NETWORK=preprod
sbt "deploy MyContract --address addr_test1q..."Example output:
[info] Deploying contract 'MyContract' to preprod...
[info] Tx e484fdac... submitted successfully
[info] Deployed successfully! Transaction hash: e484fdac...What’s Next?
- Working with Contract — Reference the deployed script from off-chain dapp code
- Building Transactions — Spend from your reference script with TxBuilder