├── LICENSE ├── README.md └── mint-005.md /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2023, Blockstream 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | 1. Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright notice, 12 | this list of conditions and the following disclaimer in the documentation 13 | and/or other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 19 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 22 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Miniscript Templates 2 | 3 | 4 | ## About 5 | 6 | [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. 7 | 8 | ## Goals 9 | 10 | - Have reviewed templates that leverage miniscript to assure there are not unintended ways of executing a valid spend beyond the intended miniscript policy. 11 | - Have standardized usages of miniscript to streamline software and hardware wallet integrations. 12 | - Have uniform on-chain usage of miniscript templates for better privacy. 13 | 14 | ## Submission Format 15 | 16 | 1. Name of Template 17 | 2. Goal to be achieved by template 18 | 3. Example Miniscript Output Descriptor 19 | -------------------------------------------------------------------------------- /mint-005.md: -------------------------------------------------------------------------------- 1 | # mint-005 2 | 3 | ## 3 Key Joint Custody 4 | 5 | ## Motivation 6 | 7 | To provide a custody arrangement in which an owner of bitcoin (Principal) is able to secure bitcoin by working with an Agent. Unlike existing collaborative custody models up to this point, **where bitcoin keys WITHIN a multisig threshold are shared between Principals and agents**, a joint custody model by default requires a threshold of keys by both the Agent & Principal for movement of funds. 8 | 9 | This introduces a concept of "Negative Control" where, by default, funds are not able to be moved unless both the Principal and Agent sign the transaction. 10 | 11 | In the event the Principal loses access to all of their keys, a secondary agent is available to work with the Primary Agent such that funds can be recovered after a set period of time. 12 | 13 | In the unlikely event the Primary Agent has lost 2 of their 3 keys, a timelock enabled threshold allows only 1 of 3 keys from the Primary Agent to be signed with the secondary agent. 14 | 15 | Finally, in the event the Principal no longer wishes to work with the agent, say after a contract expires, the custody defers to a set of recovery keys, which can be held either by the Principal, or their own delegated managers of the recovery keys. As a result, when enough time has passed, the Principal is able to move bitcoin unilaterally without having the Agent sign key material. 16 | 17 | ### More on Timelock Values 18 | 19 | There are three timelocks used for this MinT: 20 | 21 | 1. `smallest_epoch_timestamp` - The smallest epoch timestamp timelock enables a "Asset Recovery" period such that only one of the Principal keys is required to sign. 22 | 23 | 2. `between_epoch_timestamp` - The epoch timestamp value in between the smallest and largest epoch timestamp enables a "Emergency Recovery Path". In the event the Principal has lost all of their keys, the Primary Agent and Secondary Agent can work together to recover the bitcoin in the Joint Custody vault. 24 | 25 | 3. `largest_epoch_timestamp` - The largest epoch timestamp, signifying the expiration of the contract, where the Principal is able to unilaterally withdraw their bitcoin from the joint custody vault. 26 | 27 | ### Keys 28 | 29 | In total, there are 10 keys in use for the 3 Key Joint Custody Vault, they are as follows: 30 | 31 | | Key Names | Description | Key Abbreviations | Key Symbol | 32 | |:--|:--:|:--:|:--:| 33 | |Principal Keys 1,2,3 | These keys belong to the owner of the bitcoin. They are used as the default keys the Principal uses to transact bitcoin for the length of the relationship with the agent in the Joint Custody vault. | $PK_1$, $PK_2$, $PK_3$ |
![Blue Key](https://raw.githubusercontent.com/Rob1Ham/miniscript-templates/main/assets/key_blue.png)
| 34 | |Primary Agent Keys 1,2,3 | These keys belong to the agent, who the Principal has engaged with to fascilitate the securing of bitcoin for a determined set of time. | $PAK_1$, $PAK_2$, $PAK_3$ |
![Green Key](https://raw.githubusercontent.com/Rob1Ham/miniscript-templates/main/assets/key_green.png)
| 35 | |Secondary Agent Key | This key is held by a 3rd party unassoicated with the other keys, in the event the Principal has lost a majority of their keys, can sign transactions with the Primary Agent to move funds after a designated "Recovery Period" has started. | $SAK$ |
![Red Key](https://raw.githubusercontent.com/Rob1Ham/miniscript-templates/83a8c241b2c2cf7ee940570aa97d8b0e1d751f55/assets/key_red.png)
| 36 | |Recovery Keys 1,2,3 | These keys in practice belong to the Principal, they may even be keys related to the Principal Keys with a different derivation path, but can also be delegated key holders. After the initial Joint Custody vault agreement has ended, the recovery keys can unilaterally be used to withdraw money from the vault. | $RK_1$, $RK_2$, $RK_3$ |
![Gray Key](https://raw.githubusercontent.com/Rob1Ham/miniscript-templates/main/assets/key_gray.png)
| 37 | 38 | 39 | 40 | Below are reference diagrams on how the 3 Key Joint Custody operates across time: 41 | 42 | --- 43 | 44 | ### Joint Custody Summary Layers 45 | 46 | Layer is used as an abstraction to segement the different eligible spending conditions, going in an ascending order of timelock values. At the start, only "Layer 1" is accessible for spending funds, over time, other spending conditions become available, but this does not restrict the ability to spend from a proceeding layer. 47 | 48 | | Layer | Layer Name | Key Set 1 | Condition Between Sets | Key Set 2 | Timelock Condition | Timelock | 49 | |:-----:|:-------------------------:|:------------------------------:|:----------------------:|:------------------:|:------------------:|:-------------------------------:| 50 | | 1 | Default Spending Path | $PK_1$, $PK_2$, $PK_3$ (2 of 3)| AND | $PAK_1$, $PAK_2$, $PAK_3$ (2 of 3)| N/A | None | 51 | | 2 | Asset Recovery Path | $PK_1$, $PK_2$, $PK_3$ (1 of 3) | AND | $PAK_1$, $PAK_2$, $PAK_3$ (2 of 3) | AND | After (`smallest_epoch_timestamp`) | 52 | | 3 | Emergency Recovery Path | $PAK_1$, $PAK_2$, $PAK_3$ (2 of 3)| AND | $SAK$ | N/A | After (`between_epoch_timestamp`) | 53 | | 4 | Sovereign Recovery Path | $RK_1$, $RK_2$, $RK_3$ (2 of 3)| None | None | AND | After (`largest_epoch_timestamp`) | 54 | 55 | ### Layer 1 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
Default Spending Path2 of 3 PKs2 of 3 PAKs
PK1PK2PK3PAK1PAK2PAK3
2 of 3 PKs AND 2 of 3 PAKsPK1PK2PK3PAK1PAK2PAK3
81 | 82 | #### Valid Layer 1 Spend Conditions 83 | | Spending Scenario | $PK_1$ | $PK_2$ | $PK_3$ | $PAK_1$ | $PAK_2$ | $PAK_3$ | 84 | |-------------------|:------:|:------:|:------:|:-------:|:-------:|:-------:| 85 | | Scenario 1 | ✅ | ✅ | | ✅ | ✅ | | 86 | | Scenario 2 | ✅ | | ✅ | ✅ | ✅ | | 87 | | Scenario 3 | ✅ | ✅ | | | ✅ | ✅ | 88 | | Scenario 4 | | ✅ | ✅ | ✅ | ✅ | | 89 | | Scenario 5 | ✅ | | ✅ | | ✅ | ✅ | 90 | | Scenario 6 | | ✅ | ✅ | | ✅ | ✅ | 91 | | Scenario 7 | ✅ | ✅ | | ✅ | | ✅ | 92 | | Scenario 8 | ✅ | | ✅ | ✅ | | ✅ | 93 | | Scenario 9 | | ✅ | ✅ | ✅ | | ✅ | 94 | 95 | 96 | #### Layer 2 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 |
Asset Recovery Path1 of 3 PKs2 of 3 PAKsBIP-113 time greater than `smallest_epoch_timestamp`
PK1PK2PK3PAK1PAK2PAK3
1 of 3 PKs AND 2 of 3 PAKs AND BIP-113 time is greater than `smallest_epoch_timestamp`PK1PK2PK3PAK1PAK2PAK3Timelock
125 | 126 | 127 | ##### Valid Layer 2 Spend Conditions 128 | | Spending Scenario | PK_1 | PK_2 | PK_3 | PAK_1 | PAK_2 | PAK_3 | BIP-113 greater than `smallest_epoch_timestamp` | 129 | |-------------------|:----:|:----:|:----:|:-----:|:-----:|:-----:|:-----------------------------------:| 130 | | Scenario 10 | ✅ | | | ✅ | ✅ | | ✅ | 131 | | Scenario 11 | ✅ | | | ✅ | | ✅ | ✅ | 132 | | Scenario 12 | ✅ | | | | ✅ | ✅ | ✅ | 133 | | Scenario 13 | | ✅ | | ✅ | ✅ | | ✅ | 134 | | Scenario 14 | | ✅ | | ✅ | | ✅ | ✅ | 135 | | Scenario 15 | | ✅ | | | ✅ | ✅ | ✅ | 136 | | Scenario 16 | | | ✅ | ✅ | ✅ | | ✅ | 137 | | Scenario 17 | | | ✅ | ✅ | | ✅ | ✅ | 138 | | Scenario 18 | | | ✅ | | ✅ | ✅ | ✅ | 139 | 140 | #### Layer 3: 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 |
Emergency Recovery Path2 of 3 PAKs1 SAKBIP-113 time greater than `between_epoch_timestamp`
PAK1PAK2PAK3SAK
2 of 3 PAKs AND SAK AND after BIP-113 time is greater than `between_epoch_timestamp`PAK1PAK2PAK3SAK1Timelock
165 | 166 | ##### Valid Layer 3 Spend Conditions 167 | | Spending Scenario | PAK_1 | PAK_2 | PAK_3 | SAK | BIP-113 time greater than (between_epoch_timestamp) | 168 | |-------------------|:-----:|:-----:|:-----:|:---:|:----------------------------------:| 169 | | Scenario 19 | ✅ | ✅ | | ✅ | ✅ | 170 | | Scenario 20 | ✅ | | ✅ | ✅ | ✅ | 171 | | Scenario 21 | | ✅ | ✅ | ✅ | ✅ | | 172 | 173 | #### Layer 4: 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 |
Sovereign Recovery Path2 of 3 RKsNetwork BIP-113 time greater than `largest_epoch_timestamp`
RK1RK2RK3
2 of 3 RKs AND after BIP-113 time is greater than `largest_epoch_timestamp`RK1RK2RK3Timelock
195 | 196 | ##### Valid Layer 4 Spend Conditions 197 | | Spending Scenario | RK_1 | RK_2 | RK_3 | Timelock (largest_epoch_timestamp) | 198 | |-------------------|:----:|:----:|:----:|:----------------------------------:| 199 | | Scenario 22 | ✅ | ✅ | | ✅ | 200 | | Scenario 23 | ✅ | | ✅ | ✅ | 201 | | Scenario 24 | | ✅ | ✅ | ✅ | 202 | 203 | --- 204 | # Example Miniscript Output Descriptor 205 | For this example, the `smallest_epoch_timestamp` is: 1672531200 (Jan 1 2023, midnight gmt), the `between_epoch_timestamp` is: 1673740800 and `largest_epoch_timestamp` is: 1675209600 (Feb 1 2023, midnight gmt) 206 | 207 | - MINT-005 Output Descriptor: 208 | wsh(andor(multi(2,$PAK_1$,$PAK_2$,$PAK_3$),or_i(and_v(v:pkh($SAK$),after(`between_epoch_timestamp`)),thresh(2,pk($PK_1$),s:pk($PK_2$),s:pk($PK_3$),snl:after(`smallest_epoch_timestamp`))),and_v(v:thresh(2,pkh($RK_1$),a:pkh($RK_2$),a:pkh($RK_3$)),after(`larget_epoch_timestamp`)))) 209 | 210 | - Source Policy (FOR REFERENCE PURPOSES ONLY): 211 | "or(99@and(thresh(2,pk($PAK_1$),pk($PAK_2$),pk($PAK_3$)),or(99@thresh(2,pk($PK_1$),pk($PK_2$),pk($PK_3$),after(`smallest_epoch_timestamp`)),and(pk($SAK$),after(`between_epoch_timestamp`)))),and(thresh(2,pk($RK_1$),pk($RK_2$),pk($RK_3)),after(`largest_epoch_timestamp`)))" 212 | 213 | ## Layer 1 Example Spend 214 | 215 | Signed by: $PK_1$, $PK_2$, $PAK_1$, $PAK_2$ 216 | 217 | [Reference Testnet 218 | Transaction](https://mempool.space/signet/tx/2836d6af6b5c4bb01e926391f64771fb333193676040b24d4236ba0bb89a7008) 219 | 220 | ## Layer 2 Example Spend 221 | Signed by: $PK_1$, $PK_2$, $SAK$ 222 | 223 | [Reference Testnet 224 | Transaction](https://mempool.space/signet/tx/36aa3dfd0c7b4f4d8c7924c411e240920e4b4d36950ca59f68098b77162ae54d) 225 | 226 | ## Layer 3 Example Spend 227 | [Reference Testnet 228 | Transaction](https://mempool.space/signet/tx/bc75e9c7bd62168134a6283a56c2a0bf3c872cc6703d9566f1851309d5ef7465) 229 | 230 | ## Layer 4 Example Spend 231 | Signed by: $RK_1$, $RK_2$ 232 | 233 | [Reference Testnet 234 | Transaction](https://mempool.space/signet/tx/1d35568360a3a11309c77c893142a0c0cf58ed9cfce981c5492c66fb795f1872) --------------------------------------------------------------------------------