@ -429,15 +429,30 @@ wallets--not shared with the network--protecting their privacy
and keeping unnecessary personal data out of the blockchain. For
and keeping unnecessary personal data out of the blockchain. For
an example, see <<alice_tx_labels>>.
an example, see <<alice_tx_labels>>.
[[alice_tx_labels]]
++++
.Alice's transaction history with each transaction labeled
<table id="alice_tx_labels">
[options="header"]
<caption>Alice’ s transaction history with each transaction labeled</caption>
[cols="1,1,1"]
<thead>
|===
<tr>
| Date | Label | BTC
<th>Date</th>
| 2023-01-01 | Bought bitcoins from Joe | +0.00100
<th>Label</th>
| 2023-01-02 | Paid Bob for podcast | − 0.00075
<th>BTC</th>
|===
</tr>
</thead>
<tbody>
<tr>
<td><p>2023-01-01</p></td>
<td><p>Bought bitcoins from Joe</p></td>
<td><p>+0.00100</p></td>
</tr>
<tr>
<td><p>2023-01-02</p></td>
<td><p>Paid Bob for podcast</p></td>
<td><p>− 0.00075</p></td>
</tr>
</tbody>
</table>
++++
However, because address and transaction labels are stored only in each
However, because address and transaction labels are stored only in each
user's wallet database and because they aren't deterministic, they can't
user's wallet database and because they aren't deterministic, they can't
@ -512,17 +527,40 @@ the keys in that path both when it is first started and after a
restoration from a recovery code. We call this solution _implicit
restoration from a recovery code. We call this solution _implicit
paths_. Several popular implicit paths defined by BIPs are shown in <<bip_implicit_paths>>
paths_. Several popular implicit paths defined by BIPs are shown in <<bip_implicit_paths>>
[[bip_implicit_paths]]
++++
.Implicit script paths defined by various BIPs
<table id="bip_implicit_paths">
[options="header"]
<caption>Implicit script paths defined by various BIPs</caption>
[cols="1,1,1"]
<thead>
|===
<tr>
| Standard | Script | BIP32 path
<th>Standard</th>
| BIP44 | P2PKH | +m/44'/0'/0'+
<th>Script</th>
| BIP49 | Nested P2WPKH | +m/49'/1'/0'+
<th>BIP32 path</th>
| BIP84 | P2WPKH | +m/84'/0'/0'+
</tr>
| BIP86 | P2TR Single-key | +m/86'/0'/0'+
</thead>
|===
<tbody>
<tr>
<td><p>BIP44</p></td>
<td><p>P2PKH</p></td>
<td><p><code>m/44'/0'/0'</code></p></td>
</tr>
<tr>
<td><p>BIP49</p></td>
<td><p>Nested P2WPKH</p></td>
<td><p><code>m/49'/1'/0'</code></p></td>
</tr>
<tr>
<td><p>BIP84</p></td>
<td><p>P2WPKH</p></td>
<td><p><code>m/84'/0'/0'</code></p></td>
</tr>
<tr>
<td><p>BIP86</p></td>
<td><p>P2TR Single-key</p></td>
<td><p><code>m/86'/0'/0'</code></p></td>
</tr>
</tbody>
</table>
++++
The second solution is to back up the path information with the recovery
The second solution is to back up the path information with the recovery
code, making it clear which path is used with which scripts. We call
code, making it clear which path is used with which scripts. We call
@ -582,21 +620,32 @@ _descriptors_ for short) as specified in BIPs 380, 381, 382, 383, 384,
describe a script and the keys (or key paths) to be used with it.
describe a script and the keys (or key paths) to be used with it.
A few example descriptors are shown in <<sample_descriptors>>.
A few example descriptors are shown in <<sample_descriptors>>.
[[sample_descriptors]]
++++
.Sample descriptors from Bitcoin Core documentation (with elision)
<table id="sample_descriptors">
[cols="1,1"]
<caption>Sample descriptors from Bitcoin Core documentation (with elision)</caption>
|===
<thead>
| Descriptor | Explanation
<tr>
<th>Descriptor</th>
| +pkh(02c6...9ee5)+
<th>Explanation</th>
| P2PKH script for the provided public key
</tr>
</thead>
| +sh(multi(2,022f...2a01,03ac...ccbe))+
<tbody>
| P2SH multisignature requring two signatures corresponding to these two keys
<tr>
<td><p><code>pkh(02c6… 9ee5)</code></p></td>
<td><p>P2PKH script for the provided public key</p></td>
</tr>
<tr>
<td><p><code>sh(multi(2,022f… 2a01,03ac… ccbe))</code></p></td>
<td><p>P2SH multisignature requring two signatures corresponding to these two keys</p></td>
</tr>
<tr>
<td><p><code>pkh([d34db33f/44'/0'/0']xpub6ERA… RcEL/1/*)</code></p></td>
<td><p>P2PKH scripts for the BIP32 <code>d34db33f</code> with the extended public key (xpub) at the path <code>M/44'/0'/0'</code>, which is <code>xpub6ERA… RcEL</code>, using the keys at <code>M/1/*</code> of that xpub</p></td>
</tr>
</tbody>
</table>
++++
| +pkh([d34db33f/44'/0'/0']xpub6ERA...RcEL/1/*)+
| P2PKH scripts for the BIP32 +d34db33f+ with the extended public key (xpub) at the path +M/44'/0'/0'+, which is +xpub6ERA...RcEL+, using the keys at +M/1/*+ of that xpub
|===
It has long been the trend for wallet applications designed only for
It has long been the trend for wallet applications designed only for
single signature scripts to use implicit paths. Wallet applications
single signature scripts to use implicit paths. Wallet applications
@ -690,18 +739,97 @@ image::images/mbc3_0504.png["Generating entropy and encoding as a recovery code"
<<table_4-5>> shows the relationship between the size of the entropy
<<table_4-5>> shows the relationship between the size of the entropy
data and the length of recovery code in words.
data and the length of recovery code in words.
[[table_4-5]]
++++
.BIP39: entropy and word length
<table id="table_4-5">
[options="header"]
<caption>BIP39: entropy and word length</caption>
[cols="1,1,1,1"]
<thead>
|=======
<tr>
|Entropy (bits) | Checksum (bits) | Entropy *+* checksum (bits) | Recovery code words
<th>Entropy (bits)</th>
| 128 | 4 | 132 | 12
<th>Checksum (bits)</th>
| 160 | 5 | 165 | 15
<th>Entropy <strong>+</strong> checksum (bits)</th>
| 192 | 6 | 198 | 18
<th>Recovery code words</th>
| 224 | 7 | 231 | 21
</tr>
| 256 | 8 | 264 | 24
</thead>
|=======
<tbody>
<tr>
<td><p>128</p></td>
<td><p>4</p></td>
<td><p>132</p></td>
<td><p>12</p></td>
</tr>
<tr>
<td><p>160</p></td>
<td><p>5</p></td>
<td><p>165</p></td>
<td><p>15</p></td>
</tr>
<tr>
<td><p>192</p></td>
<td><p>6</p></td>
<td><p>198</p></td>
<td><p>18</p></td>
</tr>
<tr>
<td><p>224</p></td>
<td><p>7</p></td>
<td><p>231</p></td>
<td><p>21</p></td>
</tr>
<tr>
<td><p>256</p></td>
<td><p>8</p></td>
<td><p>264</p></td>
<td><p>24</p></td>
</tr>
</tbody>
</table>
++++
++++
<table id="table_4-5">
<caption>BIP39: entropy and word length</caption>
<thead>
<tr>
<th>Entropy (bits)</th>
<th>Checksum (bits)</th>
<th>Entropy <strong>+</strong> checksum (bits)</th>
<th>Recovery code words</th>
</tr>
</thead>
<tbody>
<tr>
<td><p>128</p></td>
<td><p>4</p></td>
<td><p>132</p></td>
<td><p>12</p></td>
</tr>
<tr>
<td><p>160</p></td>
<td><p>5</p></td>
<td><p>165</p></td>
<td><p>15</p></td>
</tr>
<tr>
<td><p>192</p></td>
<td><p>6</p></td>
<td><p>198</p></td>
<td><p>18</p></td>
</tr>
<tr>
<td><p>224</p></td>
<td><p>7</p></td>
<td><p>231</p></td>
<td><p>21</p></td>
</tr>
<tr>
<td><p>256</p></td>
<td><p>8</p></td>
<td><p>264</p></td>
<td><p>24</p></td>
</tr>
</tbody>
</table>
++++
[[recovery_to_seed]]
[[recovery_to_seed]]
===== From recovery code to seed
===== From recovery code to seed
@ -772,40 +900,77 @@ pass:[<a data-type="xref" href="#bip39_256_no_pass"
data-xrefstyle="select: labelnumber">#bip39_256_no_pass</a>] show
data-xrefstyle="select: labelnumber">#bip39_256_no_pass</a>] show
some examples of recovery codes and the seeds they produce.
some examples of recovery codes and the seeds they produce.
[[bip39_128_no_pass]]
++++
.128-bit entropy BIP39 recovery code, no passphrase, resulting seed
<table id="bip39_128_no_pass">
[cols="h,"]
<caption>128-bit entropy BIP39 recovery code, no passphrase, resulting seed</caption>
|=======
<tbody>
| *Entropy input (128 bits)*| +0c1e24e5917779d297e14d45f14e1a1a+
<tr>
| *Recovery Code (12 words)* | +army van defense carry jealous true garbage claim echo media make crunch+
<td><p><strong>Entropy input (128 bits)</strong></p></td>
| *Passphrase*| (none)
<td><p><code>0c1e24e5917779d297e14d45f14e1a1a</code></p></td>
| *Seed (512 bits)* | +5b56c417303faa3fcba7e57400e120a0ca83ec5a4fc9ffba757fbe63fbd77a89a1a3be4+
</tr>
+c67196f57c39a88b76373733891bfaba16ed27a813ceed498804c0570+
<tr>
|=======
<td><p><strong>Recovery Code (12 words)</strong></p></td>
<td><p><code>army van defense carry jealous true garbage claim echo media make crunch</code></p></td>
[[bip39_128_w_pass]]
</tr>
.128-bit entropy BIP39 recovery code, with passphrase, resulting seed
<tr>
[cols="h,"]
<td><p><strong>Passphrase</strong></p></td>
|=======
<td><p>(none)</p></td>
| *Entropy input (128 bits)*| +0c1e24e5917779d297e14d45f14e1a1a+
</tr>
| *Recovery Code (12 words)* | +army van defense carry jealous true garbage claim echo media make crunch+
<tr>
| *Passphrase*| SuperDuperSecret
<td><p><strong>Seed (512 bits)</strong></p></td>
| *Seed (512 bits)* | +3b5df16df2157104cfdd22830162a5e170c0161653e3afe6c88defeefb0818c793dbb28+
<td><p><code>5b56c417303faa3fcba7e57400e120a0ca83ec5a4fc9ffba757fbe63fbd77a89a1a3be4</code>
+ab3ab091897d0715861dc8a18358f80b79d49acf64142ae57037d1d54+
<code>c67196f57c39a88b76373733891bfaba16ed27a813ceed498804c0570</code></p></td>
|=======
</tr>
</tbody>
</table>
[[bip39_256_no_pass]]
.256-bit entropy BIP39 recovery code, no passphrase, resulting seed
<table id="bip39_128_w_pass">
[cols="h,"]
<caption>128-bit entropy BIP39 recovery code, with passphrase, resulting seed</caption>
|=======
<tbody>
| *Entropy input (256 bits)* | +2041546864449caff939d32d574753fe684d3c947c3346713dd8423e74abcf8c+
<tr>
| *Recovery Code (24 words)* | +cake apple borrow silk endorse fitness top denial coil riot stay wolf
<td><p><strong>Entropy input (128 bits)</strong></p></td>
luggage oxygen faint major edit measure invite love trap field dilemma oblige+
<td><p><code>0c1e24e5917779d297e14d45f14e1a1a</code></p></td>
| *Passphrase*| (none)
</tr>
| *Seed (512 bits)* | +3269bce2674acbd188d4f120072b13b088a0ecf87c6e4cae41657a0bb78f5315b33b3+
<tr>
+a04356e53d062e55f1e0deaa082df8d487381379df848a6ad7e98798404+
<td><p><strong>Recovery Code (12 words)</strong></p></td>
|=======
<td><p><code>army van defense carry jealous true garbage claim echo media make crunch</code></p></td>
</tr>
<tr>
<td><p><strong>Passphrase</strong></p></td>
<td><p>SuperDuperSecret</p></td>
</tr>
<tr>
<td><p><strong>Seed (512 bits)</strong></p></td>
<td><p><code>3b5df16df2157104cfdd22830162a5e170c0161653e3afe6c88defeefb0818c793dbb28</code>
<code>ab3ab091897d0715861dc8a18358f80b79d49acf64142ae57037d1d54</code></p></td>
</tr>
</tbody>
</table>
<table id="bip39_256_no_pass">
<caption><span class="label">Table 5-7. </span>256-bit entropy BIP39 recovery code, no passphrase, resulting seed</caption>
<tbody>
<tr>
<td><p><strong>Entropy input (256 bits)</strong></p></td>
<td><p><code>2041546864449caff939d32d574753fe684d3c947c3346713dd8423e74abcf8c</code></p></td>
</tr>
<tr>
<td><p><strong>Recovery Code (24 words)</strong></p></td>
<td><p><code>cake apple borrow silk endorse fitness top denial coil riot stay wolf
luggage oxygen faint major edit measure invite love trap field dilemma oblige</code></p></td>
</tr>
<tr>
<td><p><strong>Passphrase</strong></p></td>
<td><p>(none)</p></td>
</tr>
<tr>
<td><p><strong>Seed (512 bits)</strong></p></td>
<td><p><code>3269bce2674acbd188d4f120072b13b088a0ecf87c6e4cae41657a0bb78f5315b33b3</code>
<code>a04356e53d062e55f1e0deaa082df8d487381379df848a6ad7e98798404</code></p></td>
</tr>
</tbody>
</table>
++++
.How Much Entropy Do You Need?
.How Much Entropy Do You Need?
****
****
@ -1283,18 +1448,39 @@ master key from which it was derived. For example, identifier m/x/y/z
describes the key that is the z-th child of key m/x/y, which is the y-th
describes the key that is the z-th child of key m/x/y, which is the y-th
child of key m/x, which is the x-th child of m.
child of key m/x, which is the x-th child of m.
[[table_4-8]]
++++
.HD wallet path examples
<table id="table_4-8">
[options="header"]
<caption>HD wallet path examples</caption>
[cols="1,1"]
<thead>
|=======
<tr>
|HD path | Key described
<th>HD path</th>
| m/0 | The first (0) child private key from the master private key (m)
<th>Key described</th>
| m/0/0 | The first grandchild private key from the first child (m/0)
</tr>
| m/0'/0 | The first normal grandchild private key from the first _hardened_ child (m/0')
</thead>
| m/1/0 | The first grandchild private key from the second child (m/1)
<tbody>
| M/23/17/0/0 | The first great-great-grandchild public key from the first great-grandchild from the 18th grandchild from the 24th child
<tr>
|=======
<td><p>m/0</p></td>
<td><p>The first (0) child private key from the master private key (m)</p></td>
</tr>
<tr>
<td><p>m/0/0</p></td>
<td><p>The first grandchild private key from the first child (m/0)</p></td>
</tr>
<tr>
<td><p>m/0'/0</p></td>
<td><p>The first normal grandchild private key from the first <em>hardened</em> child (m/0')</p></td>
</tr>
<tr>
<td><p>m/1/0</p></td>
<td><p>The first grandchild private key from the second child (m/1)</p></td>
</tr>
<tr>
<td><p>M/23/17/0/0</p></td>
<td><p>The first great-great-grandchild public key from the first great-grandchild from the 18th grandchild from the 24th child</p></td>
</tr>
</tbody>
</table>
++++
===== Navigating the HD wallet tree structure
===== Navigating the HD wallet tree structure
@ -1354,16 +1540,31 @@ third receiving address for payments in the primary account
would be M/44++'++/0++'++/0++'++/0/2. <<table_4-9>> shows
would be M/44++'++/0++'++/0++'++/0/2. <<table_4-9>> shows
a few more examples.
a few more examples.
[[table_4-9]]
++++
.BIP44 HD wallet structure examples
<table id="table_4-9">
[options="header"]
<caption>BIP44 HD wallet structure examples</caption>
[cols="1,1"]
<thead>
|=======
<tr>
|HD path | Key described
<th>HD path</th>
| M/44++'++/0++'++/0++'++/0/2 | The third receiving public key for the primary Bitcoin account
<th>Key described</th>
| M/44++'++/0++'++/3++'++/1/14 | The fifteenth change-address public key for the fourth Bitcoin account
</tr>
| m/44++'++/2++'++/0++'++/0/1 | The second private key in the Litecoin main account, for signing transactions
</thead>
|=======
<tbody>
<tr>
<td><p>M/44<code>'</code>/0<code>'</code>/0<code>'</code>/0/2</p></td>
<td><p>The third receiving public key for the primary Bitcoin account</p></td>
</tr>
<tr>
<td><p>M/44<code>'</code>/0<code>'</code>/3<code>'</code>/1/14</p></td>
<td><p>The fifteenth change-address public key for the fourth Bitcoin account</p></td>
</tr>
<tr>
<td><p>m/44<code>'</code>/2<code>'</code>/0<code>'</code>/0/1</p></td>
<td><p>The second private key in the Litecoin main account, for signing transactions</p></td>
</tr>
</tbody>
</table>
++++
Many people focus on securing their bitcoins against theft and other
Many people focus on securing their bitcoins against theft and other
attacks, but one of the leading causes of lost bitcoins--perhaps _the_
attacks, but one of the leading causes of lost bitcoins--perhaps _the_