Skip to content

Simplicity (draft)

A typed, combinator-based, smart contract language for Bitcoin-like blockchains.

Live on Liquid mainnet since July 2025

Get Started Read the Docs

Simplicity is a low-level smart contract language for Bitcoin-like blockchains, built on a small set of functional combinators rather than a growing opcode set. Programs are statically analyzable: every contract has a resource cost that's known before you fund it, and the language's formal semantics support machine-checked proofs of contract behavior.

You write contracts in SimplicityHL, a higher-level language with Rust-like syntax that compiles down to Simplicity.

Simplicity has been running in production on Liquid mainnet since July 2025. The tutorials on this site currently target Liquid testnet for learning purposes; production deployments run on mainnet.

Why Simplicity

  • Formally specified

    Simplicity's semantics are formally defined and suitable for machine-checked proofs, giving high assurance that the implementation matches the specification.

  • Predictable execution cost

    Every program has a statically bounded cost, known before you fund a transaction — no surprise fees, no out-of-gas failures.

  • Introspection and covenants

    Programs can inspect the proposed transaction's inputs and outputs, enabling covenants that enforce multi-step spending policies directly on-chain.

  • A narrower attack surface

    No loops, no unbounded recursion, fully deterministic evaluation. Broad classes of runtime failure are eliminated by construction.

Write in a language you already know

You can use SimplicityHL, a high-level language with a clean, Rust-like syntax. This abstracts away low-level complexity, making it straightforward to write clear and reliable financial contracts with minimal code.

Hash Time-Locked Contract
/*
 * The recipient can spend the coins by providing the secret preimage of a hash.
 * The sender can cancel the transfer after a fixed block height.
 *
 * HTLCs enable two-way payment channels and multi-hop payments,
 * such as on the Lightning network.
 */
fn sha2(string: u256) -> u256 {
    let hasher: Ctx8 = jet::sha_256_ctx_8_init();
    let hasher: Ctx8 = jet::sha_256_ctx_8_add_32(hasher, string);
    jet::sha_256_ctx_8_finalize(hasher)
}

fn checksig(pk: Pubkey, sig: Signature) {
    let msg: u256 = jet::sig_all_hash();
    jet::bip_0340_verify((pk, msg), sig);
}

fn complete_spend(preimage: u256, recipient_sig: Signature) {
    let hash: u256 = sha2(preimage);
    let expected_hash: u256 = 0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925;
    assert!(jet::eq_256(hash, expected_hash));
    let recipient_pk: Pubkey = 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798;
    checksig(recipient_pk, recipient_sig);
}

fn cancel_spend(sender_sig: Signature) {
    let timeout: Height = 1000;
    jet::check_lock_height(timeout);
    let sender_pk: Pubkey = 0xc6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5;
    checksig(sender_pk, sender_sig)
}

fn main() {
    match witness::COMPLETE_OR_CANCEL {
        Left(preimage_sig: (u256, Signature)) => {
            let (preimage, recipient_sig): (u256, Signature) = preimage_sig;
            complete_spend(preimage, recipient_sig);
        },
        Right(sender_sig: Signature) => cancel_spend(sender_sig),
    }
}