summaryrefslogtreecommitdiff
path: root/f3/3da3d73dbc09cfb4c7ce343932dc3ddee0e729
blob: 23875753e0b49678ba8dacb6fbef78d8ccab9090 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
Return-Path: <salvatore.ingala@gmail.com>
Received: from smtp2.osuosl.org (smtp2.osuosl.org [140.211.166.133])
 by lists.linuxfoundation.org (Postfix) with ESMTP id 97279C002D
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 08:45:07 +0000 (UTC)
Received: from localhost (localhost [127.0.0.1])
 by smtp2.osuosl.org (Postfix) with ESMTP id 852DA40C0F
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 08:45:07 +0000 (UTC)
X-Virus-Scanned: amavisd-new at osuosl.org
X-Spam-Flag: NO
X-Spam-Score: -2.098
X-Spam-Level: 
X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5
 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1,
 DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001,
 HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001,
 SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: smtp2.osuosl.org (amavisd-new);
 dkim=pass (2048-bit key) header.d=gmail.com
Received: from smtp2.osuosl.org ([127.0.0.1])
 by localhost (smtp2.osuosl.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id xxNGMcgHpQhK
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 08:45:06 +0000 (UTC)
X-Greylist: whitelisted by SQLgrey-1.8.0
Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com
 [IPv6:2607:f8b0:4864:20::102f])
 by smtp2.osuosl.org (Postfix) with ESMTPS id 1512E40C9D
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 08:45:05 +0000 (UTC)
Received: by mail-pj1-x102f.google.com with SMTP id
 l20-20020a17090a409400b001dd2a9d555bso1697822pjg.0
 for <bitcoin-dev@lists.linuxfoundation.org>;
 Tue, 17 May 2022 01:45:05 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112;
 h=mime-version:references:in-reply-to:from:date:message-id:subject:to;
 bh=raSHQ0JdXv28WuQRuquW5BCN0XaYG6+VJDTKvcMLUy8=;
 b=R/q95tIWtkeoEQzwuWVmSUwYIG7XpC7gRY8R750Y8DmcR09aiCjGc+h9R1CEuJvmZL
 s8fzAst8pVKGiyYm4LP0laMXJNThY41n0sF6xBTPFRC27ZeY85IW+eRX02Vy78tqtzHI
 iXHUe4jGZLv+7jWaLB77fzjSFwfFSvqVr6q6NAmHVQ1s8q3giTc9fvQjrBvwr6fiNrMT
 yV3nMqA7K+sMjLbMNxkAsB3S6rCPYHZ7TGhORUEQE/+YvU8SY/HxglproR3kO7rgV3UF
 3sEAozRIOOnymw0RkU0K+9OEPN1INTj/Mi29pi3fRoF/uBt8IfuJEzL4lybvELxrpQ9w
 NURA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20210112;
 h=x-gm-message-state:mime-version:references:in-reply-to:from:date
 :message-id:subject:to;
 bh=raSHQ0JdXv28WuQRuquW5BCN0XaYG6+VJDTKvcMLUy8=;
 b=tGYh9XN2xRxIwIAWwQeACzld1XvOo0OuKiWQei1tEX62QIUXWt/xxZEYtuoA/GUANQ
 ZxfP2N2+aw7CzT1Uch/Us6DL2T8tWQXwnPxbSXqVpkTGTCXc2Joi0QXLdONRjGAGT7a5
 Aw/LsurDFuKXvvUFfFDQdAMLTlMElE4GF+EPo4kE8eLoc9bn33j4duuRFXNOXe4Qgq3A
 LdizwMNzfs69/856xZ3QqPVH9p203n86S6pD5Fv8IdHBau/tFywHnTOW6m0Bdz/Kcg1W
 IVkNISm+zJi5FEcWagLrwoUEXhg13nB2JhCsgFQHYBQiPxQVeuOMjTZ4Nfji8/gn1+nY
 1o1w==
X-Gm-Message-State: AOAM531FQVkA+qqMhP5A42KQByGCbWLbK3/fnYp29QgkFwmeTyvm3yfG
 /Pk7Q+PwrBVbctrJtzE4j45E3oqDtUKx+tCicqR1jAl2qhvynw==
X-Google-Smtp-Source: ABdhPJyib9IM0R8k4bQYcqoOexZYG5KV+Mh8Vi8hFYaUJmsPOpBzsNBtkTZmfKjPRZqooEEEPP/kh+dxal58QRmWIpA=
X-Received: by 2002:a17:902:ccc2:b0:15f:4acc:f202 with SMTP id
 z2-20020a170902ccc200b0015f4accf202mr20982085ple.3.1652777104809; Tue, 17 May
 2022 01:45:04 -0700 (PDT)
MIME-Version: 1.0
References: <CAMhCMoHfdsQMsVigFqPexTE_q-Cyg7pfRvORUoy2sZtvyzd1cg@mail.gmail.com>
In-Reply-To: <CAMhCMoHfdsQMsVigFqPexTE_q-Cyg7pfRvORUoy2sZtvyzd1cg@mail.gmail.com>
From: Salvatore Ingala <salvatore.ingala@gmail.com>
Date: Tue, 17 May 2022 10:44:53 +0200
Message-ID: <CAMhCMoF9P6gCqeCyfMGSHT95msDnjGVzkSfLQkRkABbu2jVz5A@mail.gmail.com>
To: Bitcoin Protocol Discussion <bitcoin-dev@lists.linuxfoundation.org>
Content-Type: multipart/alternative; boundary="00000000000039a07605df31288f"
X-Mailman-Approved-At: Tue, 17 May 2022 09:25:14 +0000
Subject: Re: [bitcoin-dev] Wallet policies for descriptor wallets
X-BeenThere: bitcoin-dev@lists.linuxfoundation.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: Bitcoin Protocol Discussion <bitcoin-dev.lists.linuxfoundation.org>
List-Unsubscribe: <https://lists.linuxfoundation.org/mailman/options/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=unsubscribe>
List-Archive: <http://lists.linuxfoundation.org/pipermail/bitcoin-dev/>
List-Post: <mailto:bitcoin-dev@lists.linuxfoundation.org>
List-Help: <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=help>
List-Subscribe: <https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev>, 
 <mailto:bitcoin-dev-request@lists.linuxfoundation.org?subject=subscribe>
X-List-Received-Date: Tue, 17 May 2022 08:45:07 -0000

--00000000000039a07605df31288f
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

Hi all,

TL;DR: It is easy to convert from wallet policy to descriptors and back;
imho aliases are better left out of descriptors in real world usage; some
more examples given.

I received some very useful feedback on the wallet policy proposal (in this
list and outside); that also led me to realize that my initial post lacked
some clarity and more practical examples.

This post wants to:
- clarify that extracting descriptors from the wallet policy is trivial;
- argue that figuring out the wallet policy (template and list of keys
information) from the descriptor is reasonably easy =E2=88=92 automatable f=
or sane
descriptors currently in use, and much more general ones as well;
- give an idea of what the information shown on a hardware wallet screen
would look like (emphasizing compactness);
- explain my point of view on "descriptors with aliases".

This gist demoes conversions from wallet policies to descriptors, and back:
https://gist.github.com/bigspider/10df51401be3aa6120217c03c2836ffa

Note that I would expect/hope software wallets to prefer working directly
with wallet policies =E2=88=92 but it might help to have automated tools fo=
r the
conversion, for interoperability with tools that do not adopt wallet
policies.

(All the following examples use the `/**` notation as a shortcut for
`/<0,1>/*`; this notation might be dropped without consequences on the rest
of the proposal.)

All the keys in the example I'm proposing are followed by /**. It is
unclear to me if hardware wallets should allow *registration* of wallet
policies with static keys (that is, without any range operator), as that
would incentivize key reuse. The specs still support it as there might be
other use cases.

The policy for miniscript examples not using taproot was generated with the
online compiler: https://bitcoin.sipa.be/miniscript. Many examples are also
borrowed from there.
(To the best of my knowledge, there is no publicly released compiler for
miniscript on taproot, yet)

Note on aliases: it has been pointed out that many miniscript
implementations internally use aliases to refer to the keys. In my opinion,
aliases:
- should be external to the descriptor language, as they bear no
significance for the actual script(s) that the descriptor can produce
- fail to distinguish which part of the KEY expression is part of the
"wallet description", and which part is not

By clearly separating the key information in the vector (typically, an xpub
with key origin information) from the key placeholder expression (which
typically will have the `/**` or `/<0,1>/*` derivation step), wallet
policies semantically represent keys in a way that should be convenient to
both software wallets and hardware signers.

Associating recognizable names to the xpubs (and registering them on the
device) is a good idea for future developments and can greatly improve the
UX, both during wallet setup, or in recognizing outputs for repeated
payments; it should be easy to build this feature on top of wallet policies=
.

=3D=3D Examples =3D=3D

All the examples show:
- Miniscript policy: semantic spending rules, and optimization hints (can
be compiled to miniscript automatically)
- Miniscript: the actual miniscript descriptor, compiles 1-to-1 to Bitcoin
Script
- Wallet template: the "wallet descriptor template"
- Vector of keys: the list of key information (with key origin information)

Together, the wallet template and the vector of keys are the complet
"wallet policy".

=3D=3D=3D Example 1: Either of two keys (equally likely) =3D=3D=3D

Miniscript policy: or(pk(key_0),pk(key_1))
Miniscript:
 wsh(or_b([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUH=
QVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/<0;1>/*)=
,s:pk([12345678/44'/0'/0']xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8=
syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/<0;1>/*)))

Descriptor template:   wsh(or_b(pk(@0/**),s:pk(@1/**)))
Vector of keys: [

"[d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMk=
hgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL",

"[12345678/44'/0'/0']xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmR=
UapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB"
]

In all the following examples, I will replace the xpubs with aliases in the
miniscript for brevity, and omit the corresponding vector of keys in the
wallet policy.

Of course, in comparing the "information density" (especially for UX
purposes), it is important to take the full descriptor into account.
It is always to be assumed that the keys are xpubs, complete with key
origin information if internal (that is, controlled by the software or
hardware signer that the wallet policy is being with).

=3D=3D=3D Example 2: Either of two keys, but one is more likely =3D=3D=3D

Miniscript policy: or(99@pk(key_likely),pk(key_unlikely))
Miniscript:           wsh(or_d(pk(key_likely),pkh(key_unlikely)))

Descriptor template: wsh(or_d(pk(@0/**),pkh(@1/**)))
Vector of keys:         <omitted>

=3D=3D=3D Example 3: A 3-of-3 that turns into a 2-of-3 after 90 days =3D=3D=
=3D

Miniscript policy: thresh(3,pk(key_0),pk(key_1),pk(key_2),older(12960))
Miniscript:
 wsh(thresh(3,pk(key_0),s:pk(key_1),s:pk(key_2),sln:older(12960)))

Descriptor template:
wsh(thresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960)))))
Vector of keys:         <omitted>

=3D=3D=3D Example 4: The BOLT #3 received HTLC policy =3D=3D=3D

Miniscript policy:
andor(pk(key_remote),or_i(and_v(v:pkh(key_local),hash160(395e368b267d64945f=
30e4b71de1054f364c9473)),older(1008)),pk(key_revocation))
Miniscript:
 wsh(andor(pk(key_remote),or_i(and_v(v:pkh(key_local),hash160(395e368b267d6=
4945f30e4b71de1054f364c9473)),older(1008)),pk(key_revocation)))

Descriptor template:
wsh(andor(pk(@0/**),or_i(and_v(v:pkh(@1/**),hash160(395e368b267d64945f30e4b=
71de1054f364c9473)),older(1008)),pk(@2/**)))
Vector of keys:          <omitted>

=3D=3D=3D Example 5: Taproot complex script (2-of-2 with cold backup and
timelocked inheritance) =3D=3D=3D

The likely path is a 2-of-2 of a hot_key and a cosigner_key (2FA-like
service). At any time, a cold_key can be used for signing, and after about
a year, a separate timelocked_key becomes active (for example, to a notary
for inheritance purposes).
The timelock is reset every time UTXOs are spent.

Miniscript policy: or(99@thresh(2,pk(hot_key),pk(cosigner_key)),1@or(99@pk
(cold_key),1@and(pk(timelocked_key),older(52596))))
Miniscript:
 tr(cold_key,{and_v(v:pk(timelocked_key),older(52596)),multi_a(2,hot_key,co=
signer_key)})

Descriptor template:
tr(@0/**,{and_v(v:pk(@1/**),older(52596)),multi_a(2,@2/**,@3/**)})
Vector of keys:          <omitted>

=3D=3D=3D Example 6: Taproot complex script with MuSig2 =3D=3D=3D

The same policy as above, but we assume that the hot wallet and the
cosigner are able to engage in the MuSig2 protocol.
This greatly exemplifies the practical advantage of MuSig2 with taproot in
terms of both transaction cost and privacy.

Miniscript policy: or(99@musig2(hot_key,cosigner_key),1@or(99@pk
(cold_key),1@and(pk(timelocked_key),older(52596))))
Miniscript:
 tr(musig2(hot_key,cosigner_key),{and_v(v:pk(timelocked_key),older(52596)),=
pk(cold_key)})

Descriptor template:
tr(musig2(@0,@1)/**,{and_v(v:pk(@2/**),older(52596)),pk(@3/**)})
Vector of keys:         <omitted>. Note: the order of keys differs from the
previous example.



Salvatore Ingala

--00000000000039a07605df31288f
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>Hi all,<br></div><div><br></div><div>TL;DR: It is eas=
y to convert from wallet policy to descriptors and back; imho aliases are b=
etter left out of descriptors in real world usage; some more examples given=
.=C2=A0<br></div><div><br></div><div>I received some very useful feedback o=
n the wallet policy proposal (in this list and outside); that also led me t=
o realize that my initial post lacked some clarity and more practical examp=
les.</div><div dir=3D"ltr"><br></div><div dir=3D"ltr">This post wants to:<b=
r>- clarify that extracting descriptors from the wallet policy is trivial;<=
/div><div dir=3D"ltr">- argue that figuring out the wallet policy (template=
 and list of keys information) from the descriptor is reasonably easy =E2=
=88=92 automatable for sane descriptors currently in use, and much more gen=
eral ones as well;</div><div dir=3D"ltr">- give an idea of what the informa=
tion shown on a hardware wallet screen would look like (emphasizing compact=
ness);</div><div>- explain my point of view on &quot;descriptors with alias=
es&quot;.</div><div dir=3D"ltr"><br></div><div>This gist demoes conversions=
 from wallet policies to descriptors, and back:=C2=A0<a href=3D"https://gis=
t.github.com/bigspider/10df51401be3aa6120217c03c2836ffa">https://gist.githu=
b.com/bigspider/10df51401be3aa6120217c03c2836ffa</a></div><div dir=3D"ltr">=
<br></div><div>Note that I would expect/hope software wallets to prefer wor=
king directly with wallet policies =E2=88=92 but it might help to have auto=
mated tools for the conversion, for interoperability with tools that do not=
 adopt wallet policies.</div><div dir=3D"ltr"><br>(All the following exampl=
es use the `/**` notation as a shortcut for `/&lt;0,1&gt;/*`; this notation=
 might be dropped without consequences on the rest of the proposal.)<br><br=
></div><div dir=3D"ltr">All the keys in the example I&#39;m proposing are f=
ollowed by /**. It is unclear to me if hardware wallets should allow=C2=A0<=
i>registration</i>=C2=A0of wallet policies with static keys (that is, witho=
ut any range operator), as that would incentivize key reuse. The specs stil=
l support it as there might be other use cases.</div><div dir=3D"ltr"><br><=
/div><div>The policy for miniscript examples not using taproot was generate=
d with the online compiler:=C2=A0<a href=3D"https://bitcoin.sipa.be/miniscr=
ipt/">https://bitcoin.sipa.be/miniscript</a>. Many examples are also borrow=
ed from there.</div><div>(To the best of my knowledge, there is no publicly=
 released compiler for miniscript on taproot, yet)</div><div dir=3D"ltr"><b=
r></div><div>Note on aliases: it has been pointed out that many miniscript =
implementations internally use aliases to refer to the keys. In my opinion,=
 aliases:</div><div>- should be external to the descriptor language, as the=
y bear no significance for the actual script(s) that the descriptor can pro=
duce</div><div>- fail to distinguish which part of the KEY expression is pa=
rt of the &quot;wallet description&quot;, and which part is not</div><div><=
br></div><div>By clearly separating the key information in the vector (typi=
cally, an xpub with key origin information) from the key placeholder expres=
sion (which typically will have the `/**` or `/&lt;0,1&gt;/*` derivation st=
ep), wallet policies semantically represent keys in a way that should be co=
nvenient to both software wallets and hardware signers.</div><div><br></div=
><div>Associating recognizable names to the xpubs (and registering them on =
the device) is a good idea for future developments and can greatly improve =
the UX,=C2=A0both during wallet setup,=C2=A0or in recognizing outputs for r=
epeated payments; it should be easy to build this feature on top of wallet =
policies.</div><div><br></div><div dir=3D"ltr">=3D=3D Examples =3D=3D<br><b=
r>All the examples show:</div><div dir=3D"ltr">- Miniscript policy: semanti=
c spending rules, and optimization hints (can be compiled to miniscript aut=
omatically)</div><div>- Miniscript: the actual miniscript descriptor, compi=
les 1-to-1 to Bitcoin Script</div><div>- Wallet template: the &quot;wallet =
descriptor template&quot;=C2=A0</div><div>- Vector of keys: the list of key=
 information (with key origin information)</div><div dir=3D"ltr"><br></div>=
<div>Together, the wallet template and the vector of keys are the complet &=
quot;wallet policy&quot;.</div><div dir=3D"ltr"><br>=3D=3D=3D Example 1: Ei=
ther of two keys (equally likely) =3D=3D=3D<br><br>Miniscript policy: or(pk=
(key_0),pk(key_1))<br>Miniscript: =C2=A0 =C2=A0 =C2=A0 =C2=A0wsh(or_b([d34d=
b33f/44&#39;/0&#39;/0&#39;]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVH=
QKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/&lt;0;1&gt;=
/*),s:pk([12345678/44&#39;/0&#39;/0&#39;]xpub661MyMwAqRbcFW31YEwpkMuc5THy2P=
St5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGud=
uB/&lt;0;1&gt;/*)))<br><br>Descriptor template: =C2=A0 wsh(or_b(pk(@0/**),s=
:pk(@1/**)))<br>Vector of keys: [<br>=C2=A0 =C2=A0 &quot;[d34db33f/44&#39;/=
0&#39;/0&#39;]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZ=
RkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL&quot;,<br>=C2=A0 =C2=A0 =
&quot;[12345678/44&#39;/0&#39;/0&#39;]xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5=
bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB&=
quot;<br>]<br><br>In all the following examples, I will replace the xpubs w=
ith aliases in the miniscript for brevity, and omit the corresponding vecto=
r of keys in the wallet policy.<br><br></div><div dir=3D"ltr">Of course, in=
 comparing the &quot;information density&quot; (especially for UX purposes)=
, it is important to take the full descriptor into account.<br></div><div d=
ir=3D"ltr">It is always to be assumed that the keys are xpubs, complete wit=
h key origin information if internal (that is, controlled by the software o=
r hardware signer that the wallet policy is being with).<br><br>=3D=3D=3D E=
xample 2: Either of two keys, but one is more likely =3D=3D=3D<br><br>Minis=
cript policy: or(99@pk(key_likely),pk(key_unlikely))<br>Miniscript:=C2=A0 =
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0wsh(or_d(pk(key_likely),pkh(key_unlikely)=
))<br><br>Descriptor template: wsh(or_d(pk(@0/**),pkh(@1/**)))<br>Vector of=
 keys:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&lt;omitted&gt;<br><br>=3D=3D=3D Ex=
ample 3: A 3-of-3 that turns into a 2-of-3 after 90 days =3D=3D=3D<br><br>M=
iniscript policy: thresh(3,pk(key_0),pk(key_1),pk(key_2),older(12960))<br>M=
iniscript:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0wsh(thresh(3,pk(key_0),s=
:pk(key_1),s:pk(key_2),sln:older(12960)))<br><br>Descriptor template: wsh(t=
hresh(3,pk(@0/**),s:pk(@1/**),s:pk(@2/**),sln:older(12960)))))<br>Vector of=
 keys:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&lt;omitted&gt;<br><br>=3D=3D=3D Ex=
ample 4: The BOLT #3 received HTLC policy =3D=3D=3D<br><br>Miniscript polic=
y: andor(pk(key_remote),or_i(and_v(v:pkh(key_local),hash160(395e368b267d649=
45f30e4b71de1054f364c9473)),older(1008)),pk(key_revocation))<br>Miniscript:=
 =C2=A0 =C2=A0 =C2=A0 =C2=A0wsh(andor(pk(key_remote),or_i(and_v(v:pkh(key_l=
ocal),hash160(395e368b267d64945f30e4b71de1054f364c9473)),older(1008)),pk(ke=
y_revocation)))<br><br>Descriptor template: wsh(andor(pk(@0/**),or_i(and_v(=
v:pkh(@1/**),hash160(395e368b267d64945f30e4b71de1054f364c9473)),older(1008)=
),pk(@2/**)))<br>Vector of keys:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;omit=
ted&gt;<br><br>=3D=3D=3D Example 5: Taproot complex script (2-of-2 with col=
d backup and timelocked inheritance) =3D=3D=3D<br><div dir=3D"ltr"><br></di=
v><div>The likely path is a 2-of-2 of a hot_key and a cosigner_key (2FA-lik=
e service). At any time, a cold_key can be used for signing, and after abou=
t a year, a separate timelocked_key becomes active (for example, to a notar=
y for inheritance purposes).</div><div>The timelock is reset every time UTX=
Os are spent.</div><div dir=3D"ltr"><br></div>Miniscript policy: or(99@thre=
sh(2,pk(hot_key),pk(cosigner_key)),1@or(99@pk(cold_key),1@and(pk(timelocked=
_key),older(52596))))</div><div dir=3D"ltr">Miniscript:=C2=A0 =C2=A0 =C2=A0=
 =C2=A0 =C2=A0 =C2=A0tr(cold_key,{and_v(v:pk(timelocked_key),older(52596)),=
multi_a(2,hot_key,cosigner_key)})<br></div><div dir=3D"ltr"><br></div><div =
dir=3D"ltr"><div dir=3D"ltr">Descriptor template: tr(@0/**,{and_v(v:pk(@1/*=
*),older(52596)),multi_a(2,@2/**,@3/**)})</div></div><div dir=3D"ltr">Vecto=
r of keys:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &lt;omitted&gt;<br></div><div =
dir=3D"ltr"><br></div><div dir=3D"ltr">=3D=3D=3D Example 6: Taproot complex=
 script with MuSig2 =3D=3D=3D<br></div><div dir=3D"ltr"><br></div><div>The =
same policy as above, but we assume that the hot wallet and the cosigner ar=
e able to engage in the MuSig2 protocol.</div><div>This greatly exemplifies=
 the practical advantage of MuSig2 with taproot in terms of both transactio=
n cost and privacy.</div><div><br></div><div dir=3D"ltr">Miniscript policy:=
 or(99@musig2(hot_key,cosigner_key),1@or(99@pk(cold_key),1@and(pk(timelocke=
d_key),older(52596))))</div><div>Miniscript:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0tr(musig2(hot_key,cosigner_key),{and_v(v:pk(timelocked_key),older=
(52596)),pk(cold_key)})<br></div><div><br></div><div><div>Descriptor templa=
te: tr(musig2(@0,@1)/**,{and_v(v:pk(@2/**),older(52596)),pk(@3/**)})</div><=
div><div dir=3D"ltr">Vector of keys:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0&lt;o=
mitted&gt;. Note: the order of keys differs from the previous example.<br><=
/div><div dir=3D"ltr"><br></div></div></div><div dir=3D"ltr"><br></div><div=
 dir=3D"ltr"><br></div><div>Salvatore Ingala</div><div dir=3D"ltr"></div></=
div>

--00000000000039a07605df31288f--