Skip to content

BlockstreamResearch/rust-simplicity

Repository files navigation

Crate Info CC0 1.0 Universal Licensed CI Status API Docs

rust-simplicity

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.

rust-simplicity

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.

Installation

To use rust-simplicity, this to your Cargo.toml:

[dependencies]
simplicity-lang = "0.5"

Quick Start

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();

Relationship to libsimplicity

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

Further Reading

Contributing

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!

Minimum Supported Rust Version

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.

Updating libsimplicity

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.

Benchmarking

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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 6