diff --git a/_autocrossref.yaml b/_autocrossref.yaml
index 627812fd..c34bb6ba 100644
--- a/_autocrossref.yaml
+++ b/_autocrossref.yaml
@@ -36,6 +36,7 @@ change output:
change outputs: change output
child key:
child keys: child key
+child private and public keys: child key
child public key:
child public keys: child public key
coinbase: coinbase transaction
@@ -122,7 +123,9 @@ p2pkh:
p2sh:
p2sh multisig:
parent chain code:
+parent key:
parent private key:
+parent private and public keys: parent key
parent public key:
Payment message: pp payment
payment protocol:
diff --git a/_includes/guide_wallets.md b/_includes/guide_wallets.md
index de895156..49da269e 100644
--- a/_includes/guide_wallets.md
+++ b/_includes/guide_wallets.md
@@ -2,11 +2,259 @@
{% autocrossref %}
-Bitcoin wallets at their core are a collection of private keys. These collections are stored digitally in a file, or can even be physically stored on pieces of paper.
+A Bitcoin wallet can refer to either a wallet program or a wallet file.
+Wallet programs create public keys to receive satoshis and use the
+corresponding private keys to spend those satoshis. Wallet files
+store private keys and (optionally) other information related to
+transactions for the wallet program.
+
+Wallet programs and wallet files are addressed below in separate
+subsections, and this document attempts to always make it clear whether
+we're talking about wallet programs or wallet files.
{% endautocrossref %}
-### Private Key Formats
+### Wallet Programs
+
+{% autocrossref %}
+
+Permitting receiving and spending of satoshis is the only essential
+feature of wallet software---but a particular wallet program doesn't
+need to do both things. Two wallet programs can work together, one
+program distributing public keys in order to receive satoshis and
+another program signing transactions spending those satoshis.
+
+Wallet programs also need to interact with the peer-to-peer network to
+get information from the block chain and to broadcast new transactions.
+However, the programs which distribute public keys or sign transactions
+don't need to interact with the peer-to-peer network themselves.
+
+This leaves us with three necessary, but separable, parts of a wallet
+system: a public key distribution program, a signing program, and a
+networked program. In the subsections below, we will describe common
+combinations of these parts.
+
+Note: we speak about distributing public keys generically. In many
+cases, P2PKH or P2SH hashes will be distributed instead of public keys,
+with the actual public keys only being distributed when the outputs
+they control are spent.
+
+{% endautocrossref %}
+
+#### Full-Service Wallets
+
+{% autocrossref %}
+
+The simplest wallet is a program which performs all three functions: it
+generates private keys, derives the corresponding public keys, helps
+distribute those public keys as necessary, monitors for outputs spent to
+those public keys, creates and signs transactions spending those
+outputs, and broadcasts the signed transactions.
+
+
+
+As of this writing, almost all popular wallets can be used as
+full-service wallets.
+
+The main advantage of full-service wallets is that they are easy to use.
+A single program does everything the user needs to receive and spend
+satoshis.
+
+The main disadvantage of full-service wallets is that they store the
+private keys on a device connected to the Internet. The compromise of
+such devices is a common occurrence, and an Internet connection makes it
+easy to transmit private keys from a compromised device to an attacker.
+
+To help protect against theft, many wallet programs offer users the
+option of encrypting the wallet files which contain the private keys.
+This protects the private keys when they aren't being used, but it
+cannot protect against an attack designed to capture the encryption
+key or to read the decrypted keys from memory.
+
+{% endautocrossref %}
+
+
+#### Signing-Only Wallets
+
+{% autocrossref %}
+
+To increase security, private keys can be generated and stored by a
+separate wallet program operating in a more secure environment. These
+signing-only wallets work in conjunction with a networked wallet which
+interacts with the peer-to-peer network.
+
+Signing-only wallets programs typically use deterministic key creation
+(described in a later subsection) to create parent private and public
+keys which can create child private and public keys.
+
+
+
+When first run, the signing-only wallet creates a parent private key and
+transfers the corresponding parent public key to the networked wallet.
+
+The networked wallet uses the parent public key to derive child public
+keys, optionally helps distribute them, monitors for outputs spent to
+those public keys, creates unsigned transactions spending those outputs,
+and transfers the unsigned transactions to the signing-only wallet.
+
+Often, users are given a chance to review the unsigned transactions' details
+(particularly the output details) using the signing-only wallet.
+
+After the optional review step, the offline wallet uses the parent
+private key to derive the appropriate child private keys and signs the
+transactions, giving the signed transactions back to the networked wallet.
+
+The networked wallet then broadcasts the signed transactions to the
+peer-to-peer network.
+
+The following subsections describe the two most common variants of
+signing-only wallets: offline wallets and hardware wallets.
+
+{% endautocrossref %}
+
+##### Offline Wallets
+
+{% autocrossref %}
+
+Several full-service wallets programs will also operate as two separate
+wallets: one program instance acting as a signing-only wallet (often called an
+"offline wallet") and the other program instance acting as the networked
+wallet (often called an "online wallet" or "watching-only wallet").
+
+The offline wallet is so named because it is intended to be run on a
+device which does not connect to any network, greatly reducing the
+number of attack vectors. If this is the case, it is usually up to the
+user to handle all data transfer using removable media such as USB
+drives. The user's workflow is something like:
+
+1. (Offline) Disable all network connections on a device and install the wallet
+ software. Start the wallet software in offline mode to create the
+ parent private and public keys. Copy the parent public key to
+ removable media.
+
+2. (Online) Install the wallet software on another device, this one
+ connected to the Internet, and import the parent public key from the
+ removable media. As you would with a full-service wallet, distribute
+ public keys to receive payment. When ready to spend satoshis, fill in
+ the output details and save the unsigned transaction generated by the
+ wallet to removable media.
+
+3. (Offline) Open the unsigned transaction in the offline instance,
+ review the output details to make sure they spend the correct
+ amount to the correct address. This prevents malware on the online
+ wallet from tricking the user into signing a transaction which pays
+ an attacker. After review, sign the transaction and save it to
+ removable media.
+
+4. (Online) Open the signed transaction in the online instance so it can
+ broadcast it to the peer-to-peer network.
+
+The primary advantage of offline wallets is their possibility for
+greatly improved security over full-service wallets. As long as the
+offline wallet is not compromised (or flawed) and the user reviews all outgoing
+transactions before signing, the user's satoshis are safe even if the
+online wallet is compromised.
+
+The primary disadvantage of offline wallets is hassle. For maximum
+security, they require the user dedicate a device to only offline tasks.
+The offline device must be booted up whenever funds are to be spent, and
+the user must physically copy data from the online device to the offline
+device and back.
+
+{% endautocrossref %}
+
+
+
+##### Hardware Wallets
+
+{% autocrossref %}
+
+Hardware wallets are devices dedicated to running a signing-only wallet.
+Their dedication lets them eliminate many of the vulnerabilities
+present in operating systems designed for general use, allowing them
+to safely communicate directly with other devices so users don't need to
+transfer data manually. The user's workflow is something like:
+
+1. (Hardware) Create parent private and public keys. Connect hardware
+ wallet to a networked device so it can get the parent public key.
+
+2. (Networked) As you would with a full-service wallet, distribute
+ public keys to receive payment. When ready to spend satoshis, fill in
+ the transaction details, connect the hardware wallet, and click
+ Spend. The networked wallet will automatically send the transaction
+ details to the hardware wallet.
+
+3. (Hardware) Review the transaction details on the hardware wallet's
+ screen. Some hardware wallets may prompt for a passphrase or PIN
+ number. The hardware wallet signs the transaction and uploads it to
+ the networked wallet.
+
+4. (Networked) The networked wallet receives the signed transaction from
+ the hardware wallet and broadcasts it to the network.
+
+The primary advantage of hardware wallets is their possibility for
+greatly improved security over full-service wallets with much less
+hassle than offline wallets.
+
+The primary disadvantage of hardware wallets is their hassle. Even
+though the hassle is less than that of offline wallets, the user must
+still purchase a hardware wallet device and carry it with them whenever
+they need to make a transaction using the signing-only wallet.
+
+An additional (hopefully temporary) disadvantage is that, as of this
+writing, very few popular wallet programs support hardware
+wallets---although almost all popular wallet programs have announced
+their intention to support at least one model of hardware wallet.
+
+{% endautocrossref %}
+
+
+
+
+#### Distributing-Only Wallets
+
+{% autocrossref %}
+
+Wallet programs which run in difficult-to-secure environments, such as
+webservers, can be designed to distribute public keys (including P2PKH
+or P2SH addresses) and nothing more. There are two common ways to
+design these minimalist wallets:
+
+
+
+* Pre-populate a database with a number of public keys or addresses, and
+ then distribute on request an output script or address using one of
+ the database entries. To [avoid key reuse][devguide avoiding key
+ resuse], webservers should keep track
+ of used keys and never run out of public keys. This can be made easier
+ by using parent public keys as suggested in the next method.
+
+* Use a parent public key to create child public keys. To avoid key
+ reuse, a method must be used to ensure the same public key isn't
+ distributed twice. This can be a database entry for each key
+ distributed or an incrementing pointer to the current child key
+ index number.
+
+Neither method adds a significant amount of overhead, especially if a
+database is used anyway to associate each incoming payment with a
+separate public key for payment tracking. See the [Payment
+Processing][devguide payment processing] section for details.
+
+{% endautocrossref %}
+
+
+
+### Wallet Files
+
+{% autocrossref %}
+
+Bitcoin wallets at their core are a collection of private keys. These
+collections are stored digitally in a file, or can even be physically
+stored on pieces of paper.
+
+{% endautocrossref %}
+
+#### Private Key Formats
{% autocrossref %}
@@ -16,7 +264,7 @@ Private keys are what are used to unlock satoshis from a particular address. In
{% endautocrossref %}
-#### Wallet Import Format (WIF)
+##### Wallet Import Format (WIF)
{% autocrossref %}
@@ -40,7 +288,7 @@ The process is easily reversible, using the Base58 decoding function, and removi
{% endautocrossref %}
-#### Mini Private Key Format
+##### Mini Private Key Format
{% autocrossref %}
@@ -62,7 +310,7 @@ address utility].
{% endautocrossref %}
-### Hierarchical Deterministic Key Creation
+#### Hierarchical Deterministic Key Creation
+
+
diff --git a/img/dev/en-wallets-full-service.dot b/img/dev/en-wallets-full-service.dot
new file mode 100644
index 00000000..bfad5bbd
--- /dev/null
+++ b/img/dev/en-wallets-full-service.dot
@@ -0,0 +1,30 @@
+digraph wallet_program {
+size="6.25";
+rankdir=LR;
+//ratio=fill;
+splines=true;
+fontname=Sans
+ranksep=0.3;
+penwidth=1.75;
+
+overlap = false;
+
+edge [ fontname=Sans, penwidth=1.75, style = "invis" ];
+node [ fontname=Sans, shape = box, penwidth=1.75 ];
+
+subgraph cluster_networked {
+ penwidth=0;
+ networked_priv [ label = "Create\nPrivate\nKeys" ];
+ networked_pub [ label = "Derive\nPublic\nKeys" ];
+ networked_distribute [ label = "Distribute\nPublic\nKeys" ];
+ networked_monitor [ label = "Monitor\nFor\nOutputs" ];
+ networked_create [ label = "Create\nUnsigned\nTxes" ];
+ networked_sign [ label = "Sign\nTxes" ];
+ networked_broadcast [ label = "Broadcast\nTxes" ];
+
+ networked_priv -> networked_pub -> networked_distribute -> networked_monitor -> networked_create -> networked_sign -> networked_broadcast [ style = "" ];
+ label = " \nFull-Service Wallet"
+}
+
+}
+
diff --git a/img/dev/en-wallets-full-service.png b/img/dev/en-wallets-full-service.png
new file mode 100644
index 00000000..afa2a6eb
Binary files /dev/null and b/img/dev/en-wallets-full-service.png differ
diff --git a/img/dev/en-wallets-full-service.svg b/img/dev/en-wallets-full-service.svg
new file mode 100644
index 00000000..d686ad4c
--- /dev/null
+++ b/img/dev/en-wallets-full-service.svg
@@ -0,0 +1,95 @@
+
+
+
+
+
diff --git a/img/dev/en-wallets-signing-only.dot b/img/dev/en-wallets-signing-only.dot
new file mode 100644
index 00000000..166480d1
--- /dev/null
+++ b/img/dev/en-wallets-signing-only.dot
@@ -0,0 +1,50 @@
+digraph wallet_program {
+size="6.25";
+rankdir=LR;
+//ratio=fill;
+splines=true;
+fontname=Sans
+ranksep=0.3;
+penwidth=1.75;
+
+overlap = false;
+
+edge [ fontname=Sans, penwidth=1.75, style = "invis" ];
+node [ fontname=Sans, shape = box, penwidth=1.75 ];
+
+subgraph cluster_signing {
+ penwidth=0;
+
+ signing_priv [ label = "Create\nParent\nPrivate\nKey" ];
+ signing_pub [ label = "Derive\nParent\nPublic\nKey" ];
+ signing_distribute [ label = "Distribute\nPublic\nKeys", style="invis" ];
+ signing_monitor [ label = "Monitor\nFor\nOutputs", style="invis" ];
+ signing_create [ label = "Create\nUnsigned\nTxes", style="invis" ];
+ signing_sign [ label = "Sign\nTxes" ];
+ signing_broadcast [ label = "Broadcast\nTxes", style="invis" ];
+
+ signing_priv -> signing_pub -> signing_distribute -> signing_monitor -> signing_create -> signing_sign -> signing_broadcast;
+ label = "Signing-Only Wallet"
+}
+
+subgraph cluster_networked {
+ penwidth=0;
+
+ networked_priv [ label = "Create\nPrivate\nKeys", style="invis" ];
+ networked_pub [ label = "Derive\nChild\nPublic\nKeys" ];
+ networked_distribute [ label = "Distribute\nPublic\nKeys" ];
+ networked_monitor [ label = "Monitor\nFor\nOutputs" ];
+ networked_create [ label = "Create\nUnsigned\nTxes" ];
+ networked_sign [ label = "Sign\nTxes", style="invis" ];
+ networked_broadcast [ label = "Broadcast\nTxes" ];
+
+ networked_priv -> networked_pub -> networked_distribute -> networked_monitor -> networked_create -> networked_sign -> networked_broadcast;
+ label = "Networked Wallet"
+}
+
+signing_priv -> signing_pub [style=""];
+signing_pub -> networked_pub [ constraint = false, style = ""];
+networked_pub -> networked_distribute -> networked_monitor -> networked_create -> signing_sign -> networked_broadcast [style=""];
+
+}
+
diff --git a/img/dev/en-wallets-signing-only.png b/img/dev/en-wallets-signing-only.png
new file mode 100644
index 00000000..0bbf4246
Binary files /dev/null and b/img/dev/en-wallets-signing-only.png differ
diff --git a/img/dev/en-wallets-signing-only.svg b/img/dev/en-wallets-signing-only.svg
new file mode 100644
index 00000000..d533e215
--- /dev/null
+++ b/img/dev/en-wallets-signing-only.svg
@@ -0,0 +1,131 @@
+
+
+
+
+