Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Templates 000,001,002 Submission #11

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
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
Empty file added .codespell-ignore
Empty file.
Empty file added .codespellrc
Empty file.
56 changes: 56 additions & 0 deletions .github/workflows/codespell.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# This is a basic workflow to help you get started with Actions
name: codespell

# Controls when the action will run.
on: [push, pull_request]

jobs:

ubuntu-site-matrix:
name: github-workspace
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
steps:
- uses: styfle/cancel-workflow-action@0.11.0
if: ${{ !env.ACT }}
with:
access_token: ${{ github.token }}
- uses: actions/checkout@v3
with:
depth: '2'
submodules: 'true'
set-safe-directory: 'true'
- name: printenv
run: |
printenv
- name: install-codespell-asciidoctor
run: |
export DEBIAN_FRONTEND=noninteractive
sudo apt list --upgradable
sudo apt upgrade -y
sudo apt update -y
sudo apt install apt-utils asciidoctor python3-pip golang-go sed -y
pip3 install -U codespell
- name: markdown-syntax
if: ${{ !env.ACT }}
run: |
git init
git grep -n --color $'\r' -- "*.md" && \
echo "^ Possible Windows style line ending detected. Please use Unix style line endings (\n)." && exit 0 || true
git grep -n --color ' $' -- "*.md" && echo "^ Trailing space detected at end of line. Please remove." && exit 0 || true
git grep -n --color $'\t' -- "*.md" && echo "^ Use of tabs detected. Please use space for indentation." && exit 0 || true
git grep -iE -n --color '(^| )(\w+) \2(\.|,|:|;| |$)' -- "*.md" && \
echo "^ Detected lexical illusion in the form of a duplicated word. Please correct." && exit 0 || true
for FILE in $(git ls-files -- "*.md"); do if [[ $(tail -c1 $FILE) != "" ]]; then echo "File ${FILE} does not end with a newline character (\n)."; exit 0; fi; done
git grep "" -- "*.md" | uniq -c | grep -1 "^ [2-9] " | cut -b9- | sed 's/:$/:[more-than-one-blank-line-here-please-remove]/' | \
grep ":" && echo "^ Multiple blank lines detected. Please use only one blank line between paragraphs." && exit 0 || true
- name: codespell-md
if: ${{ !env.ACT }}
run: |
codespell --config .codespellrc --ignore-words .codespell-ignore $(git ls-files -- "*.md")
- name: codespell-html
if: ${{ !env.ACT }}
run: |
codespell --config .codespellrc --ignore-words .codespell-ignore $(git ls-files -- "*.html")
50 changes: 39 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
# Miniscript Templates

|[![](https://avatars.githubusercontent.com/u/7424983?s=30)](https://github.com/Blockstream/miniscript-templates)|[000](mint-000.md)|[001](mint-001.md)|[002](mint-002.md)|
|----------|----------|----------|----------|

## About

[Miniscript](https://bitcoin.sipa.be/miniscript/) is a language for composing Bitcoin Scripts in a structured way, facilitating analysis, composition, and generic signing. It's a simplified, composable subset of Bitcoin's Script language. Developed to overcome limitations in writing complex spending conditions directly in Bitcoin Script, it enables formal verification and offers a more human-friendly interface.
[MiniScript](https://bitcoin.sipa.be/miniscript/) is a language for
composing Bitcoin [Script](https://en.bitcoin.it/wiki/Script) in a
structured way, facilitating analysis, composition, and generic signing.
It\'s a simplified, composable subset of the Bitcoin
[Script](https://en.bitcoin.it/wiki/Script) language. Developed to
overcome limitations in writing complex spending conditions directly in
Bitcoin [Script](https://en.bitcoin.it/wiki/Script), it enables formal
verification and offers a more human-friendly interface.

## Objectives

1. Each `MinT` (MiniScript Template) [^mint] [^mintt] will provide a common MiniScript policy.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi

Nice effort, being able to abstract policies/Miniscripts from users and still give them access to its power is very much needed.

Let me know if I should open an issue instead, I was not sure if I should comment here on the approved PR or open an issue.

provide a common MiniScript policy.

A policy can be compiled to many different Miniscripts that encode the same semantics, and the output of the policy compliation can change between compilers and even between compiler versions.

Hardware wallets generally work at the Miniscript/descriptor level and don't compile policies.

It would help if you could describe how Miniscript templates should work with hardware wallets in more detail. Ideally the hardware wallet user sees a high level description of the semantics based on these templates, but then the templates can't be policies (only), as the compiled Miniscript/descriptor could unexpectedly change.

Another point where guidance would help is with backups: the user needs to have a valid backup of the full descriptor to be able to restore, and at the same time not trust their computer to display the correct information.

Did you already brainstorm solutions to these?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @benma. Great question, and I think @Rob1Ham is better positioned than me to answer it.

For my part: in rust-miniscript we have a lift function which takes an arbitrary miniscript and drops the specific combinators to obtain a policy. We recommend users use this to compare Miniscripts for semantic equivalence. So the idea is that two Miniscripts that differ only in e.g. their choice of or constructions will be considered "the same" and if they matched a MINT in this repo, could be displayed to the user as that MINT.

This is potentially dangerous because it will show users policies that are "the same" even if they actually produce different addresses.

If we want to canonize this strategy then you're right that we need a document explaining (a) how wallets are supposed to manage things and present to users, and (b) a specification for this "lift"ing procedure. (It's super simple: you can do it textually by dropping all the letters before : or after _ in a combinator name.)

An alternate strategy would be to run every policy in these documents through the compiler to get an actual Miniscript (I think for these three MINTs there is actually only one possible sensible compilation, so this is an easy case) (where "sensible" means, like, not chaining a tons of ls and us on each other for no reason).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did notice this while working on this documentation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have additional tooling which is ommited from this PR. I recommend limiting the scope of this PR (to keep things moving) and creating an issue.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great points @benma.

Given the variation of policies that can result in effectively the same spending policies, but different script construction and therefore resulting in different addresses, it probably is best to default to an Output Descriptor post compilation.

Especially for the interoperation with Hardware Wallets, we want to have an explicit predetermined way that a given MINT would align with hardware wallets, and not have to have hardware wallet firmware/software wallet versions whenever the compiler comes out with new versions.

My ultimate goal with this project is to have a repository of known and validated application of miniscript templates which enable a synergy between users, hardware wallet signers, and software wallet developers. We remove uncertainty and opportunities for user error by deciding on a specific output descriptor for everyone to align on.

Around backups: In theory, if you knew an output descriptor followed a particular MINT, you'd be able to have some kind of compression on the data to be stored, but up to now that hasn't been discussed. One could store the XPUBs, and timelock details and have sufficient information to recover a wallet, but it isn't something I've explicitly put thought into beyond just storing the entire descriptor, happy to brainstorm ways to optimize this @benma!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I converted this into an issue at #12 as requested. Let's continue there, thanks!


2. Curate high quality example templates that demonstrate common use cases of
[MiniScript](https://raw.githubusercontent.com/bitcoin/bitcoin/master/src/script/miniscript.h)
policies.

3. Standardized implementations will establish best practices as well as promote uniform on-chain usage for better privacy.

4. Each `MinT` will be provided as is. While care is taken to ensure a high degree of quality. Developers and enthusiasts assume full responsibility for their usage [^use-at-your-own-risk].

<!--

Submission policy question:

Can a developer submit a template
under a different license?

-->

### Additional Resources

## Goals
[github.com/sipa/miniscript/tree/master](https://github.com/sipa/miniscript/tree/master )

- Have reviewed templates that leverage miniscript to assure there are not unintended ways of executing a valid spend beyond the intended miniscript policy.
- Have standardized usages of miniscript to streamline software and hardware wallet integrations.
- Have uniform on-chain usage of miniscript templates for better privacy.
[bitcoin.sipa.be/miniscript](https://bitcoin.sipa.be/miniscript )

## Submission Format
<!-- footnotes -->

1. Name of Template
2. Goal to be achieved by template
3. Example Miniscript Output Descriptor
[^mint]: MiniScript Template
[^mintt]: MiniTapScript Template
[^use-at-your-own-risk]: Use at your own risk.
Binary file added assets/key.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions assets/key.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/lock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions assets/lock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/unlock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions assets/unlock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
119 changes: 119 additions & 0 deletions mint-000.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# mint-000

## Proposed Timelock Usage

## Motivation

[Miniscript](https://bitcoin.sipa.be/miniscript/) facilitates easier
access to utilizing timelocks in Bitcoin, it opens a new frontier in
Bitcoin security concerning the construction of more advanced Scripts.
This document aims to standardize timelock application across different
wallet solutions, focusing on wallet recovery and standardizing expected
timelock usage for streamlined hardware and software wallet interfaces.

In the event an output descriptor has been partially or fully lost,
minimizing the overall search space for expected timestamp values can
expedite recovery. General Miniscript usage supports any valid timelock
value, this proposal seeks to guide implementation to more user-friendly
practices.

# Block height based Timelocks:

## Absolute block height based Timelocks

**Guideline**: Set absolute block height-based timelocks as multiples of
100, always ending in 00.

##### Examples of valid Block Height Absolute Timelocks

**<code>after(1000)</code>**

**<code>after(50700)</code>**

**<code>after(82800)</code>**

**<code>after(615000)</code>**

## Relative block height based Timelocks

**Guideline**: Make relative block height-based timelocks multiples of
100, except for the maximum value, 65,536 (2\^16).

**<code>older(100)</code>**

**<code>older(1500)</code>**

**<code>older(65535)</code>**

# Epoch timestamp based Timelocks:

## Absolute Epochtime based Timelocks

**Guideline**: To synchronize with real-world time rather than block
time, employ epoch timestamps that are divisible by 43200 (Noon GMT) or
86400 (Midnight GMT). Optimally, use multiples of 604800 for Thursday at
Midnight GMT.

**Limitation**: Avoid setting epoch timestamps beyond 2105 (4291704000)
to prevent any possible issue with related to its 32 bit unsigned
integer used for timestamps to happen in February of 2106.

##### Examples of valid Epoch Timestamp Absolute Timelocks

**<code>after(1694476800)</code>** ***September 12th, 2023 Midnight GMT***

**<code>after(1694520000)</code>** ***September 12th, 2023 Moon GMT***

**<code>after(2160172800)</code>** ***June 15th, 2038 Midnight GMT***

**<code>after(2234779200)</code>** ***October 25th, 2040 Noon GMT***

## Relative Epochtime based Timelocks

##### Examples of valid Block Height Relative Timelocks:

Background:

- Following
[BIP68](https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki),
relative epoch timestamp timelocks can only go as far out as
33,554,431 seconds (1.06 years), as it is constrained by the same
units as relative block height timelocks, 65,536 (2\^16), where each
unit represents 512 seconds (8 minutes and 32 seconds) of time
(65,356 units \* 512 seconds = 33,554,432 seconds).

- An Epoch Timestamp is not valid until the network\'s MTP (Median
Time Past) of the past 11 blocks is greater than the epoch
timestamp, MTP is defined in:
[BIP113](https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki).

- The smallest value that can be used to have the miniscript compiler
interpret a relative timelock is older(4194305) (calculated by
following the BIP68 spec of: 1 \|= (1 \<\< 22)). This is a 1 unit
timelock of duration 512 seconds.

- The maximum value for a relative epoch timelock is older(4259839)
which is 65,535 unit timelock, resulting in 33,554,431 seconds, or
388 days.

- The 512 second incrementor is a common multiple for the amount of
seconds in 4 days, which is 675 units. To encourage intuitive usage
of relative timelocks, they should be multiples of 675.

An exception should be made<br>
- for the largest possible epoch timestamp relative timelock.

**Proposal**: Starting at 4194304, increment by 675 (4 days), for
relative epochtime timelocks, the maximum value being 4259839.

##### Examples of valid Epoch Timestamp Absolute Timelocks

**<code>older(4194979)</code>** ***4 days, minimum value***

**<code>older(4214554)</code>** ***120 days***

**<code>older(4224679)</code>** ***180 days***

**<code>older(4255729)</code>** ***364 days***

**<code>older(4259839)</code>** ***388 days, maximum value***
Loading