Skip to content

Commit

Permalink
Update README with Miniscript link and description, and improve satis…
Browse files Browse the repository at this point in the history
…fier documentation adding a link to the playground
  • Loading branch information
landabaso committed Dec 29, 2022
1 parent 778d47f commit 78cade8
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 8 deletions.
52 changes: 46 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Bitcoin Miniscript

This project is a JavaScript implementation of Bitcoin Miniscript, a high-level language for describing Bitcoin spending conditions.
This project is a JavaScript implementation of [Bitcoin Miniscript](https://bitcoin.sipa.be/miniscript/), a high-level language for describing Bitcoin spending conditions.

It includes a transpilation of [Peter Wuille's C++ code](https://github.com/sipa/miniscript) for compiling spending policies into Miniscript and Bitcoin scripts, as well as a novel Miniscript Satisfier for generating explicit witness scripts that are decoupled from the tx signer.
It includes a novel Miniscript Satisfier for generating explicit witness scripts that are decoupled from the tx signer, as well as a transpilation of [Peter Wuille's C++ code](https://github.com/sipa/miniscript) for compiling spending policies into Miniscript and Bitcoin scripts.

## Features

Expand All @@ -11,11 +11,13 @@ It includes a transpilation of [Peter Wuille's C++ code](https://github.com/sipa
- The Miniscript Satisfier is able to generate explicit witness scripts from Miniscripts using variables, such as `pk(key)`.

For example, Miniscript `and_v(v:pk(key),after(10))` can be satisfied with `[{ witness: '<sig(key)>', nLockTime: 10 }]`.

- The ability to generate different satisfactions depending on the presence of `unknowns`.

For example, Miniscript `c:and_v(or_c(pk(key1),v:ripemd160(H)),pk_k(key2))` can be satisfied with: `[{ witness: '<sig(key2)> <ripemd160_preimage(H)> 0' }]`.

However, if `unknowns: ['<ripemd160_preimage(H)>']` is set, then the Miniscript can be satisfied with: `[{ witness: '<sig(key2)> <sig(key1)>' }]` because this solution can no longer be considered malleable, given then assumption that an attacker does not have access to the preimage.

- Thoroughly tested.

## Installation
Expand All @@ -28,6 +30,8 @@ npm install @bitcoinerlab/miniscript

## Usage

You can test the examples in this section using the online playground demo available at https://bitcoinerlab.com/modules/miniscript.

### Compiling Policies into Miniscript and Bitcoin script

To compile a Policy into a Miniscript and Bitcoin ASM, you can use the `compilePolicy` function:
Expand All @@ -39,6 +43,7 @@ const policy = 'or(and(pk(A),older(8640)),pk(B))';

const { miniscript, asm, issane } = compilePolicy(policy);
```

`issane` is a boolean that indicates whether the Miniscript is valid and follows the consensus and standardness rules for Bitcoin scripts. A sane Miniscript should have non-malleable solutions, not mix different timelock units on a single branch of the script, and not contain duplicate keys. In other words, it should be a well-formed and standards-compliant script that can be safely used in transactions.

### Compiling Miniscript into Bitcoin script
Expand All @@ -63,11 +68,27 @@ const { satisfier } = require('@bitcoinerlab/miniscript');
const miniscript =
'c:or_i(andor(c:pk_h(key1),pk_h(key2),pk_h(key3)),pk_k(key4))';

const satisfactions = satisfier(miniscript);
const { nonMalleableSats, malleableSats } = satisfier(miniscript);
```
`satisfier` makes sure that output `satisfactions` are non-malleable and that the `miniscript` is sane.

You can also set `unknowns`:
`satisfier` makes sure that output `satisfactions` are non-malleable and that the `miniscript` is sane by itself and it returns an object with keys:

- `nonMalleableSats`: an array of objects representing good, non-malleable witnesses.
- `malleableSats`: an array of objects representing malleable witnesses that should not be used.

In the example above `nonMalleableSats` is:

```javascript
nonMalleableSats: [
{witness: "<sig(key4)> 0"}
{witness: "<sig(key3)> <key3> 0 <key1> 1"}
{witness: "<sig(key2)> <key2> <sig(key1)> <key1> 1"}
]
```

Where satisfactions are ordered in ascending Weight Unit size.

In addition, `unknowns` can be set with the pieces of information the user does not have, f.ex., `<sig(key)>` or `<ripemd160_preimage(H)>`:

```javascript
const { satisfier } = require('@bitcoinerlab/miniscript');
Expand All @@ -76,9 +97,28 @@ const miniscript =
'c:or_i(andor(c:pk_h(key1),pk_h(key2),pk_h(key3)),pk_k(key4))';
const unknowns = ['<sig(key1)>', '<sig(key2)>'];

const satisfactions = satisfier(miniscript, unknowns);
const { nonMalleableSats, malleableSats, unknownSats } = satisfier(
miniscript,
unknowns
);
```

When passing `unknowns`, `satisfier` returns an addition object key: `{ unknownSats }`with an array of objects representing satisfactions that containt some of the `unknown` pieces of information:

```javascript
nonMalleableSats: [
{witness: "<sig(key4)> 0"}
{witness: "<sig(key3)> <key3> 0 <key1> 1"}
]
unknownSats: [ {witness: "<sig(key2)> <key2> <sig(key1)> <key1> 1"} ]
```

The objects returned in the `nonMalleableSats`, `malleableSats` and `unknownSats` arrays consist of the following properties:

- `witness`: a string with the witness script.
- `nSequence`: an integer representing the nSequence value, if needed.
- `nLockTime`: an integer representing the nLockTime value, if needed.

## Authors and Contributors

The project was initially developed and is currently maintained by [Jose-Luis Landabaso](https://github.com/landabaso). Contributions and help from other developers are welcome.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"asm",
"descriptors"
],
"homepage": "https://bitcoinerlab.com/miniscript",
"version": "1.0.2",
"homepage": "https://bitcoinerlab.com/modules/miniscript",
"version": "1.0.3",
"description": "Bitcoin Miniscript, a high-level language for describing Bitcoin spending conditions. It includes a Policy and Miniscript compiler, as well as a novel Satisfier for generating expressive witness scripts.",
"main": "dist/index.js",
"scripts": {
Expand Down

0 comments on commit 78cade8

Please sign in to comment.