This is the official Rust library of the Simplicity Language.
Simplicity is a low-level, typed functional language designed to be a drop-in alternative for Bitcoin's Tapscript. It offers static resource bounds and has a formal specification (in Rocq) which allows the creation of machine-checkable proofs of program behavior.
It is currently deployed on Blockstream's Liquid, which is a sidechain resembling Bitcoin in many ways; but which differs in many Script-relevant ways (e.g. supporting multiple assets and using Confidential Transactions). We expect by the end of 2025 to directly support Bitcoin, so that Simplicity can be used on a custom regtest chain.
Simplicity is a very low-level language. If you are simply looking to develop with the language, you may wish to use SimplicityHL instead.
The goal of rust-simplicity is to provide the tools to encode, decode, analyze, construct and manipulate Simplicity programs at all stages of development. These stages are:
- construction, which is when a program is incomplete, and consists of a set of
"Simplicity expressions" intended to be assembled into a full program. Such expressions
are represented by the
ConstructNode
type. - commitment, which is when a program is complete but has not been satisfied. At this
point, it is possible to derive addressses and receive funds to them, but to spend
those funds requires the generation of witness data. Such programs are represented
by
CommitNode
- redemption, which is when a program has witness data attached. This is the only
point at which a program may appear explicitly on the blockchain, and the only point
at which the program has a canonical encoding. Such programs are represented by
RedeemNode
Generally speaking, the process of producing a Simplicity program involves moving from one node type to the next.
To use rust-simplicity, this to your Cargo.toml:
[dependencies]
simplicity-lang = "0.5"
use simplicity::node::CoreConstructible;
use simplicity::types::Context;
use simplicity::{ConstructNode, Core};
use std::sync::Arc;
// Create a trivial Simplicity program
let ctx = Context::new();
let program = Arc::<ConstructNode<Core>>::unit(&ctx);
// Encode the program to bytes
let encoded = simplicity::bit_encoding::write_to_vec(|w| {
program.encode_without_witness(w)
}).unwrap();
This Rust library provides extensive tools for program construction and analysis, while libsimplicity is a minimal C library focused solely on decoding, validating, and executing programs in blockchain consensus code.
rust-simplicity includes a vendored copy of libsimplicity and uses it for:
- cryptographic and other "heavy" operations through optimized C jets
- cross-validating the C and Rust Bit Machine implementations
The libsimplicity repository also contains:
- A reference implementation written in Haskell
- A Rocq (Coq) implementation for formal verification and machine-checkable proofs
- API Documentation - Complete API reference
- Simplicity Tech Report - Full informal language specification
- Simplicity Website - Official language homepage
- libsimplicity - Reference implementation
The goals of this library are to support the low-level Simplicity language, and to provide a basis for the SimplicityHL language implementation. If you wish to work on high-level programming language abstractions, you may want to visit that repo instead.
Having said that, contributions are welcome! This library is in its early stages and undergoing rapid development. We especially welcome improvements in:
- representing and displaying type inference information and errors
- representing and displaying information about Simplicity (sub)expressions; usefully and uniquely specifying subexpressions within larger expressions
- improvements to the debuggability and introspection of the Bit Machine, the Simplicity interpreter.
- testing, especially of programs that exhibit extreme behavior; improving test infrastructure and CI
- improving the ergonomics and reliability of our vendoring scripts (see below)
- documentation!
The MSRV of this crate is 1.78.0. For now we will not increase this without a major version bump, though as the library matures we may change that policy.
This library includes a vendored copy of the libsimplicity C library, as well as
files generated by the GenRustJets
utility from the libsimplicity Haskell library.
These files are clearly marked as being autogenerated, and may not be directly
changed.
Instead, to update this code you must use the included vendor-simplicity.sh
and
update_jets.sh
scripts.
update_jets.sh
requires the user has cabal
and all dependencies of the libsimplicity
Haskell library. Instructions for those can be found in the simplicity repository.
There are two sets of benchmarks in this codebase. First, there is the jets-bench
sub-crate which uses criterion to collect statistics about jet performance. These
benchmarks are specifically targeted at the C jets and are intended to estimate
consensus costs.
See jets-bench/README.md
for information about running these benchmarks.
The second set of benchmarks are benchmarks for this library's performance. These are used to track performance of this library itself. These can be run with
RUSTFLAGS=--cfg=bench cargo +nightly bench
The custom cfg
flag is used to prevent nightly-only code from polluting ordinary
code.