Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
[package]
name = "simfony"
name = "simplicityhl"
version = "0.1.0"
authors = ["sanket1729 <sanket1729@gmail.com>"]
license = "CC0-1.0"
homepage = "https://github.com/BlockstreamResearch/simfony/"
repository = "https://github.com/BlockstreamResearch/simfony/"
homepage = "https://github.com/BlockstreamResearch/SimplicityHL"
repository = "https://github.com/BlockstreamResearch/SimplicityHL"
description = "Rust-like language that compiles to Simplicity bytecode."
edition = "2021"
rust-version = "1.78.0"

[lib]
name = "simfony"
name = "simplicityhl"
path = "src/lib.rs"

[[bin]]
Expand Down
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Simfony is a high-level language for writing Bitcoin smart contracts.
SimplicityHL is a high-level language for writing Bitcoin smart contracts.

Simfony looks and feels like [Rust](https://www.rust-lang.org). Just how Rust compiles down to assembly language, Simfony compiles down to [Simplicity](https://github.com/BlockstreamResearch/simplicity) bytecode. Developers write Simfony, full nodes execute Simplicity.
SimplicityHL looks and feels like [Rust](https://www.rust-lang.org). Just how Rust compiles down to assembly language, SimplicityHL compiles down to [Simplicity](https://github.com/BlockstreamResearch/simplicity) bytecode. Developers write SimplicityHL, full nodes execute Simplicity.

**Simfony is a work in progress and is not yet ready for production use.**
**SimplicityHL is a work in progress and is not yet ready for production use.**

```rust
let a: u32 = 10;
Expand All @@ -16,49 +16,49 @@ let b = {
assert!(jet::eq_32(b, 7));
```

Take a look at the [example programs](https://github.com/BlockstreamResearch/simfony/tree/master/examples).
Take a look at the [example programs](https://github.com/BlockstreamResearch/SimplicityHL/tree/master/examples).

## MSRV

This crate should compile with any feature combination on **Rust 1.78.0** or higher.

## Simplicity's need for a high-level language

Simplicity introduces a groundbreaking low-level programming language and machine model meticulously crafted for blockchain-based smart contracts. The primary goal is to provide a streamlined and comprehensible foundation that facilitates static analysis and encourages reasoning through formal methods. While the elegance of the language itself is distilled into something as succinct as fitting onto a T-shirt, it's important to note that the simplicity of the language doesn't directly equate to simplicity in the development process. Simfony revolves around demystifying and simplifying the complexities involved in this ecosystem.
Simplicity introduces a groundbreaking low-level programming language and machine model meticulously crafted for blockchain-based smart contracts. The primary goal is to provide a streamlined and comprehensible foundation that facilitates static analysis and encourages reasoning through formal methods. While the elegance of the language itself is distilled into something as succinct as fitting onto a T-shirt, it's important to note that the simplicity of the language doesn't directly equate to simplicity in the development process. SimplicityHL revolves around demystifying and simplifying the complexities involved in this ecosystem.

The distinguishing aspects that set Simplicity apart from conventional programming languages are:

- **Distinct Programming Paradigm**: Simplicity's programming model requires a paradigm shift from conventional programming. It hinges on reasoning about programs in a functional sense with a focus on combinators. This intricacy surpasses even popular functional languages like Haskell, with its own unique challenges.
- **Exceptional Low-Level Nature**: Unlike high-level languages such as JavaScript or Python, Simplicity operates at an extremely low level, resembling assembly languages. This design choice enables easier reasoning about the formal semantics of programs, but is really work on directly.

## Simfony
## SimplicityHL

Simfony is a high-level language that compiles to Simplicity. It maps programming concepts from Simplicity onto programming concepts that developers are more familar with. In particular, Rust is a popular language whose functional aspects fit Simplicity well. Simfony aims to closely resemble Rust.
SimplicityHL is a high-level language that compiles to Simplicity. It maps programming concepts from Simplicity onto programming concepts that developers are more familar with. In particular, Rust is a popular language whose functional aspects fit Simplicity well. SimplicityHL aims to closely resemble Rust.

Just how Rust is compiled to assembly language, Simfony is compiled to Simplicity. Just how writing Rust doesn't necessarily produce the most efficient assembly, writing Simfony doesn't necessarily produce the most efficient Simplicity code. The compilers try to optimize the target code they produce, but manually written target code can be more efficient. On the other hand, a compiled language is much easier to read, write and reason about. Assembly is meant to be consumed by machines while Rust is meant to be consumed by humans. Simplicity is meant to be consumed by Bitcoin full nodes while Simfony is meant to be consumed by Bitcoin developers.
Just how Rust is compiled to assembly language, SimplicityHL is compiled to Simplicity. Just how writing Rust doesn't necessarily produce the most efficient assembly, writing SimplicityHL doesn't necessarily produce the most efficient Simplicity code. The compilers try to optimize the target code they produce, but manually written target code can be more efficient. On the other hand, a compiled language is much easier to read, write and reason about. Assembly is meant to be consumed by machines while Rust is meant to be consumed by humans. Simplicity is meant to be consumed by Bitcoin full nodes while SimplicityHL is meant to be consumed by Bitcoin developers.

## Installation

Clone the repo and build the Simfony compiler using cargo.
Clone the repo and build the SimplicityHL compiler using cargo.

```bash
git clone https://github.com/BlockstreamResearch/simfony.git
cd simfony
git clone https://github.com/BlockstreamResearch/SimplicityHL.git
cd SimplicityHL
cargo build
```

Optionally, install the Simfony compiler using cargo.
Optionally, install the SimplicityHL compiler using cargo.

```bash
cargo install --path .
```

## Usage

The Simfony compiler takes two arguments:
The SimplicityHL compiler takes two arguments:

1. A path to a Simfony program file (`.simf`)
1. A path to a Simfony witness file (`.wit`, optional)
1. A path to a SimplicityHL program file (`.simf`)
1. A path to a SimplicityHL witness file (`.wit`, optional)

The compiler produces a base64-encoded Simplicity program. Witness data will be included if a witness file is provided.

Expand Down
4 changes: 2 additions & 2 deletions bitcoind-tests/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion bitcoind-tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ authors = ["sanket1729 <sanket1729@gmail.com>"]
edition = "2021"

[dependencies]
simfony = { path = ".." }
simplicityhl = { path = ".." }
elementsd = { version = "0.11.0" }
actual-rand = { package = "rand", version = "0.8.4" }
secp256k1 = { version = "0.29.0", features = ["rand-std"] }
2 changes: 1 addition & 1 deletion bitcoind-tests/tests/common/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use elements::hex::FromHex;
use elementsd::bitcoincore_rpc::jsonrpc::serde_json::{json, Value};
use elementsd::bitcoind::bitcoincore_rpc::RpcApi;
use elementsd::ElementsD;
use simfony::elements;
use simplicityhl::elements;

// We are not using pegins right now, but it might be required in case in future
// if we extend the tests to check pegins etc.
Expand Down
18 changes: 9 additions & 9 deletions bitcoind-tests/tests/common/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ use elements::pset::PartiallySignedTransaction as Psbt;
use elements::{confidential, secp256k1_zkp as secp256k1};
use elementsd::ElementsD;
use secp256k1::XOnlyPublicKey;
use simfony::{elements, simplicity};
use simplicity::jet::elements::{ElementsEnv, ElementsUtxo};
use simplicityhl::{elements, simplicity};

use crate::common::daemon::Call;

type FnWitness = fn([u8; 32]) -> simfony::WitnessValues;
type FnWitness = fn([u8; 32]) -> simplicityhl::WitnessValues;

#[derive(Clone)]
pub struct TestCase<'a> {
pub name: &'static str,
template: Option<simfony::TemplateProgram>,
compiled: Option<simfony::CompiledProgram>,
template: Option<simplicityhl::TemplateProgram>,
compiled: Option<simplicityhl::CompiledProgram>,
witness: FnWitness,
lock_time: elements::LockTime,
sequence: elements::Sequence,
Expand Down Expand Up @@ -53,7 +53,7 @@ impl<'a> TestCase<'a> {

pub fn program_path<P: AsRef<std::path::Path>>(mut self, path: P) -> Self {
let text = std::fs::read_to_string(path).expect("path should be readable");
let compiled = simfony::CompiledProgram::new(text.as_str(), simfony::Arguments::default(), false)
let compiled = simplicityhl::CompiledProgram::new(text.as_str(), simplicityhl::Arguments::default(), false)
.expect("program should compile");
self.compiled = Some(compiled);
self
Expand All @@ -62,12 +62,12 @@ impl<'a> TestCase<'a> {
pub fn template_path<P: AsRef<std::path::Path>>(mut self, path: P) -> Self {
let text = std::fs::read_to_string(path).expect("path should be readable");
let template =
simfony::TemplateProgram::new(text.as_str()).expect("program should compile");
simplicityhl::TemplateProgram::new(text.as_str()).expect("program should compile");
self.template = Some(template);
self
}

pub fn arguments(mut self, arguments: simfony::Arguments) -> Self {
pub fn arguments(mut self, arguments: simplicityhl::Arguments) -> Self {
let compiled = self
.template
.as_ref()
Expand Down Expand Up @@ -220,6 +220,6 @@ impl<'a> TestCase<'a> {
}
}

fn empty_witness(_sighash_all: [u8; 32]) -> simfony::WitnessValues {
simfony::WitnessValues::default()
fn empty_witness(_sighash_all: [u8; 32]) -> simplicityhl::WitnessValues {
simplicityhl::WitnessValues::default()
}
4 changes: 2 additions & 2 deletions bitcoind-tests/tests/common/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ pub fn sign_schnorr(secret_key: u32, message: [u8; 32]) -> [u8; 64] {
key_pair.sign_schnorr(message).serialize()
}

pub fn xonly_public_key(secret_key: u32) -> simfony::num::U256 {
pub fn xonly_public_key(secret_key: u32) -> simplicityhl::num::U256 {
let key_pair = key_pair(secret_key);
let bytes = key_pair.x_only_public_key().0.serialize();
simfony::num::U256::from_byte_array(bytes)
simplicityhl::num::U256::from_byte_array(bytes)
}
28 changes: 14 additions & 14 deletions bitcoind-tests/tests/spend_utxo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use std::collections::HashMap;
use elements::hashes::Hash;
use elements::secp256k1_zkp as secp256k1;
use secp256k1::hashes::{sha256, HashEngine};
use simfony::str::WitnessName;
use simfony::types::TypeConstructible;
use simfony::value::ValueConstructible;
use simfony::{elements, ResolvedType, Value};
use simplicityhl::str::WitnessName;
use simplicityhl::types::TypeConstructible;
use simplicityhl::value::ValueConstructible;
use simplicityhl::{elements, ResolvedType, Value};

mod common;
use common::daemon::{self, Call};
Expand Down Expand Up @@ -49,7 +49,7 @@ fn spend_utxo() {
}
}

fn hodl_vault(sighash_all: [u8; 32]) -> simfony::WitnessValues {
fn hodl_vault(sighash_all: [u8; 32]) -> simplicityhl::WitnessValues {
let mut witness_values = HashMap::new();
let oracle_height = 1000;
witness_values.insert(
Expand All @@ -73,24 +73,24 @@ fn hodl_vault(sighash_all: [u8; 32]) -> simfony::WitnessValues {
WitnessName::from_str_unchecked("OWNER_SIG"),
Value::byte_array(util::sign_schnorr(2, sighash_all)),
);
simfony::WitnessValues::from(witness_values)
simplicityhl::WitnessValues::from(witness_values)
}

fn p2pk_args() -> simfony::Arguments {
simfony::Arguments::from(HashMap::from([(
fn p2pk_args() -> simplicityhl::Arguments {
simplicityhl::Arguments::from(HashMap::from([(
WitnessName::from_str_unchecked("ALICE_PUBLIC_KEY"),
Value::u256(util::xonly_public_key(1)),
)]))
}

fn p2pk(sighash_all: [u8; 32]) -> simfony::WitnessValues {
simfony::WitnessValues::from(HashMap::from([(
fn p2pk(sighash_all: [u8; 32]) -> simplicityhl::WitnessValues {
simplicityhl::WitnessValues::from(HashMap::from([(
WitnessName::from_str_unchecked("ALICE_SIGNATURE"),
Value::byte_array(util::sign_schnorr(1, sighash_all)),
)]))
}

fn p2pkh(sighash_all: [u8; 32]) -> simfony::WitnessValues {
fn p2pkh(sighash_all: [u8; 32]) -> simplicityhl::WitnessValues {
let mut witness_values = HashMap::new();
witness_values.insert(
WitnessName::from_str_unchecked("PK"),
Expand All @@ -100,16 +100,16 @@ fn p2pkh(sighash_all: [u8; 32]) -> simfony::WitnessValues {
WitnessName::from_str_unchecked("SIG"),
Value::byte_array(util::sign_schnorr(1, sighash_all)),
);
simfony::WitnessValues::from(witness_values)
simplicityhl::WitnessValues::from(witness_values)
}

fn p2ms(sighash_all: [u8; 32]) -> simfony::WitnessValues {
fn p2ms(sighash_all: [u8; 32]) -> simplicityhl::WitnessValues {
let mut witness_values = HashMap::new();
let sig1 = Value::some(Value::byte_array(util::sign_schnorr(1, sighash_all)));
let sig2 = Value::none(ResolvedType::byte_array(64));
let sig3 = Value::some(Value::byte_array(util::sign_schnorr(3, sighash_all)));
let ty = sig1.ty().clone();
let maybe_sigs = Value::array([sig1, sig2, sig3], ty);
witness_values.insert(WitnessName::from_str_unchecked("MAYBE_SIGS"), maybe_sigs);
simfony::WitnessValues::from(witness_values)
simplicityhl::WitnessValues::from(witness_values)
}
2 changes: 1 addition & 1 deletion book/book.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ authors = ["Christian Lewe"]
language = "en"
multilingual = false
src = "src"
title = "The Simfony Programming Language"
title = "The SimplicityHL Programming Language"
8 changes: 4 additions & 4 deletions book/src/function.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ let z: u32 = add(40, 2);

## No early returns

Simfony has no support for an early return via a "return" keyword.
SimplicityHL has no support for an early return via a "return" keyword.
The only branching that is available is via [match expressions](./match_expression.md).

## No recursion

Simfony has no support for recursive function calls.
SimplicityHL has no support for recursive function calls.
A function can be called inside a function body if it has been defined before.
This means that a function cannot call itself.
Loops, where `f` calls `g` and `g` calls `f`, are also impossible.
Expand Down Expand Up @@ -75,7 +75,7 @@ fn g() -> u32 {

## Main function

The `main` function is the entry point of each Simfony program.
The `main` function is the entry point of each SimplicityHL program.
Running a program means running its `main` function.
Other functions are called from the `main` function.

Expand All @@ -86,7 +86,7 @@ fn main() {
```

The `main` function is a reserved name and must exist in every program.
Simfony programs are always "binaries".
SimplicityHL programs are always "binaries".
There is no support for "libraries".

## Jets
Expand Down
8 changes: 4 additions & 4 deletions book/src/introduction.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Introduction

Simfony is a high-level language for writing Bitcoin smart contracts.
In other words, Simfony is a language for expressing spending conditions of UTXOs on the Bitcoin blockchain.
SimplicityHL is a high-level language for writing Bitcoin smart contracts.
In other words, SimplicityHL is a language for expressing spending conditions of UTXOs on the Bitcoin blockchain.

Simfony looks and feels like [Rust](https://www.rust-lang.org/).
Developers write Simfony, Bitcoin full nodes run Simplicity.
SimplicityHL looks and feels like [Rust](https://www.rust-lang.org/).
Developers write SimplicityHL, Bitcoin full nodes run Simplicity.
4 changes: 2 additions & 2 deletions book/src/let_statement.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ Variables can be assigned to the output value of any expression, such as functio

## Explicit typing

In Simfony, the type of a defined variable **always** has to be written.
In SimplicityHL, the type of a defined variable **always** has to be written.
This is different from Rust, which has better type inference.

## Immutability

Simfony variables are **always** immutable.
SimplicityHL variables are **always** immutable.
There are no mutable variables.

## Redefinition and scoping
Expand Down
Loading
Loading