SCL Contract Overview
SCL contracts are small, deterministic programs. You write one contract per file. You anchor the compiled contract to a Bitcoin UTXO, and you verify every state change against that anchor plus Bitcoin-derived context.
What "deterministic" means here
- No randomness. No system time.
- No unbounded control flow; SCL is intentionally not Turing complete.
- Same payload + same anchor + same Bitcoin context → the same result on every honest node.
- Disagreements are objective: invalid calls are dropped, not "outvoted."
What lives on Bitcoin vs off-chain
- On Bitcoin: the deploy commitment (a hash of the compiled bytecode) and a commitment for every call (a protocol stamp of the signed call envelope).
- Off-chain: mutable state (balances, ownership, listings, pools), maintained by nodes and provable against the anchors.
SCL's bounded behaviour and non-Turing-complete, deterministic core gives convergent replay, and is cheap to verify at scale.
Install the compiler
You need a stable Rust toolchain with Cargo.
git clone https://github.com/Dark-Fusion-Protocol/scl-compiler
cd scl-compiler
cargo build --release
The binary is created at:
target/release/sclc
Compile
The CLI is positional:
sclc compile <contract.scl> [options]
A minimal contract you can compile now:
contract Hello {
greeting: Str;
fn init(who: Str) {
greeting = who;
}
fn greet() {
PRINT("hello:", greeting);
return 1;
}
}
Compile it, emitting bytecode, ABI, and metadata in one JSON blob:
sclc compile hello.scl --json > hello.artifact.json
Deploy
Deployment is a two-step act: commit the contract on Bitcoin, then register the artifact with an SCL node.
- Anchor on Bitcoin. Publish the contract commitment in a Bitcoin transaction, as specified by the protocol.
- Register with a node. Send the compiled artifact to the node's deploy endpoint, referencing the anchoring transaction:
curl -X POST http://localhost:8080/deploy_contract \
-H 'content-type: application/json' \
-d '{
"txid": "<bitcoin-txid-with-your-commitment>",
"bytecode": "<hex bytecode>",
"abi": [ ... ],
"function_offsets": { ... },
"function_offset_to_locals": { ... },
"constants": [ ... ]
}'
The bytecode, abi, function_offsets, function_offset_to_locals, and constants fields come straight out of sclc compile --json.
Call a function
Calls are signed call envelopes, anchored on Bitcoin and submitted to a node:
- Build and sign the envelope (contract ID, function, arguments, caller key, call ID, signature). The wallet SDKs and the browser signer do this for you.
- Anchor it: broadcast a Bitcoin transaction that carries the envelope's protocol stamp and spends the outpoint the envelope names.
- Submit to a node:
curl -X POST http://localhost:8080/contract_call \
-H 'content-type: application/json' \
-d '{
"txid": "<bitcoin-txid-of-the-anchoring-tx>",
"contract_id": "<contract-id>",
"payload": "<base64 Borsh-encoded CallEnvelope>"
}'
Check the call's status:
curl http://localhost:8080/contract_call/<txid>/status
The node validates the envelope's anchor binding at intake and again at confirmation, then applies the deterministic transition once the Bitcoin transaction confirms. See Settlement and Validation for the full pipeline, and the Node API Reference for every endpoint.
Do not assume this REST surface is stable. Treat it as the current implementation, not a long-term public API.
Standards and state classification
Contracts can declare conformance to versioned interfaces like utxo_token_v1, unlocking enforced standard shapes, wallet and Lightning legibility, and compact on-chain operations. See Interfaces for the syntax and guarantees.
Interface functions are also classified as touching global or partitioned state, which is what keeps one user's withheld data from ever freezing another user's assets. See Global and Partitioned State.
Next Steps
Read Language Basics to see the syntax you can use today. Then see Built-ins for what is implemented end to end. For how execution is metered and what it costs, see Fuel and Emissions.