Skip to content

Commit 949aca4

Browse files
committed
added 16_3
1 parent b1dc642 commit 949aca4

2 files changed

Lines changed: 214 additions & 1 deletion

File tree

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
1+
# 16.3: Using Miniscript with Descriptors
2+
3+
Miniscript and Policy are great for designing scripts outside of
4+
Bitcoin Core that can then be converted into Bitcoin Script and turned
5+
into addresses.
6+
7+
Some wallets offer deeper usage of Miniscript, but Bitcoin Core
8+
integration currently remains limited: to date you can only use
9+
Miniscript with Bitcoin Core to create read-only P2WSH
10+
addresses. Doing so requires a combination of two things you've
11+
already learned: first you convert from Policy to Miniscript; then you
12+
create a descriptor to read into Bitcoin Core. (We call the result a
13+
"minidescriptor", but that's not a formal term.)
14+
15+
## Create a P2WSH Minidescriptor
16+
17+
Creating a minidescriptor for import into Bitcoin Core is a simple
18+
five-step process.
19+
20+
1. **Create a Spending Policy**
21+
22+
We're going to use our president & vice-president policy from
23+
previous chapters:
24+
25+
```
26+
or(pk(president),thresh(2,pk(vp1),pk(vp2),pk(vp3)))
27+
28+
```
29+
30+
2. **Convert the Policy to Miniscript**
31+
32+
Compiling our Policy at [bitcoin.sipa.be](https://bitcoin.sipa.be/miniscript/) gives us our Miniscript:
33+
34+
```
35+
or_d(pk(president),multi(2,vp1,vp2,vp3))
36+
37+
```
38+
39+
3. **Gather the Keys**
40+
41+
To enter a minidescriptor into Bitcoin Core requires that you fill
42+
in the keys that should be used using base58 format. Since these
43+
Miniscripts are currently read-only, that means entering the xpubs,
44+
45+
Various people involved in a Minidescriptor might have created
46+
their keys in a variety of ways. Our executives used `seedtool` and
47+
`keytool` from [chapter 10](10_0_Working_with_Secrets.md) to create
48+
their secrets as follows:
49+
50+
```
51+
SEEDP=$(seedtool)
52+
KEYP=$(keytool --seed $SEEDP --account-derivation-path m/84h/1h/0h/0h --network testnet account-pub-key-base58)
53+
echo $KEYP
54+
55+
| tpubDFhGpPUEJaipdEeJtXZAUwb3Hz34hRCCqhvNgRwzrnbsGfXhCNEroYbGVHaVAyTAmJK4HXxLGCTXjP9HjwQRnG3oW7hCFY96JZkmo6kkCdt
56+
57+
SEEDVP1=$(seedtool)
58+
KEYVP1=$(keytool --seed $SEEDVP1 --account-derivation-path m/84h/1h/0h/0h --network testnet account-pub-key-base58)
59+
echo $KEYVP1
60+
61+
|tpubDE1YvUwRqg2N2JfU5LKDGuuv3AM2d2CgMYQauAxgoWnGMVaHETz8n2Cdz3VGi9bbfFeY9dRrydeshyQzqPBLPwSEV8hRBZj5JMEqV3rTkc6
62+
63+
SEEDVP2=$(seedtool)
64+
KEYVP2=$(keytool --seed $SEEDVP2 --account-derivation-path m/84h/1h/0h/0h --network testnet account-pub-key-base58)
65+
echo $KEYVP2
66+
67+
| tpubDE8xY8eWp6CZcdeVQFYG7c2H12GeUpN5j5WLpGEYxurygx5HfjkcbN28vjMmTdYHRNvPauKRsKdgwuJ4hiyJ93gnXPadBoiZeUUJsQ2sP37
68+
69+
SEEDVP3=$(seedtool)
70+
KEYVP3=$(keytool --seed $SEEDVP3 --account-derivation-path m/84h/1h/0h/0h --network testnet account-pub-key-base58)
71+
echo $KEYVP3
72+
73+
| tpubDE4kssfB4wqobfE3GWmYFkyV7giscXNG9HbXu2NykHoF1z9Tf4osozgPX4VZ8MnWxytKfeXAa89oZi9NUNauoLYcY51gFghUia34aAuj6sb
74+
```
75+
76+
4. **Place the Keys in the Minidescriptor.**
77+
78+
We gathered `84h/1h/0h/0h` keys. They're intended to support coins
79+
that are Segwit (`84h`), testnet (`1h`), first account (`0h`),
80+
non-change (`0h`). To allow for a range of addresses, we then
81+
supplement each key with a `/*` when we place it in our minscript.
82+
83+
(⚠️ We would have liked to collect `84h/1h/0h` keys and then defined
84+
them as `0h/*`, which would be more normative use, but Bitcoin Core
85+
currently flags that as "duplicate keys" if you try, even though
86+
they're not.)
87+
88+
```
89+
EXEC_MINID=$(echo "or_d(pk($KEYP/*),multi(2,$KEYVP1/*,$KEYVP2/*,$KEYVP3/*))")
90+
echo $EXEC_MINID
91+
92+
| or_d(pk(tpubDFhGpPUEJaipdEeJtXZAUwb3Hz34hRCCqhvNgRwzrnbsGfXhCNEroYbGVHaVAyTAmJK4HXxLGCTXjP9HjwQRnG3oW7hCFY96JZkmo6kkCdt/*),multi(2,tpubDE1YvUwRqg2N2JfU5LKDGuuv3AM2d2CgMYQauAxgoWnGMVaHETz8n2Cdz3VGi9bbfFeY9dRrydeshyQzqPBLPwSEV8hRBZj5JMEqV3rTkc6/*,tpubDE8xY8eWp6CZcdeVQFYG7c2H12GeUpN5j5WLpGEYxurygx5HfjkcbN28vjMmTdYHRNvPauKRsKdgwuJ4hiyJ93gnXPadBoiZeUUJsQ2sP37/*,tpubDE4kssfB4wqobfE3GWmYFkyV7giscXNG9HbXu2NykHoF1z9Tf4osozgPX4VZ8MnWxytKfeXAa89oZi9NUNauoLYcY51gFghUia34aAuj6sb/*))
93+
```
94+
95+
5. **Make a Wish**
96+
97+
To turn our Miniscript into a descriptor (a minidescriptor)
98+
requires one more thing. It has to be defined with a normal
99+
descriptor function.
100+
101+
Minidescriptors are currently only readable in Bitcoin Core as
102+
P2WSH addresses (not P2TR addresses). That requires a final step of
103+
embedding the Minidescriptor in `wsh(...)` to create a legal
104+
descriptor for Bitcoin Core to read.
105+
106+
```
107+
EXEC_MINID=$(echo "wsh($EXEC_MINID)")
108+
echo $EXEC_MINID
109+
110+
| wsh(or_d(pk(tpubDFhGpPUEJaipdEeJtXZAUwb3Hz34hRCCqhvNgRwzrnbsGfXhCNEroYbGVHaVAyTAmJK4HXxLGCTXjP9HjwQRnG3oW7hCFY96JZkmo6kkCdt/*),multi(2,tpubDE1YvUwRqg2N2JfU5LKDGuuv3AM2d2CgMYQauAxgoWnGMVaHETz8n2Cdz3VGi9bbfFeY9dRrydeshyQzqPBLPwSEV8hRBZj5JMEqV3rTkc6/*,tpubDE8xY8eWp6CZcdeVQFYG7c2H12GeUpN5j5WLpGEYxurygx5HfjkcbN28vjMmTdYHRNvPauKRsKdgwuJ4hiyJ93gnXPadBoiZeUUJsQ2sP37/*,tpubDE4kssfB4wqobfE3GWmYFkyV7giscXNG9HbXu2NykHoF1z9Tf4osozgPX4VZ8MnWxytKfeXAa89oZi9NUNauoLYcY51gFghUia34aAuj6sb/*)))
111+
```
112+
113+
## Import a P2WSH Minidescriptor
114+
115+
The Minidescriptor that you've created should theoretically be
116+
readable anywhere that supports Miniscript descriptors. To incorporate
117+
it specifically into Bitcoin Core requires the following additional
118+
steps:
119+
120+
6. **Add the Checksum**
121+
122+
As you'll recall, you always need a checksum for Bitcoin Core
123+
descriptors.
124+
125+
```
126+
EXEC_MINID_CS=$(bitcoin-cli getdescriptorinfo $EXEC_MINID | jq -r '.checksum')
127+
EXEC_MINID=$(echo $EXEC_MINID#$EXEC_MINID_CS)
128+
echo $EXEC_MINID
129+
130+
| wsh(or_d(pk(tpubDFhGpPUEJaipdEeJtXZAUwb3Hz34hRCCqhvNgRwzrnbsGfXhCNEroYbGVHaVAyTAmJK4HXxLGCTXjP9HjwQRnG3oW7hCFY96JZkmo6kkCdt/*),multi(2,tpubDE1YvUwRqg2N2JfU5LKDGuuv3AM2d2CgMYQauAxgoWnGMVaHETz8n2Cdz3VGi9bbfFeY9dRrydeshyQzqPBLPwSEV8hRBZj5JMEqV3rTkc6/*,tpubDE8xY8eWp6CZcdeVQFYG7c2H12GeUpN5j5WLpGEYxurygx5HfjkcbN28vjMmTdYHRNvPauKRsKdgwuJ4hiyJ93gnXPadBoiZeUUJsQ2sP37/*,tpubDE4kssfB4wqobfE3GWmYFkyV7giscXNG9HbXu2NykHoF1z9Tf4osozgPX4VZ8MnWxytKfeXAa89oZi9NUNauoLYcY51gFghUia34aAuj6sb/*)))#fhq2j999
131+
```
132+
133+
7. **Double-check Your Addresses**
134+
135+
Before you import your Minidescriptor it's best practice to make
136+
sure you have the right one. You can check this by verifying the
137+
addresses it creates with the `deriveaddresses` command.
138+
139+
```
140+
bitcoin-cli deriveaddresses $EXEC_MINID 2
141+
142+
| [
143+
| "tb1q5wj3hm4vask5zk2xzgdgw9slcpufml37yjnh0jhwf2c3sguuymhqsxc2gd",
144+
| "tb1qyxz7dv9859evxy5uutn3ueer978l73fw9ew0r2ajnj2lp5xltzpsrarv0q",
145+
| "tb1qy2s9l6jkhpnwfeyrsl88jj7e88a9k0dw0c8fyudeqv5lnqapm86q69zuue"
146+
| ]
147+
```
148+
149+
Presumably you've got another version of this miniscripted account
150+
somewhere else, on the wallet you're spending from. You should
151+
check the range of addresses you derived with Bitcoin Core against
152+
the first few addresses on that other wallet and make sure they
153+
are the same.
154+
155+
8. **Import Your Minidescriptor**
156+
157+
Finally, you're ready to import your minidescriptor. You want to do
158+
so into a brand-new wallet:
159+
160+
```
161+
bitcoin-cli -named createwallet wallet_name="watchmini" disable_private_keys=true blank=true
162+
```
163+
164+
Like when we imported other watch-only addresses in
165+
[§7.1](07_1_Creating_Multisig_Public_Keys.md), we create the wallet
166+
without any private keys.
167+
168+
Now you can import:
169+
170+
```
171+
bitcoin-cli -rpcwallet=watchmini importdescriptors '''[{ "desc": "'$EXEC_MINID'", "timestamp": 1790329126 }]'''
172+
173+
| [
174+
| {
175+
| "success": true,
176+
| "warnings": [
177+
| "Range not given, using default keypool range"
178+
| ]
179+
| }
180+
| ]
181+
```
182+
183+
You now have a watch-only wallet that you can use to monitor a
184+
range of addresses that you defined through Miniscript!
185+
186+
## Spend Your Funds
187+
188+
Obviously, because this is a watch-only address, you can't spend the
189+
funds from Bitcoin Core. We've set it up this way because this is the
190+
only limited, trial functionality that Bitcoin Core has for
191+
minidescriptor importing at the time of this writing.
192+
193+
As noted above, you should already be using this set of addresses
194+
somewhere else, in a wallet that you can actually spend from. But,
195+
that wallet may be offline; having a watch-only version will allow you
196+
to monitor its funds without exposing the private keys to the dangers
197+
of being on the net.
198+
199+
## Summary: Using Miniscript with Descriptors
200+
201+
Though you can use Bitcoin Scripts that you converted from Miniscript
202+
(or Policy) in Bitcoin Core, currently there's only limited ability to
203+
use Miniscript directly.
204+
205+
The one thing you can do is read in a Miniscript descriptor built with
206+
public keys to create a read-only wallet. Doing so is a simple
207+
combination of the process you've already learned to convert Policy
208+
into Miniscript with the process you've already learned to read a
209+
descriptor into Bitcoin Core.
210+
211+
## What's Next?
212+
213+
Continue "Using Miniscript" with [§16.4: Using BDK](16_4_Using_BDK.md).

‎docs/index.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ complete state.</i>
109109
* [**16.0: Using Miniscript**](16_0_Using_Miniscript.md)
110110
* [16.1: Understanding Miniscript](16_1_Understanding_Miniscript.md)
111111
* [16.2: Converting Miniscript](16_2_Converting_Miniscript.md)
112-
* [16.3: Using Miniscript with Descriptors] (pending)
112+
* [16.3: Using Miniscript with Descriptors](16_3_Using_Miniscript_with_Descriptors.md)
113113
* [16.4: Using Bitcoin Dev Kit (BDK)] (pending)
114114

115115

0 commit comments

Comments
 (0)