diff --git a/_autocrossref.yaml b/_autocrossref.yaml index 1a5d94d0..24f4182e 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 protocol: "payment protocol's": payment protocol diff --git a/_config.yml b/_config.yml index e132fb0f..1851e5be 100644 --- a/_config.yml +++ b/_config.yml @@ -112,6 +112,13 @@ aliases: --author=Satoshi Nakamoto: Satoshi Nakamoto gavinandresen: Gavin Andresen tcatm: Nils Schneider + gmaxwell: Gregory Maxwell + sipa: Pieter Wuille + jgarzik: Jeff Garzik + petertodd: Peter Todd + luke-jr: Luke-Jr + laanwj: Wladimir J. van der Laan + mikehearn: Mike Hearn safe: false server_port: 4000 diff --git a/_contrib/comparelinks.rb b/_contrib/comparelinks.rb index 8e3b246b..33bbc6a3 100644 --- a/_contrib/comparelinks.rb +++ b/_contrib/comparelinks.rb @@ -3,12 +3,7 @@ ## Example: ruby ./_contrib/comparelinks.rb master newbranch > ../diff -WORKDIR = `mktemp -d` -WORKDIR.gsub!("\n",'') - -at_exit { - `rm -fr "#{WORKDIR}"` -} +require 'tmpdir' def prompt(*args) print(*args) @@ -52,43 +47,49 @@ def fetchlinks() end -# Copy current repository to a temporary directory -`rsync -a ./ "#{WORKDIR}/"` +Dir.mktmpdir{|workdir| -# Build both version of the website and fetch all links -oldlinks = {} -newlinks = {} + WORKDIR=workdir.gsub("\n",'') -Dir.chdir(WORKDIR) do + # Copy current repository to a temporary directory + `rsync -a ./ "#{WORKDIR}/"` - `git checkout #{srcbr}` - `jekyll` - oldlinks = fetchlinks() + # Build both version of the website and fetch all links + oldlinks = {} + newlinks = {} - `git checkout #{dstbr}` - `jekyll` - newlinks = fetchlinks() + Dir.chdir(WORKDIR) do -end + `git checkout #{srcbr}` + `jekyll` + oldlinks = fetchlinks() + + `git checkout #{dstbr}` + `jekyll` + newlinks = fetchlinks() + + end + + # Find added links, removed links + diffaddlinks = [] + diffrmlinks = [] + newlinks.each { |link, etag| + next if oldlinks.has_key?(link) + diffaddlinks.push(link) + } + oldlinks.each { |link, etag| + next if newlinks.has_key?(link) + diffrmlinks.push(link) + } + + # Display resulting diff + diff = '' + if diffaddlinks.length > 0 + diff = diff + "## links added\n\n" + diffaddlinks.join("\n") + "\n\n" + end + if diffrmlinks.length > 0 + diff = diff + "## links removed\n\n" + diffrmlinks.join("\n") + "\n\n" + end + print diff -# Find added links, removed links -diffaddlinks = [] -diffrmlinks = [] -newlinks.each { |link, etag| - next if oldlinks.has_key?(link) - diffaddlinks.push(link) } -oldlinks.each { |link, etag| - next if newlinks.has_key?(link) - diffrmlinks.push(link) -} - -# Display resulting diff -diff = '' -if diffaddlinks.length > 0 - diff = diff + "## links added\n\n" + diffaddlinks.join("\n") + "\n\n" -end -if diffrmlinks.length > 0 - diff = diff + "## links removed\n\n" + diffrmlinks.join("\n") + "\n\n" -end -print diff diff --git a/_events/2014-09-26-bitcoinconferencekiev.md b/_events/2014-09-26-bitcoinconferencekiev.md new file mode 100644 index 00000000..9d7f2db7 --- /dev/null +++ b/_events/2014-09-26-bitcoinconferencekiev.md @@ -0,0 +1,9 @@ +--- +date: 2014-09-26 +title: "Bitcoin Conference Kiev 2014" +venue: "Kiev Loft" +address: "Degtiarivska, 5" +city: "Kiev" +country: "Ukraine" +link: "http://bitcoinconf.com.ua/en/" +--- \ No newline at end of file diff --git a/_events/cryptolina b/_events/cryptolina new file mode 100644 index 00000000..246bbdb9 --- /dev/null +++ b/_events/cryptolina @@ -0,0 +1,9 @@ +--- +date: 2014-08-15 +title: "Cryptolina Bitcoin Conference" +venue: "Raleigh Convention Center" +address: "500 S Salisbury Street" +city: "Raleigh, NC" +country: "United States" +link: "http://www.cryptolina.com/" +--- diff --git a/_includes/guide_wallets.md b/_includes/guide_wallets.md index de895156..74de211d 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. + +![Full-Service Wallets](/img/dev/en-wallets-full-service.svg) + +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. + +![Signing-Only Wallets](/img/dev/en-wallets-signing-only.svg) + +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: + +![Distributing-Only Wallets](/img/dev/en-wallets-distributing-only.svg) + +* 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 + reuse], 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 + + + +wallet_program + +cluster_distributing + +Distributing-Only Wallet + +cluster_networked + +       Other Wallet(s) + + + +distributing_pub + +Derive +Child +Public +Keys + + + +distributing_distribute + +Distribute +Public +Keys + + + +distributing_pub->distributing_distribute + + + + + + +networked_monitor + +Monitor +For +Outputs + + +distributing_distribute->networked_monitor + + + + + + + + + + +networked_priv + +Create +Parent +Private +Key + + +networked_pub + +Derive +Parent +Public +Key + + +networked_priv->networked_pub + + + + + +networked_pub->distributing_pub + + + + + + + +networked_create + +Create +Unsigned +Txes + + +networked_monitor->networked_create + + + + + +networked_sign + +Sign +Txes + + + +networked_create->networked_sign + + + + +networked_broadcast + +Broadcast +Txes + + + +networked_sign->networked_broadcast + + + + + 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 @@ + + + + + + +wallet_program + +cluster_networked + + +Full-Service Wallet + + +networked_priv + +Create +Private +Keys + + +networked_pub + +Derive +Public +Keys + + +networked_priv->networked_pub + + + + +networked_distribute + +Distribute +Public +Keys + + +networked_pub->networked_distribute + + + + +networked_monitor + +Monitor +For +Outputs + + +networked_distribute->networked_monitor + + + + +networked_create + +Create +Unsigned +Txes + + +networked_monitor->networked_create + + + + +networked_sign + +Sign +Txes + + +networked_create->networked_sign + + + + +networked_broadcast + +Broadcast +Txes + + +networked_sign->networked_broadcast + + + + + 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 @@ + + + + + + +wallet_program + +cluster_signing + +Signing-Only Wallet + +cluster_networked + +Networked Wallet + + +signing_priv + +Create +Parent +Private +Key + + +signing_pub + +Derive +Parent +Public +Key + + + +signing_priv->signing_pub + + + + + + +networked_pub + +Derive +Child +Public +Keys + + +signing_pub->networked_pub + + + + + + + + +signing_sign + +Sign +Txes + + + + + +networked_broadcast + +Broadcast +Txes + + +signing_sign->networked_broadcast + + + + + + +networked_distribute + +Distribute +Public +Keys + + +networked_pub->networked_distribute + + + + + +networked_monitor + +Monitor +For +Outputs + + +networked_distribute->networked_monitor + + + + + +networked_create + +Create +Unsigned +Txes + + +networked_monitor->networked_create + + + + + +networked_create->signing_sign + + + + + + + +