The third edition of Mastering Bitcoin, written by David Harding for O'Reilly Media was published in December 2023. It is now also available under a CC-BY-NC-ND license, here.develop
@ -1 +0,0 @@
|
||||
*.asciidoc linguist-detectable
|
@ -0,0 +1,73 @@
|
||||
[[appdxbitcoinimpproposals]]
|
||||
[appendix]
|
||||
== Bitcoin Improvement Proposals
|
||||
|
||||
Bitcoin Improvement Proposals are design documents providing information to the Bitcoin community or describing a new feature for Bitcoin or its processes or environment.
|
||||
|
||||
As per BIP1 _BIP Purpose and Guidelines_, there are three((("BIPs (Bitcoin Improvement Proposals)", "types of"))) kinds of BIPs:
|
||||
|
||||
_Standard_ BIP:: Describes any change that affects most or all Bitcoin implementations, such as a change to the network protocol, a change in block or transaction validity rules, or any change or addition that affects the interoperability of applications using Bitcoin.
|
||||
_Informational_ BIP:: Describes a Bitcoin design issue or provides general guidelines or information to the Bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a Bitcoin community consensus or recommendation, so users and implementors may ignore informational BIPs or follow their advice.
|
||||
_Process_ BIP:: Describes a Bitcoin process or proposes a change to (or an event in) a process. Process BIPs are like standard BIPs but apply to areas other than the Bitcoin protocol itself. They might propose an implementation but not to Bitcoin's codebase; they often require community consensus. Unlike informational BIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Bitcoin development. Any meta-BIP is also considered a process BIP.
|
||||
|
||||
BIPs are recorded in a https://oreil.ly/jjO0R[versioned repository on GitHub].
|
||||
An MIT-licensed document from the open source Bitcoin Core project,
|
||||
reproduced here in edited form, describes which BIPs it implements, including listing
|
||||
the Pull Request (PR) and version of Bitcoin Core where support for each BIP was added or
|
||||
significantly changed.
|
||||
|
||||
BIPs that are ((("BIPs (Bitcoin Improvement Proposals)", "implemented by Bitcoin Core", id="bips-implement")))((("Bitcoin Core", "BIPs implemented by", id="bitcoin-core-bips")))implemented by Bitcoin Core:
|
||||
|
||||
- BIP9: The changes allowing multiple soft forks to be deployed in parallel have been implemented since v0.12.1 (PR #7575).
|
||||
- BIP11: Multisig outputs are standard since v0.6.0 (PR #669).
|
||||
- BIP13: The address format for P2SH addresses has been implemented since v0.6.0 (PR #669).
|
||||
- BIP14: The subversion string is being used as User Agent since v0.6.0 (PR #669).
|
||||
- BIP16: The pay-to-script-hash evaluation rules have been implemented since v0.6.0, and took effect on April 1st 2012 (PR #748).
|
||||
- BIP21: The URI format for Bitcoin payments has been implemented since v0.6.0 (PR #176).
|
||||
- BIP22: The 'getblocktemplate' (GBT) RPC protocol for mining has been implemented since v0.7.0 (PR #936).
|
||||
- BIP23: Some extensions to GBT have been implemented since v0.10.0rc1, including longpolling and block proposals (PR #1816).
|
||||
- BIP30: The evaluation rules to forbid creating new transactions with the same txid as previous not-fully-spent transactions were implemented since v0.6.0, and the rule took effect on March 15th 2012 (PR #915).
|
||||
- BIP31: The 'pong' protocol message (and the protocol version bump to 60001) has been implemented since v0.6.1 (PR #1081).
|
||||
- BIP32: Hierarchical Deterministic Wallets has been implemented since v0.13.0 (PR #8035).
|
||||
- BIP34: The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since v0.7.0. The rule took effect for version 2 blocks as of block 224413 (March 5th 2013), and version 1 blocks are no longer allowed since block 227931 (March 25th 2013) (PR #1526).
|
||||
- BIP35: The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since v0.7.0 (PR #1641). As of v0.13.0, this is only available for +NODE_BLOOM+ (BIP111) peers.
|
||||
|
||||
[role="less_space pagebreak-before"]
|
||||
- BIP37: The bloom filtering for transaction relaying, partial Merkle trees for blocks, and the protocol version bump to 70001 (enabling low-bandwidth lightweight clients) has been implemented since v0.8.0 (PR #1795). Disabled by default since v0.19.0, can be enabled by the +-peerbloomfilters+ option.
|
||||
- BIP42: The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in v0.9.2 (PR #3842).
|
||||
- BIP43: The experimental descriptor wallets introduced in v0.21.0 by default use the Hierarchical Deterministic Wallet derivation proposed by BIP43 (PR #16528).
|
||||
- BIP44: The experimental descriptor wallets introduced in v0.21.0 by default use the Hierarchical Deterministic Wallet derivation proposed by BIP44 (PR #16528).
|
||||
- BIP49: The experimental descriptor wallets introduced in v0.21.0 by default use the Hierarchical Deterministic Wallet derivation proposed by BIP49 (PR #16528).
|
||||
- BIP61: The 'reject' protocol message (and the protocol version bump to 70002) was added in v0.9.0 (PR #3185). Starting v0.17.0, whether to send reject messages can be configured with the ++-enablebip61++ option, and support is deprecated (disabled by default) as of v0.18.0. Support was removed in v0.20.0 (PR #15437).
|
||||
- BIP65: The ++CHECKLOCKTIMEVERIFY++ soft fork was merged in v0.12.0 (PR #6351), and backported to v0.11.2 and v0.10.4. Mempool-only +CLTV+ was added in PR #6124.
|
||||
- BIP66: The strict DER rules and associated version 3 blocks have been implemented since v0.10.0 (PR #5713).
|
||||
- BIP68: Sequence locks have been implemented as of v0.12.1 (PR #7184), and have been buried since v0.19.0 (PR #16060).
|
||||
- BIP70 71 72: Payment Protocol support has been available in Bitcoin Core GUI since v0.9.0 (PR #5216). Support can be optionally disabled at build time since v0.18.0 (PR 14451), and it is disabled by default at build time since v0.19.0 (PR #15584). It has been removed as of v0.20.0 (PR 17165).
|
||||
- BIP84: The experimental descriptor wallets introduced in v0.21.0 by default use the Hierarchical Deterministic Wallet derivation proposed by BIP84. (PR #16528)
|
||||
- BIP86: Descriptor wallets by default use the Hierarchical Deterministic Wallet derivation proposed by BIP86 since v23.0 (PR #22364).
|
||||
- BIP90: Trigger mechanism for activation of BIPs 34, 65, and 66 has been simplified to block height checks since v0.14.0 (PR #8391).
|
||||
- BIP111: +NODE_BLOOM+ service bit added and enforced for all peer versions as of v0.13.0 (PR #6579 and PR #6641).
|
||||
- BIP112: The +CHECKSEQUENCEVERIFY+ opcode has been implemented since v0.12.1 (PR #7524), and has been buried since v0.19.0 (PR #16060).
|
||||
- BIP113: Median time past lock-time calculations have been implemented since v0.12.1 (PR #6566), and has been buried since v0.19.0 (PR #16060).
|
||||
- BIP125: Opt-in full replace-by-fee signaling partially implemented.
|
||||
- BIP130: direct headers announcement is negotiated with peer versions ≥70012 as of v0.12.0 (PR 6494).
|
||||
- BIP133: feefilter messages are respected and sent for peer versions ≥70013 as of v0.13.0 (PR 7542).
|
||||
- BIP141: Segregated Witness (Consensus Layer) as of v0.13.0 (PR 8149), defined for mainnet as of v0.13.1 (PR 8937), and buried since v0.19.0 (PR #16060).
|
||||
- BIP143: Transaction Signature Verification for Version 0 Witness Program as of v0.13.0 (PR 8149), defined for mainnet as of v0.13.1 (PR 8937), and buried since v0.19.0 (PR #16060).
|
||||
- BIP144: Segregated Witness as of 0.13.0 (PR 8149).
|
||||
- BIP145: getblocktemplate updates for Segregated Witness as of v0.13.0 (PR 8149).
|
||||
- BIP147: +NULLDUMMY+ soft fork as of v0.13.1 (PR 8636 and PR 8937), buried since v0.19.0 (PR #16060).
|
||||
- BIP152: Compact block transfer and related optimizations are used as of v0.13.0 (PR 8068).
|
||||
- BIP155: The 'addrv2' and 'sendaddrv2' messages which enable relay of Tor V3 addresses (and other networks) are supported as of v0.21.0 (PR 19954).
|
||||
- BIP157 158: Compact Block Filters for Light Clients can be indexed as of v0.19.0 (PR #14121) and served to peers on the P2P network as of v0.21.0 (PR #16442).
|
||||
- BIP159: The +NODE_NETWORK_LIMITED+ service bit is signalled as of v0.16.0 (PR 11740), and such nodes are connected to as of v0.17.0 (PR 10387).
|
||||
- BIP173: Bech32 addresses for native Segregated Witness outputs are supported as of v0.16.0 (PR 11167). Bech32 addresses are generated by default as of v0.20.0 (PR 16884).
|
||||
- BIP174: RPCs to operate on Partially Signed Bitcoin Transactions (PSBT) are present as of v0.17.0 (PR 13557).
|
||||
- BIP176: Bits Denomination [QT only] is supported as of v0.16.0 (PR 12035).
|
||||
- BIP325: Signet test network is supported as of v0.21.0 (PR 18267).
|
||||
- BIP339: Relay of transactions by wtxid is supported as of v0.21.0 (PR 18044).
|
||||
- BIP340 341 342: Validation rules for Taproot (including Schnorr signatures and Tapscript leaves) are implemented as of v0.21.0 (PR 19953), with mainnet activation as of v0.21.1 (PR 21377, PR 21686).
|
||||
- BIP350: Addresses for native v1+ segregated Witness outputs use bech32m instead of bech32 as of v22.0 (PR 20861).
|
||||
- BIP371: Taproot fields for PSBT as of v24.0 (PR 22558).
|
||||
- BIP380 381 382 383 384 385: Output Script Descriptors, and most of Script Expressions are implemented as of v0.17.0 (PR 13697).
|
||||
- BIP386: +tr()+ Output Script Descriptors are implemented as((("BIPs (Bitcoin Improvement Proposals)", "implemented by Bitcoin Core", startref="bips-implement")))((("Bitcoin Core", "BIPs implemented by", startref="bitcoin-core-bips"))) of v22.0 (PR 22051).
|
@ -1,116 +0,0 @@
|
||||
[[appdxbitcoinimpproposals]]
|
||||
[appendix]
|
||||
== Bitcoin Improvement Proposals
|
||||
|
||||
((("bitcoin improvement proposals", "types of")))Bitcoin Improvement Proposals are design documents providing information to the bitcoin community, or for describing a new feature for bitcoin or its processes or environment.
|
||||
|
||||
As per BIP-01 _BIP Purpose and Guidelines_, there are three kinds of BIPs:
|
||||
|
||||
_Standard_ BIP:: Describes any change that affects most or all bitcoin implementations, such as a change to the network protocol, a change in block or transaction validity rules, or any change or addition that affects the interoperability of applications using bitcoin.
|
||||
_Informational_ BIP:: Describes a bitcoin design issue, or provides general guidelines or information to the bitcoin community, but does not propose a new feature. Informational BIPs do not necessarily represent a bitcoin community consensus or recommendation, so users and implementors may ignore informational BIPs or follow their advice.
|
||||
_Process_ BIP:: Describes a bitcoin process, or proposes a change to (or an event in) a process. Process BIPs are like standard BIPs but apply to areas other than the Bitcoin protocol itself. They might propose an implementation, but not to bitcoin's codebase; they often require community consensus; and unlike informational BIPs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in bitcoin development. Any meta-BIP is also considered a process BIP.
|
||||
|
||||
((("bitcoin improvement proposals", "repository of")))BIPs are recorded in a versioned repository on GitHub: https://github.com/bitcoin/bips[https://github.com/bitcoin/bips]. <<table_d-1>> shows a snapshot of the BIPs in April 2017. Consult the authoritative repository for up-to-date information on existing BIPs and their contents.((("bitcoin improvement proposals", "snapshot of", id="BIPsnap15")))
|
||||
|
||||
[[table_d-1]]
|
||||
.Snapshot of BIPs
|
||||
[options="header"]
|
||||
|=======================================================================
|
||||
|BIP# | Title |Owner |Type |Status
|
||||
|[[bip-1]]https://github.com/bitcoin/bips/blob/master/bip-0001.mediawiki[BIP-1] |BIP Purpose and Guidelines |Amir Taaki |Process |Replaced
|
||||
|[[bip-2]]https://github.com/bitcoin/bips/blob/master/bip-0002.mediawiki[BIP-2] |BIP process, revised |Luke Dashjr |Process |Active
|
||||
|[[bip-8]]https://github.com/bitcoin/bips/blob/master/bip-0008.mediawiki[BIP-8] |Version bits with guaranteed lock-in |Shaolin Fry |Informational |Draft
|
||||
|[[bip-9]]https://github.com/bitcoin/bips/blob/master/bip-0009.mediawiki[BIP-9] |Version bits with timeout and delay |Pieter Wuille, Peter Todd, Greg Maxwell, Rusty Russell |Informational |Final
|
||||
|[[bip-10]]https://github.com/bitcoin/bips/blob/master/bip-0010.mediawiki[BIP-10] |Multi-Sig Transaction Distribution |Alan Reiner |Informational |Withdrawn
|
||||
|[[bip-11]]https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki[BIP-11] |M-of-N Standard Transactions |Gavin Andresen |Standard |Final
|
||||
|[[bip-12]]https://github.com/bitcoin/bips/blob/master/bip-0012.mediawiki[BIP-12] |OP_EVAL |Gavin Andresen |Standard |Withdrawn
|
||||
|[[bip-13]]https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki[BIP-13] |Address Format for pay-to-script-hash |Gavin Andresen |Standard |Final
|
||||
|[[bip-14]]https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki[BIP-14] |Protocol Version and User Agent |Amir Taaki, Patrick Strateman |Standard |Final
|
||||
|[[bip-15]]https://github.com/bitcoin/bips/blob/master/bip-0015.mediawiki[BIP-15] |Aliases |Amir Taaki |Standard |Deferred
|
||||
|[[bip-16]]https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki[BIP-16] |Pay to Script Hash |Gavin Andresen |Standard |Final
|
||||
|[[bip-17]]https://github.com/bitcoin/bips/blob/master/bip-0017.mediawiki[BIP-17] |OP_CHECKHASHVERIFY (CHV) |Luke Dashjr |Standard |Withdrawn
|
||||
|[[bip-18]]https://github.com/bitcoin/bips/blob/master/bip-0018.mediawiki[BIP-18] |hashScriptCheck |Luke Dashjr |Standard |Proposed
|
||||
|[[bip-19]]https://github.com/bitcoin/bips/blob/master/bip-0019.mediawiki[BIP-19] |M-of-N Standard Transactions (Low SigOp) |Luke Dashjr |Standard |Draft
|
||||
|[[bip-20]]https://github.com/bitcoin/bips/blob/master/bip-0020.mediawiki[BIP-20] |URI Scheme |Luke Dashjr |Standard |Replaced
|
||||
|[[bip-21]]https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki[BIP-21] |URI Scheme |Nils Schneider, Matt Corallo |Standard |Final
|
||||
|[[bip-22]]https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki[BIP-22] |getblocktemplate - Fundamentals |Luke Dashjr |Standard |Final
|
||||
|[[bip-23]]https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki[BIP-23] |getblocktemplate - Pooled Mining |Luke Dashjr |Standard |Final
|
||||
|[[bip-30]]https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki[BIP-30] |Duplicate transactions |Pieter Wuille |Standard |Final
|
||||
|[[bip-31]]https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki[BIP-31] |Pong message |Mike Hearn |Standard |Final
|
||||
|[[bip-32]]https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki[BIP-32] |Hierarchical Deterministic Wallets |Pieter Wuille |Informational |Final
|
||||
|[[bip-33]]https://github.com/bitcoin/bips/blob/master/bip-0033.mediawiki[BIP-33] |Stratized Nodes |Amir Taaki |Standard |Draft
|
||||
|[[bip-34]]https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki[BIP-34] |Block v2, Height in Coinbase |Gavin Andresen |Standard |Final
|
||||
|[[bip-35]]https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki[BIP-35] |mempool message |Jeff Garzik |Standard |Final
|
||||
|[[bip-36]]https://github.com/bitcoin/bips/blob/master/bip-0036.mediawiki[BIP-36] |Custom Services |Stefan Thomas |Standard |Draft
|
||||
|[[bip-37]]https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki[BIP-37] |Connection Bloom filtering |Mike Hearn, Matt Corallo |Standard |Final
|
||||
|[[bip-39]]https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki[BIP-39] |Mnemonic code for generating deterministic keys |Marek Palatinus, Pavol Rusnak, Aaron Voisine, Sean Bowe |Standard |Proposed
|
||||
|[[bip-40]]https://github.com/bitcoin/bips/blob/master/bip-0040.mediawiki[BIP-40] |Stratum wire protocol |Marek Palatinus |Standard |BIP number allocated
|
||||
|[[bip-41]]https://github.com/bitcoin/bips/blob/master/bip-0041.mediawiki[BIP-41] |Stratum mining protocol |Marek Palatinus |Standard |BIP number allocated
|
||||
|[[bip-42]]https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki[BIP-42] |A finite monetary supply for Bitcoin |Pieter Wuille |Standard |Draft
|
||||
|[[bip-43]]https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki[BIP-43] |Purpose Field for Deterministic Wallets |Marek Palatinus, Pavol Rusnak |Informational |Draft
|
||||
|[[bip-44]]https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki[BIP-44] |Multi-Account Hierarchy for Deterministic Wallets |Marek Palatinus, Pavol Rusnak |Standard |Proposed
|
||||
|[[bip-45]]https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki[BIP-45] |Structure for Deterministic P2SH Multisignature Wallets |Manuel Araoz, Ryan X. Charles, Matias Alejo Garcia |Standard |Proposed
|
||||
|[[bip-47]]https://github.com/bitcoin/bips/blob/master/bip-0047.mediawiki[BIP-47] |Reusable Payment Codes for Hierarchical Deterministic Wallets |Justus Ranvier |Informational |Draft
|
||||
|[[bip-49]]https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki[BIP-49] |Derivation scheme for P2WPKH-nested-in-P2SH based accounts |Daniel Weigl |Informational |Draft
|
||||
|[[bip-50]]https://github.com/bitcoin/bips/blob/master/bip-0050.mediawiki[BIP-50] |March 2013 Chain Fork Post-Mortem |Gavin Andresen |Informational |Final
|
||||
|[[bip-60]]https://github.com/bitcoin/bips/blob/master/bip-0060.mediawiki[BIP-60] |Fixed Length "version" Message (Relay-Transactions Field) |Amir Taaki |Standard |Draft
|
||||
|[[bip-61]]https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki[BIP-61] |Reject P2P message |Gavin Andresen |Standard |Final
|
||||
|[[bip-62]]https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki[BIP-62] |Dealing with malleability |Pieter Wuille |Standard |Withdrawn
|
||||
|[[bip-63]]https://github.com/bitcoin/bips/blob/master/bip-0063.mediawiki[BIP-63] |Stealth Addresses |Peter Todd |Standard |BIP number allocated
|
||||
|[[bip-64]]https://github.com/bitcoin/bips/blob/master/bip-0064.mediawiki[BIP-64] |getutxo message |Mike Hearn |Standard |Draft
|
||||
|[[bip-65]]https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki[BIP-65] |OP_CHECKLOCKTIMEVERIFY |Peter Todd |Standard |Final
|
||||
|[[bip-66]]https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki[BIP-66] |Strict DER signatures |Pieter Wuille |Standard |Final
|
||||
|[[bip-67]]https://github.com/bitcoin/bips/blob/master/bip-0067.mediawiki[BIP-67] |Deterministic Pay-to-script-hash multi-signature addresses through public key sorting |Thomas Kerin, Jean-Pierre Rupp, Ruben de Vries |Standard |Proposed
|
||||
|[[bip-68]]https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki[BIP-68] |Relative lock-time using consensus-enforced sequence numbers |Mark Friedenbach, BtcDrak, Nicolas Dorier, kinoshitajona |Standard |Final
|
||||
|[[bip-69]]https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki[BIP-69] |Lexicographical Indexing of Transaction Inputs and Outputs |Kristov Atlas |Informational |Proposed
|
||||
|[[bip-70]]https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki[BIP-70] |Payment Protocol |Gavin Andresen, Mike Hearn |Standard |Final
|
||||
|[[bip-71]]https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki[BIP-71] |Payment Protocol MIME types |Gavin Andresen |Standard |Final
|
||||
|[[bip-72]]https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki[BIP-72] |bitcoin: uri extensions for Payment Protocol |Gavin Andresen |Standard |Final
|
||||
|[[bip-73]]https://github.com/bitcoin/bips/blob/master/bip-0073.mediawiki[BIP-73] |Use "Accept" header for response type negotiation with Payment Request URLs |Stephen Pair |Standard |Final
|
||||
|[[bip-74]]https://github.com/bitcoin/bips/blob/master/bip-0074.mediawiki[BIP-74] |Allow zero value OP_RETURN in Payment Protocol |Toby Padilla |Standard |Draft
|
||||
|[[bip-75]]https://github.com/bitcoin/bips/blob/master/bip-0075.mediawiki[BIP-75] |Out of Band Address Exchange using Payment Protocol Encryption |Justin Newton, Matt David, Aaron Voisine, James MacWhyte |Standard |Draft
|
||||
|[[bip-80]]https://github.com/bitcoin/bips/blob/master/bip-0080.mediawiki[BIP-80] |Hierarchy for Non-Colored Voting Pool Deterministic Multisig Wallets |Justus Ranvier, Jimmy Song |Informational |Deferred
|
||||
|[[bip-81]]https://github.com/bitcoin/bips/blob/master/bip-0081.mediawiki[BIP-81] |Hierarchy for Colored Voting Pool Deterministic Multisig Wallets |Justus Ranvier, Jimmy Song |Informational |Deferred
|
||||
|[[bip-83]]https://github.com/bitcoin/bips/blob/master/bip-0083.mediawiki[BIP-83] |Dynamic Hierarchical Deterministic Key Trees |Eric Lombrozo |Standard |Draft
|
||||
|[[bip-90]]https://github.com/bitcoin/bips/blob/master/bip-0090.mediawiki[BIP-90] |Buried Deployments |Suhas Daftuar |Informational |Draft
|
||||
|[[bip-99]]https://github.com/bitcoin/bips/blob/master/bip-0099.mediawiki[BIP-99] |Motivation and deployment of consensus rule changes ([soft/hard]forks) |Jorge Timón |Informational |Draft
|
||||
|[[bip-101]]https://github.com/bitcoin/bips/blob/master/bip-0101.mediawiki[BIP-101] |Increase maximum block size |Gavin Andresen |Standard |Withdrawn
|
||||
|[[bip-102]]https://github.com/bitcoin/bips/blob/master/bip-0102.mediawiki[BIP-102] |Block size increase to 2MB |Jeff Garzik |Standard |Draft
|
||||
|[[bip-103]]https://github.com/bitcoin/bips/blob/master/bip-0103.mediawiki[BIP-103] |Block size following technological growth |Pieter Wuille |Standard |Draft
|
||||
|[[bip-104]]https://github.com/bitcoin/bips/blob/master/bip-0104.mediawiki[BIP-104] |'Block75' - Max block size like difficulty |t.khan |Standard |Draft
|
||||
|[[bip-105]]https://github.com/bitcoin/bips/blob/master/bip-0105.mediawiki[BIP-105] |Consensus based block size retargeting algorithm |BtcDrak |Standard |Draft
|
||||
|[[bip-106]]https://github.com/bitcoin/bips/blob/master/bip-0106.mediawiki[BIP-106] |Dynamically Controlled Bitcoin Block Size Max Cap |Upal Chakraborty |Standard |Draft
|
||||
|[[bip-107]]https://github.com/bitcoin/bips/blob/master/bip-0107.mediawiki[BIP-107] |Dynamic limit on the block size |Washington Y. Sanchez |Standard |Draft
|
||||
|[[bip-109]]https://github.com/bitcoin/bips/blob/master/bip-0109.mediawiki[BIP-109] |Two million byte size limit with sigop and sighash limits |Gavin Andresen |Standard |Rejected
|
||||
|[[bip-111]]https://github.com/bitcoin/bips/blob/master/bip-0111.mediawiki[BIP-111] |NODE_BLOOM service bit |Matt Corallo, Peter Todd |Standard |Proposed
|
||||
|[[bip-112]]https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki[BIP-112] |CHECKSEQUENCEVERIFY |BtcDrak, Mark Friedenbach, Eric Lombrozo |Standard |Final
|
||||
|[[bip-113]]https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki[BIP-113] |Median time-past as endpoint for lock-time calculations |Thomas Kerin, Mark Friedenbach |Standard |Final
|
||||
|[[bip-114]]https://github.com/bitcoin/bips/blob/master/bip-0114.mediawiki[BIP-114] |Merkelized Abstract Syntax Tree |Johnson Lau |Standard |Draft
|
||||
|[[bip-120]]https://github.com/bitcoin/bips/blob/master/bip-0120.mediawiki[BIP-120] |Proof of Payment |Kalle Rosenbaum |Standard |Draft
|
||||
|[[bip-121]]https://github.com/bitcoin/bips/blob/master/bip-0121.mediawiki[BIP-121] |Proof of Payment URI scheme |Kalle Rosenbaum |Standard |Draft
|
||||
|[[bip-122]]https://github.com/bitcoin/bips/blob/master/bip-0122.mediawiki[BIP-122] |URI scheme for Blockchain references / exploration |Marco Pontello |Standard |Draft
|
||||
|[[bip-123]]https://github.com/bitcoin/bips/blob/master/bip-0123.mediawiki[BIP-123] |BIP Classification |Eric Lombrozo |Process |Active
|
||||
|[[bip-124]]https://github.com/bitcoin/bips/blob/master/bip-0124.mediawiki[BIP-124] |Hierarchical Deterministic Script Templates |Eric Lombrozo, William Swanson |Informational |Draft
|
||||
|[[bip-125]]https://github.com/bitcoin/bips/blob/master/bip-0125.mediawiki[BIP-125] |Opt-in Full Replace-by-Fee Signaling |David A. Harding, Peter Todd |Standard |Proposed
|
||||
|[[bip-126]]https://github.com/bitcoin/bips/blob/master/bip-0126.mediawiki[BIP-126] |Best Practices for Heterogeneous Input Script Transactions |Kristov Atlas |Informational |Draft
|
||||
|[[bip-130]]https://github.com/bitcoin/bips/blob/master/bip-0130.mediawiki[BIP-130] |sendheaders message |Suhas Daftuar |Standard |Proposed
|
||||
|[[bip-131]]https://github.com/bitcoin/bips/blob/master/bip-0131.mediawiki[BIP-131] |"Coalescing Transaction" Specification (wildcard inputs) |Chris Priest |Standard |Draft
|
||||
|[[bip-132]]https://github.com/bitcoin/bips/blob/master/bip-0132.mediawiki[BIP-132] |Committee-based BIP Acceptance Process |Andy Chase |Process |Withdrawn
|
||||
|[[bip-133]]https://github.com/bitcoin/bips/blob/master/bip-0133.mediawiki[BIP-133] |feefilter message |Alex Morcos |Standard |Draft
|
||||
|[[bip-134]]https://github.com/bitcoin/bips/blob/master/bip-0134.mediawiki[BIP-134] |Flexible Transactions |Tom Zander |Standard |Draft
|
||||
|[[bip-140]]https://github.com/bitcoin/bips/blob/master/bip-0140.mediawiki[BIP-140] |Normalized TXID |Christian Decker |Standard |Draft
|
||||
|[[bip-141]]https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki[BIP-141] |Segregated Witness (Consensus layer) |Eric Lombrozo, Johnson Lau, Pieter Wuille |Standard |Draft
|
||||
|[[bip-142]]https://github.com/bitcoin/bips/blob/master/bip-0142.mediawiki[BIP-142] |Address Format for Segregated Witness |Johnson Lau |Standard |Deferred
|
||||
|[[bip-143]]https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki[BIP-143] |Transaction Signature Verification for Version 0 Witness Program |Johnson Lau, Pieter Wuille |Standard |Draft
|
||||
|[[bip-144]]https://github.com/bitcoin/bips/blob/master/bip-0144.mediawiki[BIP-144] |Segregated Witness (Peer Services) |Eric Lombrozo, Pieter Wuille |Standard |Draft
|
||||
|[[bip-145]]https://github.com/bitcoin/bips/blob/master/bip-0145.mediawiki[BIP-145] |getblocktemplate Updates for Segregated Witness |Luke Dashjr |Standard |Draft
|
||||
|[[bip-146]]https://github.com/bitcoin/bips/blob/master/bip-0146.mediawiki[BIP-146] |Dealing with signature encoding malleability |Johnson Lau, Pieter Wuille |Standard |Draft
|
||||
|[[bip-147]]https://github.com/bitcoin/bips/blob/master/bip-0147.mediawiki[BIP-147] |Dealing with dummy stack element malleability |Johnson Lau |Standard |Draft
|
||||
|[[bip-148]]https://github.com/bitcoin/bips/blob/master/bip-0148.mediawiki[BIP-148] |Mandatory activation of segwit deployment |Shaolin Fry |Standard |Draft
|
||||
|[[bip-150]]https://github.com/bitcoin/bips/blob/master/bip-0150.mediawiki[BIP-150] |Peer Authentication |Jonas Schnelli |Standard |Draft
|
||||
|[[bip-151]]https://github.com/bitcoin/bips/blob/master/bip-0151.mediawiki[BIP-151] |Peer-to-Peer Communication Encryption |Jonas Schnelli |Standard |Draft
|
||||
|[[bip-152]]https://github.com/bitcoin/bips/blob/master/bip-0152.mediawiki[BIP-152] |Compact Block Relay |Matt Corallo |Standard |Draft
|
||||
|[[bip-171]]https://github.com/bitcoin/bips/blob/master/bip-0171.mediawiki[BIP-171] |Currency/exchange rate information API |Luke Dashjr |Standard |Draft
|
||||
|[[bip-180]]https://github.com/bitcoin/bips/blob/master/bip-0180.mediawiki[BIP-180] |Block size/weight fraud proof |Luke Dashjr |Standard |Draft
|
||||
|[[bip-199]]https://github.com/bitcoin/bips/blob/master/bip-0199.mediawiki[BIP-199] |Hashed Time-Locked Contract transactions |Sean Bowe, Daira Hopwood |Standard |Draft((("", startref="BIPsnap15")))
|
||||
|=======================================================================
|
@ -1,116 +0,0 @@
|
||||
[[appdx_bitcore]]
|
||||
[appendix]
|
||||
|
||||
== Bitcore
|
||||
|
||||
|
||||
((("Bitcore", id="bitcore16")))Bitcore is a suite of tools provided by BitPay. Its goal is to provide easy-to-use tools for Bitcoin developers. Almost all of Bitcore's code is written in JavaScript. There are some modules written specifically for NodeJS. Finally, the "node" module of Bitcore includes Bitcoin Core's C++ code. Please see https://bitcore.io for more information.
|
||||
|
||||
=== Bitcore's Feature List
|
||||
|
||||
* Bitcoin full node (bitcore-node)
|
||||
* Block explorer (insight)
|
||||
* Block, transaction, and wallet utilities (bitcore-lib)
|
||||
* Communicating directly with Bitcoin's P2P network (bitcore-p2p)
|
||||
* Seed entropy mnemonic generation (bitcore-mnemonic)
|
||||
* Payment protocol (bitcore-payment-protocol)
|
||||
* Message verification and signing (bitcore-message)
|
||||
* Elliptic curve Integrated Encryption Scheme (bitcore-ecies)
|
||||
* Wallet service (bitcore-wallet-service)
|
||||
* Wallet client (bitcore-wallet-client)
|
||||
* Integrating services directly with Bitcoin Core (bitcore-node)
|
||||
|
||||
=== Bitcore Library Examples
|
||||
|
||||
==== Prerequisites
|
||||
|
||||
* NodeJS >= 4.x
|
||||
|
||||
If using NodeJS and the node REPL:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ npm install -g bitcore-lib bitcore-p2p
|
||||
----
|
||||
|
||||
==== Wallet Examples using bitcore-lib
|
||||
|
||||
Creating a new Bitcoin address with associated private key:
|
||||
|
||||
----
|
||||
> bitcore = require('bitcore-lib')
|
||||
> privateKey = new bitcore.PrivateKey()
|
||||
> address = privateKey.toAddress().toString()
|
||||
----
|
||||
|
||||
Creating a hierarchical deterministic private key and address:
|
||||
|
||||
----
|
||||
> hdPrivateKey = bitcore.HDPrivateKey()
|
||||
> hdPublicKey = bitcore.HDPublicKey(hdPrivateKey)
|
||||
> hdAddress = new bitcore.Address(hdPublicKey.publicKey).toString()
|
||||
----
|
||||
|
||||
Creating and signing a transaction from an UTXO:
|
||||
|
||||
----
|
||||
> utxo = {
|
||||
txId: txId, // transaction id containing an unspent output
|
||||
outputIndex: outputIndex, // output index (e.g. 0)
|
||||
address: addressOfUtxo,
|
||||
script: bitcore.Script.buildPublicKeyHashOut(addressOfUtxo).toString(),
|
||||
satoshis: satoshis // amount sent to the address
|
||||
}
|
||||
> fee = 3000 //set appropriately for conditions on the network
|
||||
> tx = new bitcore.Transaction()
|
||||
.from(utxo)
|
||||
.to(address, 35000)
|
||||
.fee(fee)
|
||||
.enableRBF()
|
||||
.sign(privateKeyOfUtxo)
|
||||
----
|
||||
|
||||
Replace the last transaction in the mempool (replace-by-fee):
|
||||
|
||||
----
|
||||
> rbfTx = new Transaction()
|
||||
.from(utxo)
|
||||
.to(address, 35000)
|
||||
.fee(fee*2)
|
||||
.enableRBF()
|
||||
.sign(privateKeyOfUtxo);
|
||||
> tx.serialize();
|
||||
> rbfTx.serialize();
|
||||
----
|
||||
|
||||
Broadcasting a transaction to the Bitcoin network
|
||||
(note: broadcast valid transactions only; refer to https://bitnodes.21.co/nodes[] for peer hosts):
|
||||
|
||||
1. Copy the code below into a file called _broadcast.js_.
|
||||
2. The +tx+ and +rbfTx+ variables are the output of +tx.serialize()+ and +rbfTx.serialize()+, respectively.
|
||||
3. In order to replace-by-fee, the peer must support bitcoind option +mempoolreplace+ and have it set to +1+.
|
||||
4. Run the file node _broadcast.js_((("", startref="bitcore16"))):
|
||||
|
||||
----
|
||||
var p2p = require('bitcore-p2p');
|
||||
var bitcore = require('bitcore-lib');
|
||||
var tx = new bitcore.Transaction('output from serialize function');
|
||||
var rbfTx = new bitcore.Transaction('output from serialize function');
|
||||
var host = 'ip address'; //use valid peer listening on tcp 8333
|
||||
var peer = new p2p.Peer({host: host});
|
||||
var messages = new p2p.Messages();
|
||||
peer.on('ready', function() {
|
||||
var txs = [messages.Transaction(tx), messages.Transaction(rbfTx)];
|
||||
var index = 0;
|
||||
var interval = setInterval(function() {
|
||||
peer.sendMessage(txs[index++]);
|
||||
console.log('tx: ' + index + ' sent');
|
||||
if (index === txs.length) {
|
||||
clearInterval(interval);
|
||||
console.log('disconnecting from peer: ' + host);
|
||||
peer.disconnect();
|
||||
}
|
||||
}, 2000);
|
||||
});
|
||||
peer.connect();
|
||||
----
|
@ -1,181 +0,0 @@
|
||||
[[appdx_bx]]
|
||||
[appendix]
|
||||
|
||||
== Bitcoin Explorer (bx) Commands
|
||||
|
||||
((("Bitcoin Explorer (bx) commands", id="BX18_1", range="startofrange")))Bitcoin Explorer (bx) is a command-line tool that offers a variety of commands for key management and transaction construction. It is part of the libbitcoin bitcoin library.
|
||||
|
||||
----
|
||||
Usage: bx COMMAND [--help]
|
||||
|
||||
Info: The bx commands are:
|
||||
|
||||
address-decode
|
||||
address-embed
|
||||
address-encode
|
||||
address-validate
|
||||
base16-decode
|
||||
base16-encode
|
||||
base58-decode
|
||||
base58-encode
|
||||
base58check-decode
|
||||
base58check-encode
|
||||
base64-decode
|
||||
base64-encode
|
||||
bitcoin160
|
||||
bitcoin256
|
||||
btc-to-satoshi
|
||||
ec-add
|
||||
ec-add-secrets
|
||||
ec-multiply
|
||||
ec-multiply-secrets
|
||||
ec-new
|
||||
ec-to-address
|
||||
ec-to-public
|
||||
ec-to-wif
|
||||
fetch-balance
|
||||
fetch-header
|
||||
fetch-height
|
||||
fetch-history
|
||||
fetch-stealth
|
||||
fetch-tx
|
||||
fetch-tx-index
|
||||
hd-new
|
||||
hd-private
|
||||
hd-public
|
||||
hd-to-address
|
||||
hd-to-ec
|
||||
hd-to-public
|
||||
hd-to-wif
|
||||
help
|
||||
input-set
|
||||
input-sign
|
||||
input-validate
|
||||
message-sign
|
||||
message-validate
|
||||
mnemonic-decode
|
||||
mnemonic-encode
|
||||
ripemd160
|
||||
satoshi-to-btc
|
||||
script-decode
|
||||
script-encode
|
||||
script-to-address
|
||||
seed
|
||||
send-tx
|
||||
send-tx-node
|
||||
send-tx-p2p
|
||||
settings
|
||||
sha160
|
||||
sha256
|
||||
sha512
|
||||
stealth-decode
|
||||
stealth-encode
|
||||
stealth-public
|
||||
stealth-secret
|
||||
stealth-shared
|
||||
tx-decode
|
||||
tx-encode
|
||||
uri-decode
|
||||
uri-encode
|
||||
validate-tx
|
||||
watch-address
|
||||
wif-to-ec
|
||||
wif-to-public
|
||||
wrap-decode
|
||||
wrap-encode
|
||||
----
|
||||
|
||||
For more information, see the https://github.com/libbitcoin/libbitcoin-explorer[Bitcoin Explorer homepage] and https://github.com/libbitcoin/libbitcoin-explorer/wiki[Bitcoin Explorer user documentation].
|
||||
|
||||
=== Examples of bx Command Use
|
||||
|
||||
Let's look at some examples of using Bitcoin Explorer commands to experiment with keys and addresses.
|
||||
|
||||
Generate a random "seed" value using the +seed+ command, which uses the operating system's random number generator. Pass the seed to the +ec-new+ command to generate a new private key. We save the standard output into the file _private_key_:
|
||||
|
||||
----
|
||||
$ bx seed | bx ec-new > private_key
|
||||
$ cat private_key
|
||||
73096ed11ab9f1db6135857958ece7d73ea7c30862145bcc4bbc7649075de474
|
||||
----
|
||||
|
||||
Now, generate the public key from that private key using the +ec-to-public+ command. We pass the _private_key_ file into the standard input and save the standard output of the command into a new file _public_key_:
|
||||
|
||||
----
|
||||
$ bx ec-to-public < private_key > public_key
|
||||
$ cat public_key
|
||||
02fca46a6006a62dfdd2dbb2149359d0d97a04f430f12a7626dd409256c12be500
|
||||
----
|
||||
|
||||
We can reformat the +public_key+ as an address using the +ec-to-address+ command. We pass the _public_key_ into standard input:
|
||||
|
||||
----
|
||||
$ bx ec-to-address < public_key
|
||||
17re1S4Q8ZHyCP8Kw7xQad1Lr6XUzWUnkG
|
||||
----
|
||||
|
||||
Keys generated in this manner produce a type-0 nondeterministic wallet. That means that each key is generated from an independent seed. Bitcoin Explorer commands can also generate keys deterministically, in accordance with BIP-32. In this case, a "master" key is created from a seed and then extended deterministically to produce a tree of subkeys, resulting in a type-2 deterministic wallet.
|
||||
|
||||
First, we use the +seed+ and +hd-new+ commands to generate a master key that will be used as the basis to derive a hierarchy of keys:
|
||||
|
||||
----
|
||||
$ bx seed > seed
|
||||
$ cat seed
|
||||
eb68ee9f3df6bd4441a9feadec179ff1
|
||||
|
||||
$ bx hd-new < seed > master
|
||||
$ cat master
|
||||
xprv9s21ZrQH143K2BEhMYpNQoUvAgiEjArAVaZaCTgsaGe6LsAnwubeiTcDzd23mAoyizm9cApe51gNfLMkBqkYoWWMCRwzfuJk8RwF1SVEpAQ
|
||||
----
|
||||
|
||||
We now use the +hd-private+ command to generate a hardened "account" key and a sequence of two private keys within the account:
|
||||
|
||||
----
|
||||
$ bx hd-private --hard < master > account
|
||||
$ cat account
|
||||
xprv9vkDLt81dTKjwHB8fsVB5QK8cGnzveChzSrtCfvu3aMWvQaThp59ueufuyQ8Qi3qpjk4aKsbmbfxwcgS8PYbgoR2NWHeLyvg4DhoEE68A1n
|
||||
|
||||
$ bx hd-private --index 0 < account
|
||||
xprv9xHfb6w1vX9xgZyPNXVgAhPxSsEkeRcPHEUV5iJcVEsuUEACvR3NRY3fpGhcnBiDbvG4LgndirDsia1e9F3DWPkX7Tp1V1u97HKG1FJwUpU
|
||||
|
||||
$ bx hd-private --index 1 < account
|
||||
xprv9xHfb6w1vX9xjc8XbN4GN86jzNAZ6xHEqYxzbLB4fzHFd6VqCLPGRZFsdjsuMVERadbgDbziCRJru9n6tzEWrASVpEdrZrFidt1RDfn4yA3
|
||||
----
|
||||
|
||||
Next, we use the +hd-public+ command to generate the corresponding sequence of two public keys:
|
||||
|
||||
----
|
||||
$ bx hd-public --index 0 < account
|
||||
xpub6BH1zcTuktiFu43rUZ2gXqLgzu5F3tLEeTQ5t6iE3aQtM2VMTxMcyLN9fYHiGhGpQe9QQYmqL2eYPFJ3vezHz5wzaSW4FiGrseNDR4LKqTy
|
||||
|
||||
$ bx hd-public --index 1 < account
|
||||
xpub6BH1zcTuktiFx6CzhPbGjG3UYQ13WR16CmtbPiagEKpEVtpyjshWyMaMV1cn7nUPUkgQHPVXJVqsrA8xWbGQDhohEcDFTEYMvYzwRD7Juf8
|
||||
----
|
||||
|
||||
The public keys can also be derived from their corresponding private keys using the +hd-to-public+ command:
|
||||
|
||||
----
|
||||
$ bx hd-private --index 0 < account | bx hd-to-public
|
||||
xpub6BH1zcTuktiFu43rUZ2gXqLgzu5F3tLEeTQ5t6iE3aQtM2VMTxMcyLN9fYHiGhGpQe9QQYmqL2eYPFJ3vezHz5wzaSW4FiGrseNDR4LKqTy
|
||||
|
||||
$ bx hd-private --index 1 < account | bx hd-to-public
|
||||
xpub6BH1zcTuktiFx6CzhPbGjG3UYQ13WR16CmtbPiagEKpEVtpyjshWyMaMV1cn7nUPUkgQHPVXJVqsrA8xWbGQDhohEcDFTEYMvYzwRD7Juf8
|
||||
----
|
||||
|
||||
We can generate a practically limitless number of keys in a deterministic chain, all derived from a single seed. This technique is used in many wallet applications to generate keys that can be backed up and restored with a single seed value. This is easier than having to back up the wallet with all its randomly generated keys every time a new key is created.
|
||||
|
||||
The seed can be encoded using the +mnemonic-encode+ command:
|
||||
|
||||
----
|
||||
$ bx hd-mnemonic < seed > words
|
||||
adore repeat vision worst especially veil inch woman cast recall dwell appreciate
|
||||
----
|
||||
|
||||
The seed can then be decoded using the +mnemonic-decode+ command:
|
||||
|
||||
----
|
||||
$ bx mnemonic-decode < words
|
||||
eb68ee9f3df6bd4441a9feadec179ff1
|
||||
----
|
||||
|
||||
Mnemonic encoding can make the seed easier to record and even remember.(((range="endofrange", startref="BX18_1")))
|
@ -1,424 +0,0 @@
|
||||
[[appdx-pycoin]]
|
||||
[appendix]
|
||||
== pycoin, ku, and tx
|
||||
|
||||
|
||||
((("pycoin library")))The Python library https://github.com/richardkiss/pycoin[+pycoin+], originally written and maintained by Richard Kiss, is a Python-based library that supports manipulation of bitcoin keys and transactions, even supporting the scripting language enough to properly deal with nonstandard transactions.
|
||||
|
||||
The pycoin library supports both Python 2 (2.7.x) and Python 3 (3.3 and later) and comes with some handy command-line utilities, +ku+ and +tx+.
|
||||
|
||||
=== Key Utility (KU)
|
||||
|
||||
((("key utility (ku)", id="keyutil17")))The command-line utility +ku+ ("key utility") is a Swiss Army knife for manipulating keys. It supports BIP-32 keys, WIF, and addresses (bitcoin and alt coins). Following are some examples.
|
||||
|
||||
Create a BIP-32 key using the default entropy sources of GPG and _/dev/random_:
|
||||
|
||||
|
||||
----
|
||||
$ ku create
|
||||
|
||||
input : create
|
||||
network : Bitcoin
|
||||
wallet key : xprv9s21ZrQH143K3LU5ctPZTBnb9kTjA5Su9DcWHvXJemiJBsY7VqXUG7hipgdWaU
|
||||
m2nhnzdvxJf5KJo9vjP2nABX65c5sFsWsV8oXcbpehtJi
|
||||
public version : xpub661MyMwAqRbcFpYYiuvZpKjKhnJDZYAkWSY76JvvD7FH4fsG3Nqiov2CfxzxY8
|
||||
DGcpfT56AMFeo8M8KPkFMfLUtvwjwb6WPv8rY65L2q8Hz
|
||||
tree depth : 0
|
||||
fingerprint : 9d9c6092
|
||||
parent f'print : 00000000
|
||||
child index : 0
|
||||
chain code : 80574fb260edaa4905bc86c9a47d30c697c50047ed466c0d4a5167f6821e8f3c
|
||||
private key : yes
|
||||
secret exponent : 112471538590155650688604752840386134637231974546906847202389294096567806844862
|
||||
hex : f8a8a28b28a916e1043cc0aca52033a18a13cab1638d544006469bc171fddfbe
|
||||
wif : L5Z54xi6qJusQT42JHA44mfPVZGjyb4XBRWfxAzUWwRiGx1kV4sP
|
||||
uncompressed : 5KhoEavGNNH4GHKoy2Ptu4KfdNp4r56L5B5un8FP6RZnbsz5Nmb
|
||||
public pair x : 76460638240546478364843397478278468101877117767873462127021560368290114016034
|
||||
public pair y : 59807879657469774102040120298272207730921291736633247737077406753676825777701
|
||||
x as hex : a90b3008792432060fa04365941e09a8e4adf928bdbdb9dad41131274e379322
|
||||
y as hex : 843a0f6ed9c0eb1962c74533795406914fe3f1957c5238951f4fe245a4fcd625
|
||||
y parity : odd
|
||||
key pair as sec : 03a90b3008792432060fa04365941e09a8e4adf928bdbdb9dad41131274e379322
|
||||
uncompressed : 04a90b3008792432060fa04365941e09a8e4adf928bdbdb9dad41131274e379322
|
||||
843a0f6ed9c0eb1962c74533795406914fe3f1957c5238951f4fe245a4fcd625
|
||||
hash160 : 9d9c609247174ae323acfc96c852753fe3c8819d
|
||||
uncompressed : 8870d869800c9b91ce1eb460f4c60540f87c15d7
|
||||
Bitcoin address : 1FNNRQ5fSv1wBi5gyfVBs2rkNheMGt86sp
|
||||
uncompressed : 1DSS5isnH4FsVaLVjeVXewVSpfqktdiQAM
|
||||
----
|
||||
|
||||
Create a BIP-32 key from a passphrase:
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
The passphrase in this example is way too easy to guess.
|
||||
====
|
||||
|
||||
----
|
||||
$ ku P:foo
|
||||
|
||||
input : P:foo
|
||||
network : Bitcoin
|
||||
wallet key : xprv9s21ZrQH143K31AgNK5pyVvW23gHnkBq2wh5aEk6g1s496M8ZMjxncCKZKgb5j
|
||||
ZoY5eSJMJ2Vbyvi2hbmQnCuHBujZ2WXGTux1X2k9Krdtq
|
||||
public version : xpub661MyMwAqRbcFVF9ULcqLdsEa5WnCCugQAcgNd9iEMQ31tgH6u4DLQWoQayvtS
|
||||
VYFvXz2vPPpbXE1qpjoUFidhjFj82pVShWu9curWmb2zy
|
||||
tree depth : 0
|
||||
fingerprint : 5d353a2e
|
||||
parent f'print : 00000000
|
||||
child index : 0
|
||||
chain code : 5eeb1023fd6dd1ae52a005ce0e73420821e1d90e08be980a85e9111fd7646bbc
|
||||
private key : yes
|
||||
secret exponent : 65825730547097305716057160437970790220123864299761908948746835886007793998275
|
||||
hex : 91880b0e3017ba586b735fe7d04f1790f3c46b818a2151fb2def5f14dd2fd9c3
|
||||
wif : L26c3H6jEPVSqAr1usXUp9qtQJw6NHgApq6Ls4ncyqtsvcq2MwKH
|
||||
uncompressed : 5JvNzA5vXDoKYJdw8SwwLHxUxaWvn9mDea6k1vRPCX7KLUVWa7W
|
||||
public pair x : 81821982719381104061777349269130419024493616650993589394553404347774393168191
|
||||
public pair y : 58994218069605424278320703250689780154785099509277691723126325051200459038290
|
||||
x as hex : b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f
|
||||
y as hex : 826d8b4d3010aea16ff4c1c1d3ae68541d9a04df54a2c48cc241c2983544de52
|
||||
y parity : even
|
||||
key pair as sec : 02b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f
|
||||
uncompressed : 04b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f
|
||||
826d8b4d3010aea16ff4c1c1d3ae68541d9a04df54a2c48cc241c2983544de52
|
||||
hash160 : 5d353a2ecdb262477172852d57a3f11de0c19286
|
||||
uncompressed : e5bd3a7e6cb62b4c820e51200fb1c148d79e67da
|
||||
Bitcoin address : 19Vqc8uLTfUonmxUEZac7fz1M5c5ZZbAii
|
||||
uncompressed : 1MwkRkogzBRMehBntgcq2aJhXCXStJTXHT
|
||||
----
|
||||
|
||||
|
||||
Get info as JSON:
|
||||
|
||||
|
||||
----
|
||||
$ ku P:foo -P -j
|
||||
----
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"y_parity": "even",
|
||||
"public_pair_y_hex": "826d8b4d3010aea16ff4c1c1d3ae68541d9a04df54a2c48cc241c2983544de52",
|
||||
"private_key": "no",
|
||||
"parent_fingerprint": "00000000",
|
||||
"tree_depth": "0",
|
||||
"network": "Bitcoin",
|
||||
"btc_address_uncompressed": "1MwkRkogzBRMehBntgcq2aJhXCXStJTXHT",
|
||||
"key_pair_as_sec_uncompressed": "04b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f826d8b4d3010aea16ff4c1c1d3ae68541d9a04df54a2c48cc241c2983544de52",
|
||||
"public_pair_x_hex": "b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f",
|
||||
"wallet_key": "xpub661MyMwAqRbcFVF9ULcqLdsEa5WnCCugQAcgNd9iEMQ31tgH6u4DLQWoQayvtSVYFvXz2vPPpbXE1qpjoUFidhjFj82pVShWu9curWmb2zy",
|
||||
"chain_code": "5eeb1023fd6dd1ae52a005ce0e73420821e1d90e08be980a85e9111fd7646bbc",
|
||||
"child_index": "0",
|
||||
"hash160_uncompressed": "e5bd3a7e6cb62b4c820e51200fb1c148d79e67da",
|
||||
"btc_address": "19Vqc8uLTfUonmxUEZac7fz1M5c5ZZbAii",
|
||||
"fingerprint": "5d353a2e",
|
||||
"hash160": "5d353a2ecdb262477172852d57a3f11de0c19286",
|
||||
"input": "P:foo",
|
||||
"public_pair_x": "81821982719381104061777349269130419024493616650993589394553404347774393168191",
|
||||
"public_pair_y": "58994218069605424278320703250689780154785099509277691723126325051200459038290",
|
||||
"key_pair_as_sec": "02b4e599dfa44555a4ed38bcfff0071d5af676a86abf123c5b4b4e8e67a0b0b13f"
|
||||
}
|
||||
----
|
||||
|
||||
Public BIP32 key:
|
||||
|
||||
----
|
||||
$ ku -w -P P:foo
|
||||
xpub661MyMwAqRbcFVF9ULcqLdsEa5WnCCugQAcgNd9iEMQ31tgH6u4DLQWoQayvtSVYFvXz2vPPpbXE1qpjoUFidhjFj82pVShWu9curWmb2zy
|
||||
----
|
||||
|
||||
Generate a subkey:
|
||||
|
||||
----
|
||||
$ ku -w -s3/2 P:foo
|
||||
xprv9wTErTSkjVyJa1v4cUTFMFkWMe5eu8ErbQcs9xajnsUzCBT7ykHAwdrxvG3g3f6BFk7ms5hHBvmbdutNmyg6iogWKxx6mefEw4M8EroLgKj
|
||||
----
|
||||
|
||||
Hardened subkey:
|
||||
|
||||
----
|
||||
$ ku -w -s3/2H P:foo
|
||||
xprv9wTErTSu5AWGkDeUPmqBcbZWX1xq85ZNX9iQRQW9DXwygFp7iRGJo79dsVctcsCHsnZ3XU3DhsuaGZbDh8iDkBN45k67UKsJUXM1JfRCdn1
|
||||
----
|
||||
|
||||
WIF:
|
||||
|
||||
----
|
||||
$ ku -W P:foo
|
||||
L26c3H6jEPVSqAr1usXUp9qtQJw6NHgApq6Ls4ncyqtsvcq2MwKH
|
||||
----
|
||||
|
||||
Address:
|
||||
|
||||
|
||||
----
|
||||
$ ku -a P:foo
|
||||
19Vqc8uLTfUonmxUEZac7fz1M5c5ZZbAii
|
||||
----
|
||||
|
||||
|
||||
|
||||
Generate a bunch of subkeys:
|
||||
|
||||
|
||||
----
|
||||
$ ku P:foo -s 0/0-5 -w
|
||||
xprv9xWkBDfyBXmZjBG9EiXBpy67KK72fphUp9utJokEBFtjsjiuKUUDF5V3TU8U8cDzytqYnSekc8bYuJS8G3bhXxKWB89Ggn2dzLcoJsuEdRK
|
||||
xprv9xWkBDfyBXmZnzKf3bAGifK593gT7WJZPnYAmvc77gUQVej5QHckc5Adtwxa28ACmANi9XhCrRvtFqQcUxt8rUgFz3souMiDdWxJDZnQxzx
|
||||
xprv9xWkBDfyBXmZqdXA8y4SWqfBdy71gSW9sjx9JpCiJEiBwSMQyRxan6srXUPBtj3PTxQFkZJAiwoUpmvtrxKZu4zfsnr3pqyy2vthpkwuoVq
|
||||
xprv9xWkBDfyBXmZsA85GyWj9uYPyoQv826YAadKWMaaEosNrFBKgj2TqWuiWY3zuqxYGpHfv9cnGj5P7e8EskpzKL1Y8Gk9aX6QbryA5raK73p
|
||||
xprv9xWkBDfyBXmZv2q3N66hhZ8DAcEnQDnXML1J62krJAcf7Xb1HJwuW2VMJQrCofY2jtFXdiEY8UsRNJfqK6DAdyZXoMvtaLHyWQx3FS4A9zw
|
||||
xprv9xWkBDfyBXmZw4jEYXUHYc9fT25k9irP87n2RqfJ5bqbjKdT84Mm7Wtc2xmzFuKg7iYf7XFHKkSsaYKWKJbR54bnyAD9GzjUYbAYTtN4ruo
|
||||
----
|
||||
|
||||
[role="pagebreak-before"]
|
||||
Generate the corresponding addresses:
|
||||
|
||||
|
||||
----
|
||||
$ ku P:foo -s 0/0-5 -a
|
||||
1MrjE78H1R1rqdFrmkjdHnPUdLCJALbv3x
|
||||
1AnYyVEcuqeoVzH96zj1eYKwoWfwte2pxu
|
||||
1GXr1kZfxE1FcK6ZRD5sqqqs5YfvuzA1Lb
|
||||
116AXZc4bDVQrqmcinzu4aaPdrYqvuiBEK
|
||||
1Cz2rTLjRM6pMnxPNrRKp9ZSvRtj5dDUML
|
||||
1WstdwPnU6HEUPme1DQayN9nm6j7nDVEM
|
||||
----
|
||||
|
||||
|
||||
Generate the corresponding WIFs:
|
||||
|
||||
|
||||
----
|
||||
$ ku P:foo -s 0/0-5 -W
|
||||
L5a4iE5k9gcJKGqX3FWmxzBYQc29PvZ6pgBaePLVqT5YByEnBomx
|
||||
Kyjgne6GZwPGB6G6kJEhoPbmyjMP7D5d3zRbHVjwcq4iQXD9QqKQ
|
||||
L4B3ygQxK6zH2NQGxLDee2H9v4Lvwg14cLJW7QwWPzCtKHdWMaQz
|
||||
L2L2PZdorybUqkPjrmhem4Ax5EJvP7ijmxbNoQKnmTDMrqemY8UF
|
||||
L2oD6vA4TUyqPF8QG4vhUFSgwCyuuvFZ3v8SKHYFDwkbM765Nrfd
|
||||
KzChTbc3kZFxUSJ3Kt54cxsogeFAD9CCM4zGB22si8nfKcThQn8C
|
||||
----
|
||||
|
||||
|
||||
|
||||
Check that it works by choosing a BIP32 string (the one corresponding to subkey 0/3):
|
||||
|
||||
|
||||
|
||||
----
|
||||
$ ku -W xprv9xWkBDfyBXmZsA85GyWj9uYPyoQv826YAadKWMaaEosNrFBKgj2TqWuiWY3zuqxYGpHfv9cnGj5P7e8EskpzKL1Y8Gk9aX6QbryA5raK73p
|
||||
L2L2PZdorybUqkPjrmhem4Ax5EJvP7ijmxbNoQKnmTDMrqemY8UF
|
||||
$ ku -a xprv9xWkBDfyBXmZsA85GyWj9uYPyoQv826YAadKWMaaEosNrFBKgj2TqWuiWY3zuqxYGpHfv9cnGj5P7e8EskpzKL1Y8Gk9aX6QbryA5raK73p
|
||||
116AXZc4bDVQrqmcinzu4aaPdrYqvuiBEK
|
||||
----
|
||||
|
||||
|
||||
Yep, looks familiar.
|
||||
|
||||
From secret exponent:
|
||||
|
||||
|
||||
----
|
||||
$ ku 1
|
||||
|
||||
input : 1
|
||||
network : Bitcoin
|
||||
secret exponent : 1
|
||||
hex : 1
|
||||
wif : KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn
|
||||
uncompressed : 5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf
|
||||
public pair x : 55066263022277343669578718895168534326250603453777594175500187360389116729240
|
||||
public pair y : 32670510020758816978083085130507043184471273380659243275938904335757337482424
|
||||
x as hex : 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
y as hex : 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
||||
y parity : even
|
||||
key pair as sec : 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
uncompressed : 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
uncompressed : 91b24bf9f5288532960ac687abb035127b1d28a5
|
||||
Bitcoin address : 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
|
||||
uncompressed : 1EHNa6Q4Jz2uvNExL497mE43ikXhwF6kZm
|
||||
----
|
||||
|
||||
|
||||
Litecoin version:
|
||||
|
||||
|
||||
----
|
||||
$ ku -nL 1
|
||||
|
||||
input : 1
|
||||
network : Litecoin
|
||||
secret exponent : 1
|
||||
hex : 1
|
||||
wif : T33ydQRKp4FCW5LCLLUB7deioUMoveiwekdwUwyfRDeGZm76aUjV
|
||||
uncompressed : 6u823ozcyt2rjPH8Z2ErsSXJB5PPQwK7VVTwwN4mxLBFrao69XQ
|
||||
public pair x : 55066263022277343669578718895168534326250603453777594175500187360389116729240
|
||||
public pair y : 32670510020758816978083085130507043184471273380659243275938904335757337482424
|
||||
x as hex : 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
y as hex : 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
||||
y parity : even
|
||||
key pair as sec : 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
uncompressed : 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
uncompressed : 91b24bf9f5288532960ac687abb035127b1d28a5
|
||||
Litecoin address : LVuDpNCSSj6pQ7t9Pv6d6sUkLKoqDEVUnJ
|
||||
uncompressed : LYWKqJhtPeGyBAw7WC8R3F7ovxtzAiubdM
|
||||
----
|
||||
|
||||
|
||||
Dogecoin WIF:
|
||||
|
||||
|
||||
----
|
||||
$ ku -nD -W 1
|
||||
QNcdLVw8fHkixm6NNyN6nVwxKek4u7qrioRbQmjxac5TVoTtZuot
|
||||
----
|
||||
|
||||
|
||||
From public pair (on Testnet):
|
||||
|
||||
|
||||
----
|
||||
$ ku -nT 55066263022277343669578718895168534326250603453777594175500187360389116729240,even
|
||||
|
||||
input : 550662630222773436695787188951685343262506034537775941755001873603
|
||||
89116729240,even
|
||||
network : Bitcoin testnet
|
||||
public pair x : 55066263022277343669578718895168534326250603453777594175500187360389116729240
|
||||
public pair y : 32670510020758816978083085130507043184471273380659243275938904335757337482424
|
||||
x as hex : 79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
y as hex : 483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
||||
y parity : even
|
||||
key pair as sec : 0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
uncompressed : 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798
|
||||
483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
uncompressed : 91b24bf9f5288532960ac687abb035127b1d28a5
|
||||
Bitcoin testnet address : mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r
|
||||
uncompressed : mtoKs9V381UAhUia3d7Vb9GNak8Qvmcsme
|
||||
----
|
||||
|
||||
|
||||
From hash160:
|
||||
|
||||
|
||||
----
|
||||
$ ku 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
|
||||
input : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
network : Bitcoin
|
||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
Bitcoin address : 1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH
|
||||
----
|
||||
|
||||
|
||||
((("", startref="pycoin library")))As a Dogecoin address:
|
||||
|
||||
|
||||
----
|
||||
$ ku -nD 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
|
||||
input : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
network : Dogecoin
|
||||
hash160 : 751e76e8199196d454941c45d1b3a323f1433bd6
|
||||
Dogecoin address : DFpN6QqFfUm3gKNaxN6tNcab1FArL9cZLE
|
||||
----
|
||||
|
||||
==== Transaction Utility (TX)
|
||||
|
||||
((("transaction utility (TX)", id="TX17")))
|
||||
The command-line utility +tx+ will display transactions in human-readable form, fetch base transactions from pycoin's transaction cache or from web services (blockchain.info, blockcypher.com, blockr.io and chain.so are currently supported), merge transactions, add or delete inputs or outputs, and sign transactions.
|
||||
|
||||
Following are some examples.
|
||||
|
||||
|
||||
View the famous "pizza" transaction:
|
||||
|
||||
|
||||
----
|
||||
$ tx 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a
|
||||
warning: consider setting environment variable PYCOIN_CACHE_DIR=~/.pycoin_cache to cache transactions fetched via web services
|
||||
warning: no service providers found for get_tx; consider setting environment variable PYCOIN_BTC_PROVIDERS
|
||||
usage: tx [-h] [-t TRANSACTION_VERSION] [-l LOCK_TIME] [-n NETWORK] [-a]
|
||||
[-i address] [-f path-to-private-keys] [-g GPG_ARGUMENT]
|
||||
[--remove-tx-in tx_in_index_to_delete]
|
||||
[--remove-tx-out tx_out_index_to_delete] [-F transaction-fee] [-u]
|
||||
[-b BITCOIND_URL] [-o path-to-output-file]
|
||||
argument [argument ...]
|
||||
tx: error: can't find Tx with id 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a
|
||||
----
|
||||
|
||||
|
||||
Oops! We don't have web services set up. Let's do that now:
|
||||
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ PYCOIN_CACHE_DIR=~/.pycoin_cache
|
||||
$ PYCOIN_BTC_PROVIDERS="block.io blockchain.info blockexplorer.com"
|
||||
$ export PYCOIN_CACHE_DIR PYCOIN_BTC_PROVIDERS
|
||||
----
|
||||
|
||||
|
||||
It's not done automatically so a command-line tool won't leak potentially private information about what transactions you're interested in to a third-party website. If you don't care, you could put these lines into your _.profile_.
|
||||
|
||||
Let's try again:
|
||||
|
||||
----
|
||||
$ tx 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a
|
||||
Version: 1 tx hash 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a 159 bytes
|
||||
TxIn count: 1; TxOut count: 1
|
||||
Lock time: 0 (valid anytime)
|
||||
Input:
|
||||
0: (unknown) from 1e133f7de73ac7d074e2746a3d6717dfc99ecaa8e9f9fade2cb8b0b20a5e0441:0
|
||||
Output:
|
||||
0: 1CZDM6oTttND6WPdt3D6bydo7DYKzd9Qik receives 10000000.00000 mBTC
|
||||
Total output 10000000.00000 mBTC
|
||||
including unspents in hex dump since transaction not fully signed
|
||||
010000000141045e0ab2b0b82cdefaf9e9a8ca9ec9df17673d6a74e274d0c73ae77d3f131e000000004a493046022100a7f26eda874931999c90f87f01ff1ffc76bcd058fe16137e0e63fdb6a35c2d78022100a61e9199238eb73f07c8f209504c84b80f03e30ed8169edd44f80ed17ddf451901ffffffff010010a5d4e80000001976a9147ec1003336542cae8bded8909cdd6b5e48ba0ab688ac00000000
|
||||
|
||||
** can't validate transaction as source transactions missing
|
||||
----
|
||||
|
||||
The final line appears because to validate the transactions' signatures, you technically need the source transactions. So let's add +-a+ to augment the transactions with source information:
|
||||
|
||||
----
|
||||
$ tx -a 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a
|
||||
warning: transaction fees recommendations casually calculated and estimates may be incorrect
|
||||
warning: transaction fee lower than (casually calculated) expected value of 0.1 mBTC, transaction might not propagate
|
||||
Version: 1 tx hash 49d2adb6e476fa46d8357babf78b1b501fd39e177ac7833124b3f67b17c40c2a 159 bytes
|
||||
TxIn count: 1; TxOut count: 1
|
||||
Lock time: 0 (valid anytime)
|
||||
Input:
|
||||
0: 17WFx2GQZUmh6Up2NDNCEDk3deYomdNCfk from 1e133f7de73ac7d074e2746a3d6717dfc99ecaa8e9f9fade2cb8b0b20a5e0441:0 10000000.00000 mBTC sig ok
|
||||
Output:
|
||||
0: 1CZDM6oTttND6WPdt3D6bydo7DYKzd9Qik receives 10000000.00000 mBTC
|
||||
Total input 10000000.00000 mBTC
|
||||
Total output 10000000.00000 mBTC
|
||||
Total fees 0.00000 mBTC
|
||||
|
||||
010000000141045e0ab2b0b82cdefaf9e9a8ca9ec9df17673d6a74e274d0c73ae77d3f131e000000004a493046022100a7f26eda874931999c90f87f01ff1ffc76bcd058fe16137e0e63fdb6a35c2d78022100a61e9199238eb73f07c8f209504c84b80f03e30ed8169edd44f80ed17ddf451901ffffffff010010a5d4e80000001976a9147ec1003336542cae8bded8909cdd6b5e48ba0ab688ac00000000
|
||||
|
||||
all incoming transaction values validated
|
||||
----
|
||||
|
||||
((("", startref="TX17")))Now, let's look at unspent outputs for a specific address (UTXO). In block #1, we see a coinbase transaction to +12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX+. Let's use +fetch_unspent+ to find all coins in this address:
|
||||
|
||||
----
|
||||
$ fetch_unspent 12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX
|
||||
a3a6f902a51a2cbebede144e48a88c05e608c2cce28024041a5b9874013a1e2a/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/333000
|
||||
cea36d008badf5c7866894b191d3239de9582d89b6b452b596f1f1b76347f8cb/31/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/10000
|
||||
065ef6b1463f552f675622a5d1fd2c08d6324b4402049f68e767a719e2049e8d/86/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/10000
|
||||
a66dddd42f9f2491d3c336ce5527d45cc5c2163aaed3158f81dc054447f447a2/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/10000
|
||||
ffd901679de65d4398de90cefe68d2c3ef073c41f7e8dbec2fb5cd75fe71dfe7/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/100
|
||||
d658ab87cc053b8dbcfd4aa2717fd23cc3edfe90ec75351fadd6a0f7993b461d/5/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/911
|
||||
36ebe0ca3237002acb12e1474a3859bde0ac84b419ec4ae373e63363ebef731c/1/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/100000
|
||||
fd87f9adebb17f4ebb1673da76ff48ad29e64b7afa02fda0f2c14e43d220fe24/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/1
|
||||
dfdf0b375a987f17056e5e919ee6eadd87dad36c09c4016d4a03cea15e5c05e3/1/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/1337
|
||||
cb2679bfd0a557b2dc0d8a6116822f3fcbe281ca3f3e18d3855aa7ea378fa373/0/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/1337
|
||||
d6be34ccf6edddc3cf69842dce99fe503bf632ba2c2adb0f95c63f6706ae0c52/1/76a914119b098e2e980a229e139a9ed01a469e518e6f2688ac/2000000
|
||||
0e3e2357e806b6cdb1f70b54c3a3a17b6714ee1f0e68bebb44a74b1efd512098/0/410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac/5000000000
|
||||
----
|
@ -0,0 +1,51 @@
|
||||
= Mastering Bitcoin
|
||||
|
||||
include::preface.asciidoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::intro.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::overview.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::bitcoin-core.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::keys.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::wallets.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::transactions.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::authorization-authentication.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::signatures.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::fees.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::network.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::blockchain.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::mining.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::security.adoc[]
|
||||
|
||||
//IMAGE_REPORT:NEW_CHAPTER
|
||||
include::applications.adoc[]
|
||||
|
||||
include::whitepaper.adoc[]
|
||||
|
||||
include::errata.adoc[]
|
||||
|
||||
include::bips.adoc[]
|
@ -1,45 +0,0 @@
|
||||
= Mastering Bitcoin
|
||||
|
||||
include::preface.asciidoc[]
|
||||
|
||||
include::glossary.asciidoc[]
|
||||
|
||||
include::ch01.asciidoc[]
|
||||
|
||||
include::ch02.asciidoc[]
|
||||
|
||||
include::ch03.asciidoc[]
|
||||
|
||||
include::ch04.asciidoc[]
|
||||
|
||||
include::ch05.asciidoc[]
|
||||
|
||||
include::ch06.asciidoc[]
|
||||
|
||||
include::ch07.asciidoc[]
|
||||
|
||||
include::ch08.asciidoc[]
|
||||
|
||||
include::ch09.asciidoc[]
|
||||
|
||||
include::ch10.asciidoc[]
|
||||
|
||||
include::ch11.asciidoc[]
|
||||
|
||||
include::ch12.asciidoc[]
|
||||
|
||||
include::appdx-bitcoinwhitepaper.asciidoc[]
|
||||
|
||||
include::appdx-scriptops.asciidoc[]
|
||||
|
||||
include::appdx-bips.asciidoc[]
|
||||
|
||||
include::appdx-bitcore.asciidoc[]
|
||||
|
||||
include::appdx-pycoin.asciidoc[]
|
||||
|
||||
include::appdx-bx.asciidoc[]
|
||||
|
||||
include::ix.html[]
|
||||
|
||||
include::colo.html[]
|
@ -1,800 +0,0 @@
|
||||
[[ch03_bitcoin_client]]
|
||||
== Bitcoin Core: The Reference Implementation
|
||||
|
||||
((("open source licenses")))((("Nakamoto, Satoshi")))Bitcoin is an _open source_ project and the source code is available under an open (MIT) license, free to download and use for any purpose. Open source means more than simply free to use. It also means that bitcoin is developed by an open community of volunteers. At first, that community consisted of only Satoshi Nakamoto. By 2016, bitcoin's source code had more than 400 contributors with about a dozen developers working on the code almost full-time and several dozen more on a part-time basis. Anyone can contribute to the code—including you!
|
||||
|
||||
|
||||
((("bitcoin whitepaper")))((("Satoshi client")))((("reference implementation", see="Bitcoin Core")))((("Bitcoin Core", "reference implementation")))When bitcoin was created by Satoshi Nakamoto, the software was actually completed before the whitepaper reproduced in <<satoshi_whitepaper>> was written. Satoshi wanted to make sure it worked before writing about it. That first implementation, then simply known as "Bitcoin" or "Satoshi client," has been heavily modified and improved. It has evolved into what is known as _Bitcoin Core_, to differentiate it from other compatible implementations. Bitcoin Core is the _reference implementation_ of the Bitcoin system, meaning that it is the authoritative reference on how each part of the technology should be implemented. Bitcoin Core implements all aspects of bitcoin, including wallets, a transaction and block validation engine, and a full network node in the peer-to-peer Bitcoin network.
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
((("wallets", "best practices for")))((("bitcoin improvement proposals", "Mnemonic Code Words (BIP-39)")))((("bitcoin improvement proposals", "Hierarchical Deterministic Wallets (BIP-32/BIP-44)")))Even though Bitcoin Core includes a reference implementation of a wallet, this is not intended to be used as a production wallet for users or for applications. Application developers are advised to build wallets using modern standards such as BIP-39 and BIP-32 (see <<mnemonic_code_words>> and <<hd_wallets>>). BIP stands for _Bitcoin Improvement Proposal_.
|
||||
====
|
||||
|
||||
<<bitcoin_core_architecture>> shows the architecture of Bitcoin Core.((("Bitcoin Core", "architecture")))
|
||||
|
||||
[[bitcoin_core_architecture]]
|
||||
.Bitcoin Core architecture (Source: Eric Lombrozo)
|
||||
image::images/mbc2_0301.png["Bitcoin Core Architecture"]
|
||||
|
||||
|
||||
=== Bitcoin Development Environment
|
||||
|
||||
((("development environment", "setup", see="Bitcoin Core")))If you're a developer, you will want to set up a development environment with all the tools, libraries, and support software for writing bitcoin applications. In this highly technical chapter, we'll walk through that process step-by-step. If the material becomes too dense (and you're not actually setting up a development environment) feel free to skip to the next chapter, which is less technical.
|
||||
|
||||
[[compiling_core]]
|
||||
=== Compiling Bitcoin Core from the Source Code
|
||||
|
||||
((("Bitcoin Core", "compiling from source code", id="BCsource03")))((("Bitcoin Core", "compiling from source code", "downloading")))((("code examples, obtaining and using")))Bitcoin Core's source code can be downloaded as an archive or by cloning the authoritative source repository from GitHub. ((("Bitcoin Core downloads")))On the https://bitcoincore.org/bin/[Bitcoin Core download page], select the most recent version and download the compressed archive of the source code, e.g., +bitcoin-0.15.0.2.tar.gz+. ((("GitHub bitcoin page")))Alternatively, use the git command line to create a local copy of the source code from the https://github.com/bitcoin/bitcoin[GitHub bitcoin page].
|
||||
|
||||
[TIP]
|
||||
====
|
||||
((("$ symbol")))((("shell commands")))((("terminal applications")))In many of the examples in this chapter we will be using the operating system's command-line interface (also known as a "shell"), accessed via a "terminal" application. The shell will display a prompt; you type a command; and the shell responds with some text and a new prompt for your next command. The prompt may look different on your system, but in the following examples it is denoted by a +$+ symbol. In the examples, when you see text after a +$+ symbol, don't type the +$+ symbol but type the command immediately following it, then press Enter to execute the command. In the examples, the lines below each command are the operating system's responses to that command. When you see the next +$+ prefix, you'll know it's a new command and you should repeat the process.
|
||||
====
|
||||
|
||||
((("cloning source code")))((("source code, cloning", seealso="Bitcoin Core")))In this example, we are using the +git+ command to create a local copy ("clone") of the source code:
|
||||
|
||||
----
|
||||
$ git clone https://github.com/bitcoin/bitcoin.git
|
||||
Cloning into 'bitcoin'...
|
||||
remote: Counting objects: 102071, done.
|
||||
remote: Compressing objects: 100% (10/10), done.
|
||||
Receiving objects: 100% (102071/102071), 86.38 MiB | 730.00 KiB/s, done.
|
||||
remote: Total 102071 (delta 4), reused 5 (delta 1), pack-reused 102060
|
||||
Resolving deltas: 100% (76168/76168), done.
|
||||
Checking connectivity... done.
|
||||
$
|
||||
----
|
||||
|
||||
[TIP]
|
||||
====
|
||||
((("distributed version control systems")))Git is the most widely used distributed version control system, an essential part of any software developer's toolkit. You may need to install the +git+ command, or a graphical user interface for git, on your operating system if you do not have it already.
|
||||
====
|
||||
|
||||
When the git cloning operation has completed, you will have a complete local copy of the source code repository in the directory _bitcoin_. Change to this directory by typing ++**cd bitcoin**++ at the prompt:
|
||||
|
||||
----
|
||||
$ cd bitcoin
|
||||
----
|
||||
|
||||
==== Selecting a Bitcoin Core Release
|
||||
((("Bitcoin Core", "compiling from source code", "version selection")))By default, the local copy will be synchronized with the most recent code, which might be an unstable or beta version of bitcoin. Before compiling the code, select a specific version by checking out a release _tag_. This will synchronize the local copy with a specific snapshot of the code repository identified by a keyword tag. Tags are used by the developers to mark specific releases of the code by version number. First, to find the available tags, we use the +git tag+ command:
|
||||
|
||||
----
|
||||
$ git tag
|
||||
v0.1.5
|
||||
v0.1.6test1
|
||||
v0.10.0
|
||||
...
|
||||
v0.11.2
|
||||
v0.11.2rc1
|
||||
v0.12.0rc1
|
||||
v0.12.0rc2
|
||||
...
|
||||
----
|
||||
|
||||
The list of tags shows all the released versions of bitcoin. By convention, _release candidates_, which are intended for testing, have the suffix "rc." Stable releases that can be run on production systems have no suffix. From the preceding list, select the highest version release, which at the time of writing was v0.15.0. To synchronize the local code with this version, use the +git checkout+ command:
|
||||
|
||||
----
|
||||
$ git checkout v0.15.0
|
||||
HEAD is now at 3751912... Merge #11295: doc: Old fee_estimates.dat are discarded by 0.15.0
|
||||
----
|
||||
|
||||
You can confirm you have the desired version "checked out" by issuing the command +git status+:
|
||||
|
||||
----
|
||||
$ git status
|
||||
HEAD detached at v0.15.0
|
||||
nothing to commit, working directory clean
|
||||
----
|
||||
|
||||
==== Configuring the Bitcoin Core Build
|
||||
|
||||
((("Bitcoin Core", "compiling from source code", "build configuration")))((("documentation")))((("build documentation", seealso="Bitcoin Core")))The source code includes documentation, which can be found in a number of files. Review the main documentation located in _README.md_ in the _bitcoin_ directory by typing ++**more README.md**++ at the prompt and using the spacebar to progress to the next page. In this chapter, we will build the command-line Bitcoin client, also known as +bitcoind+ on Linux. Review the instructions for compiling the +bitcoind+ command-line client on your platform by typing ++**more doc/build-unix.md**++. Alternative instructions for macOS and Windows can be found in the _doc_ directory, as _build-osx.md_ or _build-windows.md_, respectively.
|
||||
|
||||
Carefully review the build prerequisites, which are in the first part of the build documentation. These are libraries that must be present on your system before you can begin to compile bitcoin. If these prerequisites are missing, the build process will fail with an error. If this happens because you missed a prerequisite, you can install it and then resume the build process from where you left off. Assuming the prerequisites are installed, you start the build process by generating a set of build scripts using the _autogen.sh_ script.
|
||||
|
||||
----
|
||||
$ ./autogen.sh
|
||||
...
|
||||
glibtoolize: copying file 'build-aux/m4/libtool.m4'
|
||||
glibtoolize: copying file 'build-aux/m4/ltoptions.m4'
|
||||
glibtoolize: copying file 'build-aux/m4/ltsugar.m4'
|
||||
glibtoolize: copying file 'build-aux/m4/ltversion.m4'
|
||||
...
|
||||
configure.ac:10: installing 'build-aux/compile'
|
||||
configure.ac:5: installing 'build-aux/config.guess'
|
||||
configure.ac:5: installing 'build-aux/config.sub'
|
||||
configure.ac:9: installing 'build-aux/install-sh'
|
||||
configure.ac:9: installing 'build-aux/missing'
|
||||
Makefile.am: installing 'build-aux/depcomp'
|
||||
...
|
||||
----
|
||||
|
||||
The _autogen.sh_ script creates a set of automatic configuration scripts that will interrogate your system to discover the correct settings and ensure you have all the necessary libraries to compile the code. The most important of these is the +configure+ script that offers a number of different options to customize the build process. Type ++**./configure --help**++ to see the various options:
|
||||
|
||||
----
|
||||
$ ./configure --help
|
||||
`configure' configures Bitcoin Core 0.15.0 to adapt to many kinds of systems.
|
||||
|
||||
Usage: ./configure [OPTION]... [VAR=VALUE]...
|
||||
|
||||
...
|
||||
Optional Features:
|
||||
--disable-option-checking ignore unrecognized --enable/--with options
|
||||
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
|
||||
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
|
||||
|
||||
--enable-wallet enable wallet (default is yes)
|
||||
|
||||
--with-gui[=no|qt4|qt5|auto]
|
||||
...
|
||||
----
|
||||
|
||||
The +configure+ script allows you to enable or disable certain features of +bitcoind+ through the use of the +--enable-FEATURE+ and +--disable-FEATURE+ flags, where pass:[<span class="keep-together"><code>FEATURE</code></span>] is replaced by the feature name, as listed in the help output. In this chapter, we will build the +bitcoind+ client with all the default features. We won't be using the configuration flags, but you should review them to understand what optional features are part of the client. If you are in an academic setting, computer lab restrictions may require you to install applications in your home directory (e.g., using +--prefix=$HOME+).
|
||||
|
||||
Here are some useful options that override the default behavior of the configure script:
|
||||
|
||||
++++
|
||||
<dl>
|
||||
<dt><code>--prefix=$HOME</code></dt>
|
||||
<dd><p>This overrides the default installation location (which is <em>/usr/local/</em>) for the resulting executable. Use <code>$HOME</code> to put everything in your home directory, or a different path.</p></dd>
|
||||
|
||||
<dt><code>--disable-wallet</code></dt>
|
||||
<dd><p>This is used to disable the reference wallet implementation.</p></dd>
|
||||
|
||||
<dt><code>--with-incompatible-bdb</code></dt>
|
||||
<dd><p>If you are building a wallet, allow the use of an incompatible version of the Berkeley DB library.</p></dd>
|
||||
|
||||
<dt><code>--with-gui=no</code></dt>
|
||||
<dd><p>Don't build the graphical user interface, which requires the Qt library. This builds server and command-line bitcoin only.</p></dd>
|
||||
</dl>
|
||||
++++
|
||||
|
||||
Next, run the +configure+ script to automatically discover all the necessary libraries and create a customized build script for your system:
|
||||
|
||||
----
|
||||
$ ./configure
|
||||
checking build system type... x86_64-unknown-linux-gnu
|
||||
checking host system type... x86_64-unknown-linux-gnu
|
||||
checking for a BSD-compatible install... /usr/bin/install -c
|
||||
checking whether build environment is sane... yes
|
||||
checking for a thread-safe mkdir -p... /bin/mkdir -p
|
||||
checking for gawk... gawk
|
||||
checking whether make sets $(MAKE)... yes
|
||||
...
|
||||
[many pages of configuration tests follow]
|
||||
...
|
||||
$
|
||||
----
|
||||
|
||||
|
||||
If all went well, the +configure+ command will end by creating the customized build scripts that will allow us to compile +bitcoind+. If there are any missing libraries or errors, the +configure+ command will terminate with an error instead of creating the build scripts. If an error occurs, it is most likely because of a missing or incompatible library. Review the build documentation again and make sure you install the missing prerequisites. Then run +configure+ again and see if that fixes the error.
|
||||
|
||||
==== Building the Bitcoin Core Executables
|
||||
|
||||
((("Bitcoin Core", "compiling from source code", "core executables")))((("core executables", seealso="Bitcoin Core")))Next, you will compile the source code, a process that can take up to an hour to complete, depending on the speed of your CPU and available memory. During the compilation process you should see output every few seconds or every few minutes, or an error if something goes wrong. If an error occurs, or the compilation process is interrupted, it can be resumed any time by typing +make+ again. Type ++**make**++ to start compiling the executable application:
|
||||
|
||||
----
|
||||
$ make
|
||||
Making all in src
|
||||
CXX crypto/libbitcoinconsensus_la-hmac_sha512.lo
|
||||
CXX crypto/libbitcoinconsensus_la-ripemd160.lo
|
||||
CXX crypto/libbitcoinconsensus_la-sha1.lo
|
||||
CXX crypto/libbitcoinconsensus_la-sha256.lo
|
||||
CXX crypto/libbitcoinconsensus_la-sha512.lo
|
||||
CXX libbitcoinconsensus_la-hash.lo
|
||||
CXX primitives/libbitcoinconsensus_la-transaction.lo
|
||||
CXX libbitcoinconsensus_la-pubkey.lo
|
||||
CXX script/libbitcoinconsensus_la-bitcoinconsensus.lo
|
||||
CXX script/libbitcoinconsensus_la-interpreter.lo
|
||||
|
||||
[... many more compilation messages follow ...]
|
||||
|
||||
$
|
||||
----
|
||||
|
||||
On a fast system with more than one CPU, you might want to set the number of parallel compile jobs. For instance, +make -j 2+ will use two cores if they are available. If all goes well, Bitcoin Core is now compiled. You should run the unit test suite with +make check+ to ensure the linked libraries are not broken in obvious ways. The final step is to install the various executables on your system using the +make install+ command. You may be prompted for your user password, because this step requires administrative privileges:
|
||||
|
||||
----
|
||||
$ make check && sudo make install
|
||||
Password:
|
||||
Making install in src
|
||||
../build-aux/install-sh -c -d '/usr/local/lib'
|
||||
libtool: install: /usr/bin/install -c bitcoind /usr/local/bin/bitcoind
|
||||
libtool: install: /usr/bin/install -c bitcoin-cli /usr/local/bin/bitcoin-cli
|
||||
libtool: install: /usr/bin/install -c bitcoin-tx /usr/local/bin/bitcoin-tx
|
||||
...
|
||||
$
|
||||
----
|
||||
|
||||
((("", startref="BCsource03")))The default installation of +bitcoind+ puts it in _/usr/local/bin_. You can confirm that Bitcoin Core is correctly installed by asking the system for the path of the executables, as follows:
|
||||
|
||||
----
|
||||
$ which bitcoind
|
||||
/usr/local/bin/bitcoind
|
||||
|
||||
$ which bitcoin-cli
|
||||
/usr/local/bin/bitcoin-cli
|
||||
----
|
||||
|
||||
=== Running a Bitcoin Core Node
|
||||
|
||||
((("Bitcoin Core", "running core nodes", id="BCnode03")))((("Bitcoin nodes", "running core nodes", id="BNcore03")))Bitcoin's peer-to-peer network is composed of network "nodes," run mostly by volunteers and some of the businesses that build bitcoin applications. Those running Bitcoin nodes have a direct and authoritative view of the Bitcoin blockchain, with a local copy of all the transactions, independently validated by their own system. By running a node, you don't have to rely on any third party to validate a transaction. Moreover, by running a Bitcoin node you contribute to the Bitcoin network by making it more robust.
|
||||
|
||||
Running a node, however, requires a permanently connected system with enough resources to process all bitcoin transactions. Depending on whether you choose to index all transactions and keep a full copy of the blockchain, you may also need a lot of disk space and RAM. As of early 2021, a full-index node needs 2 GB of RAM and a minimum of 360 GB of disk space (see https://www.blockchain.com/charts/blocks-size[]). Bitcoin nodes also transmit and receive bitcoin transactions and blocks, consuming internet bandwidth. If your internet connection is limited, has a low data cap, or is metered (charged by the gigabit), you should probably not run a Bitcoin node on it, or run it in a way that constrains its bandwidth (see <<constrained_resources>>).
|
||||
|
||||
[TIP]
|
||||
====
|
||||
((("warnings and cautions", "core node resource requirements")))((("resource requirements")))Bitcoin Core keeps a full copy of the blockchain by default, with every transaction that has ever occurred on the Bitcoin network since its inception in 2009. This dataset is dozens of gigabytes in size and is downloaded incrementally over several days or weeks, depending on the speed of your CPU and internet connection. Bitcoin Core will not be able to process transactions or update account balances until the full blockchain dataset is downloaded. Make sure you have enough disk space, bandwidth, and time to complete the initial synchronization. You can configure Bitcoin Core to reduce the size of the blockchain by discarding old blocks (see <<constrained_resources>>), but it will still download the entire dataset before discarding data.
|
||||
====
|
||||
|
||||
Despite these resource requirements, thousands of volunteers run Bitcoin nodes. Some are running on systems as simple as a Raspberry Pi (a $35 USD computer the size of a pack of cards). Many volunteers also run Bitcoin nodes on rented servers, usually some variant of Linux. A _Virtual Private Server_ (VPS) or _Cloud Computing Server_ instance can be used to run a Bitcoin node. Such servers can be rented for $25 to $50 USD per month from a variety of providers.
|
||||
|
||||
Why would you want to run a node? Here are some of the most common reasons:
|
||||
|
||||
* If you are developing bitcoin software and need to rely on a Bitcoin node for programmable (API) access to the network and blockchain.
|
||||
|
||||
* If you are building applications that must validate transactions according to bitcoin's consensus rules. Typically, bitcoin software companies run several nodes.
|
||||
|
||||
* If you want to support bitcoin. Running a node makes the network more robust and able to serve more wallets, more users, and more transactions.
|
||||
|
||||
* If you do not want to rely on any third party to process or validate your transactions.
|
||||
|
||||
If you're reading this book and interested in developing bitcoin software, you should be running your own node.
|
||||
|
||||
==== Configuring the Bitcoin Core Node
|
||||
|
||||
((("Bitcoin Core", "running core nodes", "configuring")))((("warnings and cautions", "password creation")))((("passwords", "creating")))((("security", "passwords")))Bitcoin Core will look for a configuration file in its data directory on every start. In this section we will examine the various configuration options and set up a configuration file. To locate the configuration file, run +bitcoind -printtoconsole+ in your terminal and look for the first couple of lines.
|
||||
|
||||
----
|
||||
$ bitcoind -printtoconsole
|
||||
Bitcoin version v0.15.0
|
||||
Using the 'standard' SHA256 implementation
|
||||
Using data directory /home/ubuntu/.bitcoin/
|
||||
Using config file /home/ubuntu/.bitcoin/bitcoin.conf
|
||||
...
|
||||
[a lot more debug output]
|
||||
...
|
||||
----
|
||||
|
||||
You can hit Ctrl-C to shut down the node once you determine the location of the config file. Usually the configuration file is inside the _.bitcoin_ data directory under your user's home directory. It is not created automatically, but you can create a starter config file by copying and pasting from the <<#full_index_node>> example, below. You can create or modify the configuration file in your preferred editor.
|
||||
|
||||
Bitcoin Core offers more than 100 configuration options that modify the behavior of the network node, the storage of the blockchain, and many other aspects of its operation. To see a listing of these options, run +bitcoind --help+:
|
||||
|
||||
----
|
||||
$ bitcoind --help
|
||||
Bitcoin Core Daemon version v0.15.0
|
||||
|
||||
Usage:
|
||||
bitcoind [options] Start Bitcoin Core Daemon
|
||||
|
||||
Options:
|
||||
|
||||
-?
|
||||
Print this help message and exit
|
||||
|
||||
-version
|
||||
Print version and exit
|
||||
|
||||
-alertnotify=<cmd>
|
||||
Execute command when a relevant alert is received or we see a really
|
||||
long fork (%s in cmd is replaced by message)
|
||||
...
|
||||
[many more options]
|
||||
...
|
||||
|
||||
-rpcthreads=<n>
|
||||
Set the number of threads to service RPC calls (default: 4)
|
||||
----
|
||||
|
||||
((("configuration options", seealso="Bitcoin Core")))Here are some of the most important options that you can set in the configuration file, or as command-line parameters to +bitcoind+:
|
||||
|
||||
alertnotify:: Run a specified command or script to send emergency alerts to the owner of this node, usually by email.
|
||||
|
||||
conf:: An alternative location for the configuration file. This only makes sense as a command-line parameter to +bitcoind+, as it can't be inside the configuration file it refers to.
|
||||
|
||||
datadir:: Select the directory and filesystem in which to put all the blockchain data. By default this is the _.bitcoin_ subdirectory of your home directory. Make sure this filesystem has several gigabytes of free space.
|
||||
|
||||
prune:: Reduce the disk space requirements to this many megabytes, by deleting old blocks. Use this on a resource-constrained node that can't fit the full blockchain.
|
||||
|
||||
txindex:: Maintain an index of all transactions. This means a complete copy of the blockchain that allows you to programmatically retrieve any transaction by ID.
|
||||
|
||||
dbcache:: The size of the UTXO cache. The default is 450 MiB. Increase this on high-end hardware and reduce the size on low-end hardware to save memory at the expense of slow disk IO.
|
||||
|
||||
maxconnections:: Set the maximum number of nodes from which to accept connections. Reducing this from the default will reduce your bandwidth consumption. Use if you have a data cap or pay by the gigabyte.
|
||||
|
||||
maxmempool:: Limit the transaction memory pool to this many megabytes. Use it to reduce memory use on memory-constrained nodes.
|
||||
|
||||
maxreceivebuffer/maxsendbuffer:: Limit per-connection memory buffer to this many multiples of 1000 bytes. Use on memory-constrained nodes.
|
||||
|
||||
minrelaytxfee:: Set the minimum fee rate for transaction you will relay. Below this value, the transaction is treated nonstandard, rejected from the transaction pool and not relayed.
|
||||
|
||||
|
||||
[[txindex]]
|
||||
.Transaction Database Index and txindex Option
|
||||
****
|
||||
((("Bitcoin Core", "running core nodes", "database options")))((("transactions", "database configuration options")))((("txindex option")))((("full indexing option")))By default, Bitcoin Core builds a database containing _only_ the transactions related to the user's wallet. If you want to be able to access _any_ transaction with commands like +getrawtransaction+ (see <<exploring_and_decoding_transanctions>>), you need to configure Bitcoin Core to build a complete transaction index, which can be achieved with the +txindex+ option. Set +txindex=1+ in the Bitcoin Core configuration file. If you don't set this option at first and later set it to full indexing, you need to restart +bitcoind+ with the +-reindex+ option and wait for it to rebuild the index.
|
||||
****
|
||||
|
||||
<<full_index_node>> shows how you might combine the preceding options, with a fully indexed node, running as an API backend for a bitcoin application.
|
||||
|
||||
[[full_index_node]]
|
||||
.Sample configuration of a full-index node
|
||||
====
|
||||
----
|
||||
alertnotify=myemailscript.sh "Alert: %s"
|
||||
datadir=/lotsofspace/bitcoin
|
||||
txindex=1
|
||||
----
|
||||
====
|
||||
|
||||
<<constrained_resources>> shows a resource-constrained node running on a smaller server.
|
||||
|
||||
[[constrained_resources]]
|
||||
.Sample configuration of a resource-constrained system
|
||||
====
|
||||
----
|
||||
alertnotify=myemailscript.sh "Alert: %s"
|
||||
maxconnections=15
|
||||
prune=5000
|
||||
dbcache=150
|
||||
maxmempool=150
|
||||
maxreceivebuffer=2500
|
||||
maxsendbuffer=500
|
||||
----
|
||||
====
|
||||
|
||||
Once you've edited the configuration file and set the options that best represent your needs, you can test +bitcoind+ with this configuration. Run Bitcoin Core with the option +printtoconsole+ to run in the foreground with output to the console:
|
||||
|
||||
----
|
||||
$ bitcoind -printtoconsole
|
||||
|
||||
Bitcoin version v0.15.0
|
||||
InitParameterInteraction: parameter interaction: -whitelistforcerelay=1 -> setting -whitelistrelay=1
|
||||
Assuming ancestors of block 0000000000000000003b9ce759c2a087d52abc4266f8f4ebd6d768b89defa50a have valid signatures.
|
||||
Using the 'standard' SHA256 implementation
|
||||
Default data directory /home/ubuntu/.bitcoin
|
||||
Using data directory /lotsofspace/.bitcoin
|
||||
Using config file /home/ubuntu/.bitcoin/bitcoin.conf
|
||||
Using at most 125 automatic connections (1048576 file descriptors available)
|
||||
Using 16 MiB out of 32/2 requested for signature cache, able to store 524288 elements
|
||||
Using 16 MiB out of 32/2 requested for script execution cache, able to store 524288 elements
|
||||
Using 2 threads for script verification
|
||||
HTTP: creating work queue of depth 16
|
||||
No rpcpassword set - using random cookie authentication
|
||||
Generated RPC authentication cookie /lotsofspace/.bitcoin/.cookie
|
||||
HTTP: starting 4 worker threads
|
||||
init message: Verifying wallet(s)...
|
||||
Using BerkeleyDB version Berkeley DB 4.8.30: (April 9, 2010)
|
||||
Using wallet wallet.dat
|
||||
CDBEnv::Open: LogDir=/lotsofspace/.bitcoin/database ErrorFile=/lotsofspace/.bitcoin/db.log
|
||||
scheduler thread start
|
||||
Cache configuration:
|
||||
* Using 250.0MiB for block index database
|
||||
* Using 8.0MiB for chain state database
|
||||
* Using 1742.0MiB for in-memory UTXO set (plus up to 286.1MiB of unused mempool space)
|
||||
init message: Loading block index...
|
||||
Opening LevelDB in /lotsofspace/.bitcoin/blocks/index
|
||||
Opened LevelDB successfully
|
||||
|
||||
[... more startup messages ...]
|
||||
----
|
||||
|
||||
You can hit Ctrl-C to interrupt the process once you are satisfied that it is loading the correct settings and running as you expect.
|
||||
|
||||
To run Bitcoin Core in the background as a process, start it with the +daemon+ option, as +bitcoind -daemon+.
|
||||
|
||||
To monitor the progress and runtime status of your Bitcoin node, use the command +bitcoin-cli getblockchaininfo+:
|
||||
|
||||
----
|
||||
$ bitcoin-cli getblockchaininfo
|
||||
----
|
||||
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"chain": "main",
|
||||
"blocks": 0,
|
||||
"headers": 83999,
|
||||
"bestblockhash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
|
||||
"difficulty": 1,
|
||||
"mediantime": 1231006505,
|
||||
"verificationprogress": 3.783041623201835e-09,
|
||||
"chainwork": "0000000000000000000000000000000000000000000000000000000100010001",
|
||||
"pruned": false,
|
||||
[...]
|
||||
}
|
||||
----
|
||||
|
||||
This shows a node with a blockchain height of 0 blocks and 83999 headers. The node currently fetches the block headers of the best chain and afterward continues to download the full blocks.
|
||||
|
||||
Once you are happy with the configuration options you have selected, you should add bitcoin to the startup scripts in your operating system, so that it runs continuously and restarts when the operating system restarts. You will find a number of example startup scripts for various operating systems in bitcoin's source directory under _contrib/init_ and a _README.md_ file showing which system uses which script.((("", startref="BCnode03")))((("", startref="BNcore03")))
|
||||
|
||||
=== Bitcoin Core Application Programming Interface (API)
|
||||
|
||||
((("Bitcoin Core", "Bitcoin Core API", id="BCapi03")))The Bitcoin Core client implements a JSON-RPC interface that can also be accessed using the command-line helper +bitcoin-cli+. The command line allows us to experiment interactively with the capabilities that are also available programmatically via the API. ((("Bitcoin Core", "Bitcoin Core API", "RPC commands")))To start, invoke the +help+ command to see a list of the available bitcoin RPC commands:
|
||||
|
||||
[[bitcoind_commands]]
|
||||
|
||||
----
|
||||
$ bitcoin-cli help
|
||||
addmultisigaddress nrequired ["key",...] ( "account" )
|
||||
addnode "node" "add|remove|onetry"
|
||||
backupwallet "destination"
|
||||
createmultisig nrequired ["key",...]
|
||||
createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...}
|
||||
decoderawtransaction "hexstring"
|
||||
...
|
||||
...
|
||||
verifymessage "bitcoinaddress" "signature" "message"
|
||||
walletlock
|
||||
walletpassphrase "passphrase" timeout
|
||||
walletpassphrasechange "oldpassphrase" "newpassphrase"
|
||||
----
|
||||
|
||||
Each of these commands may take a number of parameters. To get additional help, a detailed description, and information on the parameters, add the command name after +help+. For example, to see help on the +getblockhash+ RPC command:
|
||||
|
||||
----
|
||||
$ bitcoin-cli help getblockhash
|
||||
getblockhash height
|
||||
|
||||
Returns hash of block in best-block-chain at height provided.
|
||||
|
||||
Arguments:
|
||||
1. height (numeric, required) The height index
|
||||
|
||||
Result:
|
||||
"hash" (string) The block hash
|
||||
|
||||
Examples:
|
||||
> bitcoin-cli getblockhash 1000
|
||||
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockhash", "params": [1000] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
|
||||
----
|
||||
|
||||
At the end of the help information you will see two examples of the RPC command, using the +bitcoin-cli+ helper or the HTTP client +curl+. These examples demonstrate how you might call the command. Copy the first example and see the result:
|
||||
|
||||
----
|
||||
$ bitcoin-cli getblockhash 1000
|
||||
00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09
|
||||
----
|
||||
|
||||
The result is a block hash, which is described in more detail in the following chapters. But for now, this command should return the same result on your system, demonstrating that your Bitcoin Core node is running, is accepting commands, and has information about block 1000 to return to you.
|
||||
|
||||
In the next sections we will demonstrate some very useful RPC commands and their expected output.
|
||||
|
||||
==== Getting Information on the Bitcoin Core Client Status
|
||||
|
||||
((("Bitcoin Core", "Bitcoin Core API", "status information")))Bitcoin Core provides status reports on different modules through the JSON-RPC interface. The most important commands include +getblockchaininfo+, +getmempoolinfo+, +getnetworkinfo+ and +getwalletinfo+.
|
||||
|
||||
Bitcoin's +getblockchaininfo+ RPC command was introduced earlier. The +getnetworkinfo+ command displays basic information about the status of the Bitcoin network node. Use +bitcoin-cli+ to run it:
|
||||
|
||||
----
|
||||
$ bitcoin-cli getnetworkinfo
|
||||
----
|
||||
[source,json]
|
||||
----
|
||||
{
|
||||
"version": 150000,
|
||||
"subversion": "/Satoshi:0.15.0/",
|
||||
"protocolversion": 70015,
|
||||
"localservices": "000000000000000d",
|
||||
"localrelay": true,
|
||||
"timeoffset": 0,
|
||||
"networkactive": true,
|
||||
"connections": 8,
|
||||
"networks": [
|
||||
...
|
||||
detailed information about all networks (ipv4, ipv6 or onion)
|
||||
...
|
||||
],
|
||||
"relayfee": 0.00001000,
|
||||
"incrementalfee": 0.00001000,
|
||||
"localaddresses": [
|
||||
],
|
||||
"warnings": ""
|
||||
}
|
||||
|
||||
----
|
||||
|
||||
The data is returned in JavaScript Object Notation (JSON), a format that can easily be "consumed" by all programming languages but is also quite human-readable. Among this data we see the version numbers for the bitcoin software client (150000) and Bitcoin protocol (70015). We see the current number of connections (8) and various information about the Bitcoin network and the settings related to this client.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
It will take some time, perhaps more than a day, for the +bitcoind+ client to "catch up" to the current blockchain height as it downloads blocks from other Bitcoin clients. You can check its progress using +getblockchaininfo+ to see the number of known blocks.
|
||||
====
|
||||
|
||||
[[exploring_and_decoding_transanctions]]
|
||||
==== Exploring and Decoding Transactions
|
||||
|
||||
((("Bitcoin Core", "Bitcoin Core API", "exploring and decoding transactions")))((("transactions", "exploring with Bitcoin Core API")))Commands: +getrawtransaction+, +decoderawtransaction+
|
||||
|
||||
|
||||
|
||||
In <<cup_of_coffee>>, ((("use cases", "buying coffee", id="alicethree")))Alice bought a cup of coffee from Bob's Cafe. Her transaction was recorded on the blockchain with transaction ID (+txid+) +0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2+. Let's use the API to retrieve and examine that transaction by passing the transaction ID as a parameter:
|
||||
|
||||
++++
|
||||
<pre data-type="programlisting">
|
||||
$ bitcoin-cli getrawtransaction 0627052b6f28912f2703066a912ea577f2ce4da4caa5a↵
|
||||
5fbd8a57286c345c2f2
|
||||
|
||||
0100000001186f9f998a5aa6f048e51dd8419a14d8a0f1a8a2836dd734d2804fe65fa35779000↵
|
||||
000008b483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4↵
|
||||
ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813014↵
|
||||
10484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc54123363767↵
|
||||
89d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adfffffffff0260e3160000000↵
|
||||
0001976a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788acd0ef8000000000001976a9↵
|
||||
147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac00000000
|
||||
</pre>
|
||||
++++
|
||||
|
||||
|
||||
[TIP]
|
||||
====
|
||||
((("transaction IDs (txd)")))((("malleability")))A transaction ID is not authoritative until a transaction has been confirmed. Absence of a transaction hash in the blockchain does not mean the transaction was not processed. This is known as "transaction malleability," because transaction hashes can be modified prior to confirmation in a block. After confirmation, the +txid+ is immutable and authoritative.
|
||||
====
|
||||
|
||||
The command +getrawtransaction+ returns a serialized transaction in hexadecimal notation. To decode that, we use the +decoderawtransaction+ command, passing the hex data as a parameter. You can copy the hex returned by +getrawtransaction+ and paste it as a parameter to +decoderawtransaction+:
|
||||
|
||||
++++
|
||||
<pre data-type="programlisting">
|
||||
$ bitcoin-cli decoderawtransaction 0100000001186f9f998a5aa6f048e51dd8419a14d8↵
|
||||
a0f1a8a2836dd734d2804fe65fa35779000000008b483045022100884d142d86652a3f47ba474↵
|
||||
6ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298↵
|
||||
cad530a863ea8f53982c09db8f6e381301410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fd↵
|
||||
e0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa↵
|
||||
336a8d752adfffffffff0260e31600000000001976a914ab68025513c3dbd2f7b92a94e0581f5↵
|
||||
d50f654e788acd0ef8000000000001976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8↵
|
||||
88ac00000000
|
||||
|
||||
</pre>
|
||||
++++
|
||||
|
||||
++++
|
||||
<pre data-type="programlisting" data-code-language="json">
|
||||
{
|
||||
"txid": "0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2",
|
||||
"size": 258,
|
||||
"version": 1,
|
||||
"locktime": 0,
|
||||
"vin": [
|
||||
{
|
||||
"txid": "7957a35fe64f80d234d76d83a2...8149a41d81de548f0a65a8a999f6f18",
|
||||
"vout": 0,
|
||||
"scriptSig": {
|
||||
"asm":"3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1decc...",
|
||||
"hex":"483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1de..."
|
||||
},
|
||||
"sequence": 4294967295
|
||||
}
|
||||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.01500000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 ab68...5f654e7 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex": "76a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788ac",
|
||||
"reqSigs": 1,
|
||||
"type": "pubkeyhash",
|
||||
"addresses": [
|
||||
"1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"value": 0.08450000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 7f9b1a...025a8 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
"hex": "76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac",
|
||||
"reqSigs": 1,
|
||||
"type": "pubkeyhash",
|
||||
"addresses": [
|
||||
"1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
</pre>
|
||||
++++
|
||||
|
||||
The transaction decode shows all the components of this transaction, including the transaction inputs and outputs. In this case we see that the transaction that credited our new address with 15 millibits used one input and generated two outputs. The input to this transaction was the output from a previously confirmed transaction (shown as the vin +txid+ starting with +7957a35fe+). The two outputs correspond to the 15 millibit credit and an output with change back to the sender.
|
||||
|
||||
We can further explore the blockchain by examining the previous transaction referenced by its +txid+ in this transaction using the same commands (e.g., +getrawtransaction+). Jumping from transaction to transaction we can follow a chain of transactions back as the coins are transmitted from owner address to owner address.
|
||||
|
||||
|
||||
|
||||
==== Exploring Blocks
|
||||
|
||||
((("Bitcoin Core", "Bitcoin Core API", "exploring blocks")))((("blocks", "exploring with Bitcoin Core API")))Commands: +getblock+, +getblockhash+
|
||||
|
||||
((("blocks", "block height")))((("blocks", "block hash")))Exploring blocks is similar to exploring transactions. However, blocks can be referenced either by the block _height_ or by the block _hash_. First, let's find a block by its height. In <<cup_of_coffee>>, we saw that Alice's transaction was included in block 277316.
|
||||
|
||||
We use the +getblockhash+ command, which takes the block height as the parameter and returns the block hash for that block:
|
||||
|
||||
++++
|
||||
<pre data-type="programlisting">
|
||||
$ bitcoin-cli getblockhash 277316
|
||||
0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4
|
||||
</pre>
|
||||
++++
|
||||
|
||||
Now that we know which block Alice's transaction was included in, we can query that block. We use the +getblock+ command with the block hash as the parameter:
|
||||
|
||||
++++
|
||||
<pre data-type="programlisting">
|
||||
$ bitcoin-cli getblock 0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b3↵
|
||||
1b2cc7bdc4
|
||||
</pre>
|
||||
++++
|
||||
|
||||
++++
|
||||
<pre data-type="programlisting" data-code-language="json">
|
||||
{
|
||||
"hash": "0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4",
|
||||
"confirmations": 37371,
|
||||
"size": 218629,
|
||||
"height": 277316,
|
||||
"version": 2,
|
||||
"merkleroot": "c91c008c26e50763e9f548bb8b2fc323735f73577effbc55502c51eb4cc7cf2e",
|
||||
"tx": [
|
||||
"d5ada064c6417ca25c4308bd158c34b77e1c0eca2a73cda16c737e7424afba2f",
|
||||
"b268b45c59b39d759614757718b9918caf0ba9d97c56f3b91956ff877c503fbe",
|
||||
"04905ff987ddd4cfe603b03cfb7ca50ee81d89d1f8f5f265c38f763eea4a21fd",
|
||||
"32467aab5d04f51940075055c2f20bbd1195727c961431bf0aff8443f9710f81",
|
||||
"561c5216944e21fa29dd12aaa1a45e3397f9c0d888359cb05e1f79fe73da37bd",
|
||||
[... hundreds of transactions ...]
|
||||
"78b300b2a1d2d9449b58db7bc71c3884d6e0579617e0da4991b9734cef7ab23a",
|
||||
"6c87130ec283ab4c2c493b190c20de4b28ff3caf72d16ffa1ce3e96f2069aca9",
|
||||
"6f423dbc3636ef193fd8898dfdf7621dcade1bbe509e963ffbff91f696d81a62",
|
||||
"802ba8b2adabc5796a9471f25b02ae6aeee2439c679a5c33c4bbcee97e081196",
|
||||
"eaaf6a048588d9ad4d1c092539bd571dd8af30635c152a3b0e8b611e67d1a1af",
|
||||
"e67abc6bd5e2cac169821afc51b207127f42b92a841e976f9b752157879ba8bd",
|
||||
"d38985a6a1bfd35037cb7776b2dc86797abbb7a06630f5d03df2785d50d5a2ac",
|
||||
"45ea0a3f6016d2bb90ab92c34a7aac9767671a8a84b9bcce6c019e60197c134b",
|
||||
"c098445d748ced5f178ef2ff96f2758cbec9eb32cb0fc65db313bcac1d3bc98f"
|
||||
],
|
||||
"time": 1388185914,
|
||||
"mediantime": 1388183675,
|
||||
"nonce": 924591752,
|
||||
"bits": "1903a30c",
|
||||
"difficulty": 1180923195.258026,
|
||||
"chainwork": "000000000000000000000000000000000000000000000934695e92aaf53afa1a",
|
||||
"previousblockhash": "0000000000000002a7bbd25a417c0374cc55261021e8a9ca74442b01284f0569",
|
||||
"nextblockhash": "000000000000000010236c269dd6ed714dd5db39d36b33959079d78dfd431ba7"
|
||||
}
|
||||
</pre>
|
||||
++++
|
||||
|
||||
The block contains 419 transactions and the 64th transaction listed (+0627052b...+) is Alice's coffee payment. The +height+ entry tells us this is the 277316th block in the blockchain.
|
||||
|
||||
==== Using Bitcoin Core's Programmatic Interface
|
||||
|
||||
((("Bitcoin Core", "Bitcoin Core API", "using programmatic interface")))((("programmatic interface", id="progint03")))The +bitcoin-cli+ helper is very useful for exploring the Bitcoin Core API and testing functions. But the whole point of an application programming interface is to access functions programmatically. In this section we will demonstrate accessing Bitcoin Core from another program.
|
||||
|
||||
Bitcoin Core's API is a JSON-RPC interface. JSON stands for JavaScript Object Notation and it is a very convenient way to present data that both humans and programs can easily read. RPC stands for Remote Procedure Call, which means that we are calling procedures (functions) that are remote (on the Bitcoin Core node) via a network protocol. In this case, the network protocol is HTTP, or HTTPS (for encrypted connections).
|
||||
|
||||
When we used the +bitcoin-cli+ command to get help on a command, it showed us an example of using +curl+, the versatile command-line HTTP client to construct one of these JSON-RPC calls:
|
||||
|
||||
----
|
||||
$ curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockchaininfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/
|
||||
----
|
||||
|
||||
This command shows that +curl+ submits an HTTP request to the local host (127.0.0.1), connecting to the default bitcoin port (8332), and submitting a +jsonrpc+ request for the +getblockchaininfo+ method using +text/plain+ encoding.
|
||||
|
||||
You might notice that curl will ask for credentials to be sent along with the request. Bitcoin Core will create a random password on each start and place it in the data directory under the name +.cookie+. The +bitcoin-cli+ helper can read this password file given the data directory. Similarly, you can copy the password and pass it to curl (or any higher level Bitcoin Core RPC wrappers). Alternatively, you can create a static password with the helper script provided in _./share/rpcauth/rpcauth.py_ in Bitcoin Core's source directory.
|
||||
|
||||
If you're implementing a JSON-RPC call in your own program, you can use a generic HTTP library to construct the call, similar to what is shown in the preceding +curl+ example.
|
||||
|
||||
However, there are libraries in most every programming language that "wrap" the Bitcoin Core API in a way that makes this a lot simpler. We will use the +python-bitcoinlib+ library to simplify API access. Remember, this requires you to have a running Bitcoin Core instance, which will be used to make JSON-RPC calls.
|
||||
|
||||
The Python script in <<rpc_example>> makes a simple +getblockchaininfo+ call and prints the +blocks+ parameter from the data returned by Bitcoin Core (full node required).
|
||||
|
||||
[[rpc_example]]
|
||||
.Running getblockchaininfo via Bitcoin Core's JSON-RPC API
|
||||
====
|
||||
[source,python]
|
||||
----
|
||||
include::code/rpc_example.py[]
|
||||
----
|
||||
====
|
||||
|
||||
Running it gives us the following result:
|
||||
|
||||
----
|
||||
$ python rpc_example.py
|
||||
394075
|
||||
----
|
||||
|
||||
It tells us that our local Bitcoin Core node has 394075 blocks in its blockchain. Not a spectacular result, but it demonstrates the basic use of the library as a simplified interface to Bitcoin Core's JSON-RPC API.
|
||||
|
||||
Next, let's use the +getrawtransaction+ and +decodetransaction+ calls to retrieve the details of Alice's coffee payment. In <<rpc_transaction>>, we retrieve Alice's transaction and list the transaction's outputs. For each output, we show the recipient address and value. As a reminder, Alice's transaction had one output paying Bob's Cafe and one output for change back to Alice.
|
||||
|
||||
[[rpc_transaction]]
|
||||
.Retrieving a transaction and iterating its outputs
|
||||
====
|
||||
[source,python]
|
||||
----
|
||||
include::code/rpc_transaction.py[]
|
||||
----
|
||||
====
|
||||
|
||||
Running this code, we get:
|
||||
|
||||
----
|
||||
$ python rpc_transaction.py
|
||||
([u'1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA'], Decimal('0.01500000'))
|
||||
([u'1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK'], Decimal('0.08450000'))
|
||||
----
|
||||
|
||||
Both of the preceding examples are rather simple. You don't really need a program to run them; you could just as easily use the +bitcoin-cli+ helper. The next example, however, requires several hundred RPC calls and more clearly demonstrates the use of a programmatic interface.
|
||||
|
||||
In <<rpc_block>>, we first retrieve block 277316, then retrieve each of the 419 transactions within by reference to each transaction ID. Next, we iterate through each of the transaction's outputs and add up the value.((("", startref="alicethree")))
|
||||
|
||||
[[rpc_block]]
|
||||
.Retrieving a block and adding all the transaction outputs
|
||||
====
|
||||
[source,python]
|
||||
----
|
||||
include::code/rpc_block.py[]
|
||||
----
|
||||
====
|
||||
|
||||
Running this code, we get:
|
||||
|
||||
----
|
||||
$ python rpc_block.py
|
||||
|
||||
('Total value in block: ', Decimal('10322.07722534'))
|
||||
----
|
||||
|
||||
Our example code calculates that the total value transacted in this block is 10,322.07722534 BTC (including 25 BTC reward and 0.0909 BTC in fees). Compare that to the amount reported by a block explorer site by searching for the block hash or height. Some block explorers report the total value excluding the reward and excluding the fees. See if you can spot the difference.((("", startref="BCapi03")))((("", startref="progint03")))
|
||||
|
||||
[[alt_libraries]]
|
||||
=== Alternative Clients, Libraries, and Toolkits
|
||||
|
||||
((("Bitcoin Core", "alternatives to", id="BCalt03")))((("clients, libraries, and toolkits", id="clients03")))((("libraries, clients, and toolkits", id="librar03")))((("toolkits, libraries, and clients", id="toolkit03")))((("third-party API clients", id="thirdpart03")))There are many alternative clients, libraries, toolkits, and even full-node implementations in the bitcoin ecosystem. These are implemented in a variety of programming languages, offering programmers native interfaces in their preferred language.
|
||||
|
||||
The following sections list some of the best libraries, clients, and toolkits, organized by programming languages.
|
||||
|
||||
==== C/C++
|
||||
https://github.com/bitcoin/bitcoin[Bitcoin Core] :: The reference implementation of bitcoin
|
||||
https://github.com/libbitcoin/libbitcoin-system[libbitcoin]:: Cross-platform C++ development toolkit, node, and consensus library
|
||||
https://github.com/libbitcoin/libbitcoin-explorer[bitcoin explorer]:: Libbitcoin's command-line tool
|
||||
https://github.com/jgarzik/picocoin[picocoin]:: A C language lightweight client library for bitcoin by Jeff Garzik
|
||||
|
||||
==== JavaScript
|
||||
https://bcoin.io/[bcoin]:: A modular and scalable full-node implementation with API
|
||||
https://bitcore.io/[Bitcore] :: Full node, API, and library by Bitpay
|
||||
https://github.com/bitcoinjs/bitcoinjs-lib[BitcoinJS] :: A pure JavaScript Bitcoin library for node.js and browsers
|
||||
|
||||
==== Java
|
||||
https://bitcoinj.github.io[bitcoinj]:: A Java full-node client library
|
||||
|
||||
==== PHP
|
||||
https://github.com/bit-wasp/bitcoin-php[bitwasp/bitcoin]:: A PHP bitcoin library, and related projects
|
||||
|
||||
==== Python
|
||||
https://github.com/petertodd/python-bitcoinlib[python-bitcoinlib]:: A Python bitcoin library, consensus library, and node by Peter Todd
|
||||
https://github.com/richardkiss/pycoin[pycoin]:: A Python bitcoin library by Richard Kiss
|
||||
https://github.com/primal100/pybitcointools[pybitcointools]:: An archived fork of Python bitcoin library by Vitalik Buterin
|
||||
|
||||
==== Ruby
|
||||
https://github.com/sinisterchipmunk/bitcoin-client[bitcoin-client]:: A Ruby library wrapper for the JSON-RPC API
|
||||
|
||||
==== Go
|
||||
https://github.com/btcsuite/btcd[btcd]:: A Go language full-node Bitcoin client
|
||||
|
||||
==== Rust
|
||||
https://github.com/rust-bitcoin/rust-bitcoin[rust-bitcoin]:: Rust bitcoin library for serialization, parsing, and API calls
|
||||
|
||||
==== C#
|
||||
https://github.com/MetacoSA/NBitcoin[NBitcoin]:: Comprehensive bitcoin library for the .NET framework
|
||||
|
||||
==== Objective-C
|
||||
https://github.com/oleganza/CoreBitcoin[CoreBitcoin]:: Bitcoin toolkit for ObjC and Swift
|
||||
|
||||
Many more libraries exist in a variety of other programming languages and more are created all the time.((("", startref="BCalt03")))((("", startref="clients03")))((("", startref="thirdpart03")))((("", startref="toolkit03")))((("", startref="librar03")))
|
@ -1,500 +0,0 @@
|
||||
[[ch05_wallets]]
|
||||
== Wallets
|
||||
|
||||
((("wallets", "defined")))The word "wallet" is used to describe a few different things in bitcoin.
|
||||
|
||||
At a high level, a wallet is an application that serves as the primary user interface. The wallet controls access to a user's money, managing keys and addresses, tracking the balance, and creating and signing transactions.
|
||||
|
||||
More narrowly, from a programmer's perspective, the word "wallet" refers to the data structure used to store and manage a user's keys.
|
||||
|
||||
In this chapter we will look at the second meaning, where wallets are containers for private keys, usually implemented as structured files or simple databases.
|
||||
|
||||
=== Wallet Technology Overview
|
||||
|
||||
In this section we summarize the various technologies used to construct user-friendly, secure, and flexible bitcoin wallets.
|
||||
|
||||
((("wallets", "contents of")))A common misconception about bitcoin is that bitcoin wallets contain bitcoin. In fact, the wallet contains only keys. The "coins" are recorded in the blockchain on the Bitcoin network. Users control the coins on the network by signing transactions with the keys in their wallets. ((("keychains")))In a sense, a bitcoin wallet is a _keychain_.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
Bitcoin wallets contain keys, not coins. Each user has a wallet containing keys. Wallets are really keychains containing pairs of private/public keys (see <<private_public_keys>>). Users sign transactions with the keys, thereby proving they own the transaction outputs (their coins). The coins are stored on the blockchain in the form of transaction outputs (often noted as vout or txout).
|
||||
====
|
||||
|
||||
((("wallets", "types of", "primary distinctions")))There are two primary types of wallets, distinguished by whether the keys they contain are related to each other or not.
|
||||
|
||||
((("JBOK wallets", seealso="wallets")))((("wallets", "types of", "JBOK wallets")))((("nondeterministic wallets", seealso="wallets")))The first type is a _nondeterministic wallet_, where each key is independently generated from a random number. The keys are not related to each other. This type of wallet is also known as a JBOK wallet from the phrase "Just a Bunch Of Keys."
|
||||
|
||||
((("deterministic wallets", seealso="wallets")))The second type of wallet is a _deterministic wallet_, where all the keys are derived from a single master key, known as the _seed_. All the keys in this type of wallet are related to each other and can be generated again if one has the original seed. ((("key derivation methods")))There are a number of different _key derivation_ methods used in deterministic wallets. ((("hierarchical deterministic (HD) wallets", seealso="wallets")))The most commonly used derivation method uses a tree-like structure and is known as a _hierarchical deterministic_ or _HD_ wallet.
|
||||
|
||||
((("mnemonic code words")))Deterministic wallets are initialized from a random sequence (entropy). To make these easier to use, random sequences are encoded as English words, also known as _mnemonic code words_.
|
||||
|
||||
The next few sections introduce each of these technologies at a high level.
|
||||
|
||||
[[random_wallet]]
|
||||
==== Nondeterministic (Random) Wallets
|
||||
|
||||
((("wallets", "types of", "nondeterministic (random) wallets")))In the first bitcoin wallet (now called Bitcoin Core), wallets were collections of randomly generated private keys. For example, the original Bitcoin Core client pregenerates 100 random private keys when first started and generates more keys as needed, using each key only once. Such wallets are being replaced with deterministic wallets because they are cumbersome to manage, back up, and import. The disadvantage of random keys is that if you generate many of them you must keep copies of all of them, meaning that the wallet must be backed up frequently. Each key must be backed up, or the funds it controls are irrevocably lost if the wallet becomes inaccessible. This conflicts directly with the principle of avoiding address reuse, by using each Bitcoin address for only one transaction. Address reuse reduces privacy by associating multiple transactions and addresses with each other. A Type-0 nondeterministic wallet is a poor choice of wallet, especially if you want to avoid address reuse because it means managing many keys, which creates the need for frequent backups. Although the Bitcoin Core client includes a Type-0 wallet, using this wallet is discouraged by developers of Bitcoin Core. <<Type0_wallet>> shows a nondeterministic wallet, containing a loose collection of random keys.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
The use of nondeterministic wallets is discouraged for anything other than simple tests. They are simply too cumbersome to back up and use. Instead, use an industry-standard–based _HD wallet_ with a _mnemonic_ random sequence (entropy, or "initial seed") for backup.
|
||||
====
|
||||
|
||||
[[Type0_wallet]]
|
||||
[role="smallersixty"]
|
||||
.Type-0 nondeterministic (random) wallet: a collection of randomly generated keys
|
||||
image::images/mbc2_0501.png["Non-Deterministic Wallet"]
|
||||
|
||||
==== Deterministic (Seeded) Wallets
|
||||
|
||||
((("wallets", "types of", "deterministic (seeded) wallets")))Deterministic, or "seeded," wallets are wallets that contain private keys that are all derived from a common seed, through the use of a one-way hash function. The seed is a randomly generated number that is combined with other data, such as an index number or "chain code" (see <<hd_wallets>>) to derive the private keys. In a deterministic wallet, the seed is sufficient to recover all the derived keys, and therefore a single backup at creation time is sufficient. The seed is also sufficient for a wallet export or import, allowing for easy migration of all the user's keys between different wallet implementations. <<Type1_wallet>> shows a logical diagram of a deterministic wallet.
|
||||
|
||||
[[Type1_wallet]]
|
||||
[role="smallersixty"]
|
||||
.Type-1 deterministic (seeded) wallet: a deterministic sequence of keys derived from a seed
|
||||
image::images/mbc2_0502.png["Deterministic Wallet"]
|
||||
|
||||
[[hd_wallets]]
|
||||
==== HD Wallets (BIP-32/BIP-44)
|
||||
|
||||
((("wallets", "types of", "hierarchical deterministic (HD) wallets")))((("hierarchical deterministic (HD) wallets")))((("bitcoin improvement proposals", "Hierarchical Deterministic Wallets (BIP-32/BIP-44)")))Deterministic wallets were developed to make it easy to derive many keys from a single "seed". The most advanced form of deterministic wallets is the HD wallet defined by the BIP-32 standard. HD wallets contain keys derived in a tree structure, such that a parent key can derive a sequence of children keys, each of which can derive a sequence of grandchildren keys, and so on, to an infinite depth. This tree structure is illustrated in <<Type2_wallet>>.
|
||||
|
||||
[[Type2_wallet]]
|
||||
.Type-2 HD wallet: a tree of keys generated from a single seed
|
||||
image::images/mbc2_0503.png["HD wallet"]
|
||||
|
||||
HD wallets offer two major advantages over random (nondeterministic) keys. First, the tree structure can be used to express additional organizational meaning, such as when a specific branch of subkeys is used to receive incoming payments and a different branch is used to receive change from outgoing payments. Branches of keys can also be used in corporate settings, allocating different branches to departments, subsidiaries, specific functions, or accounting categories.
|
||||
|
||||
The second advantage of HD wallets is that users can create a sequence of public keys without having access to the corresponding private keys. This allows HD wallets to be used on an insecure server or in a receive-only capacity, issuing a different public key for each transaction. The public keys do not need to be preloaded or derived in advance, yet the server doesn't have the private keys that can spend the funds.
|
||||
|
||||
==== Seeds and Mnemonic Codes (BIP-39)
|
||||
|
||||
((("wallets", "technology of", "seeds and mnemonic codes")))((("mnemonic code words")))((("bitcoin improvement proposals", "Mnemonic Code Words (BIP-39)")))HD wallets are a very powerful mechanism for managing many keys and addresses. They are even more useful if they are combined with a standardized way of creating seeds from a sequence of English words that are easy to transcribe, export, and import across wallets. This is known as a _mnemonic_ and the standard is defined by BIP-39. Today, most bitcoin wallets (as well as wallets for other cryptocurrencies) use this standard and can import and export seeds for backup and recovery using interoperable mnemonics.
|
||||
|
||||
Let's look at this from a practical perspective. Which of the following seeds is easier to transcribe, record on paper, read without error, export, and import into another wallet?
|
||||
|
||||
.A seed for a deterministic wallet, in hex
|
||||
----
|
||||
0C1E24E5917779D297E14D45F14E1A1A
|
||||
----
|
||||
|
||||
.A seed for a deterministic wallet, from a 12-word mnemonic
|
||||
----
|
||||
army van defense carry jealous true
|
||||
garbage claim echo media make crunch
|
||||
----
|
||||
|
||||
==== Wallet Best Practices
|
||||
|
||||
((("wallets", "best practices for")))((("bitcoin improvement proposals", "Multipurpose HD Wallet Structure (BIP-43)")))As bitcoin wallet technology has matured, certain common industry standards have emerged that make bitcoin wallets broadly interoperable, easy to use, secure, and flexible. These common standards are:
|
||||
|
||||
* Mnemonic code words, based on BIP-39
|
||||
* HD wallets, based on BIP-32
|
||||
* Multipurpose HD wallet structure, based on BIP-43
|
||||
* Multicurrency and multiaccount wallets, based on BIP-44
|
||||
|
||||
These standards may change or may become obsolete by future developments, but for now they form a set of interlocking technologies that have become the de facto wallet standard for bitcoin.
|
||||
|
||||
The standards have been adopted by a broad range of software and hardware bitcoin wallets, making all these wallets interoperable. A user can export a mnemonic generated on one of these wallets and import it in another wallet, recovering all transactions, keys, and addresses.
|
||||
|
||||
((("hardware wallets")))((("hardware wallets", see="also wallets")))Some example of software wallets supporting these standards include (listed alphabetically) Bluewallet, Breadwallet, Copay, and Multibit HD. Examples of hardware wallets supporting these standards include (listed alphabetically) KeepKey, Ledger, and Trezor.
|
||||
|
||||
The following sections examine each of these technologies in detail.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
If you are implementing a bitcoin wallet, it should be built as a HD wallet, with a seed derived from, and encoded as, a mnemonic code for backup, following the BIP-32, BIP-39, BIP-43, and BIP-44 standards, as described in the following sections.
|
||||
====
|
||||
|
||||
==== Using a Bitcoin Wallet
|
||||
|
||||
((("wallets", "using bitcoin wallets")))In <<user-stories>> we introduced Gabriel, ((("use cases", "web store", id="gabrielfive")))an enterprising young teenager in Rio de Janeiro, who is running a simple web store that sells bitcoin-branded t-shirts, coffee mugs, and stickers.
|
||||
|
||||
((("wallets", "types of", "hardware wallets")))Gabriel uses a Trezor bitcoin hardware wallet (<<a_trezor_device>>) to securely manage his bitcoin. The Trezor is a simple USB device with two buttons that stores keys (in the form of an HD wallet) and signs transactions. Trezor wallets implement all the industry standards discussed in this chapter, so Gabriel is not reliant on any proprietary technology or single vendor solution.
|
||||
|
||||
[[a_trezor_device]]
|
||||
.A Trezor device: a bitcoin HD wallet in hardware
|
||||
image::images/mbc2_0504.png[alt]
|
||||
|
||||
When Gabriel used the Trezor for the first time, the device generated a random sequence (entropy), the associated mnemonic and derived a seed from a built-in hardware random number generator. During this initialization phase, the wallet displayed a numbered sequence of words, one by one, on the screen (see <<trezor_mnemonic_display>>).
|
||||
|
||||
[[trezor_mnemonic_display]]
|
||||
.Trezor displaying one of the mnemonic words
|
||||
image::images/mbc2_0505.png["Trezor wallet display of mnemonic word"]
|
||||
|
||||
By writing down this mnemonic, Gabriel created a backup (see <<mnemonic_paper_backup>>) that can be used for recovery in the case of loss or damage to the Trezor device. This mnemonic can be used for recovery in a new Trezor or in any one of the many compatible software or hardware wallets. Note that the sequence of words is important, so mnemonic paper backups have numbered spaces for each word. Gabriel had to carefully record each word in the numbered space to preserve the correct sequence.
|
||||
|
||||
[[mnemonic_paper_backup]]
|
||||
.Gabriel's paper backup of the mnemonic
|
||||
[cols="<1,^50,<1,^50", width="80%"]
|
||||
|===
|
||||
|*1.*| _army_ |*7.*| _garbage_
|
||||
|*2.*| _van_ |*8.*| _claim_
|
||||
|*3.*| _defense_ |*9.*| _echo_
|
||||
|*4.*| _carry_ |*10.*| _media_
|
||||
|*5.*| _jealous_ |*11.*| _make_
|
||||
|*6.*| _true_ |*12.*| _crunch_
|
||||
|===
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
A 12-word mnemonic is shown in <<mnemonic_paper_backup>>, for simplicity. In fact, most hardware wallets generate a more secure 24-word mnemonic. The mnemonic is used in exactly the same way, regardless of length.
|
||||
====
|
||||
|
||||
For the first implementation of his web store, Gabriel uses a single Bitcoin address, generated on his Trezor device. This single address is used by all customers for all orders. As we will see, this approach has some drawbacks and can be improved upon with an HD wallet.((("", startref="gabrielfive")))
|
||||
|
||||
=== Wallet Technology Details
|
||||
|
||||
Let's now examine each of the important industry standards that are used by many bitcoin wallets in detail.
|
||||
|
||||
[[mnemonic_code_words]]
|
||||
==== Mnemonic Code Words (BIP-39)
|
||||
|
||||
((("wallets", "technology of", "mnemonic code words")))((("mnemonic code words", id="mnemonic05")))((("bitcoin improvement proposals", "Mnemonic Code Words (BIP-39)", id="BIP3905")))Mnemonic code words are word sequences that represent (encode) a random number used as a seed to derive a deterministic wallet. The sequence of words is sufficient to re-create the seed and from there re-create the wallet and all the derived keys. A wallet application that implements deterministic wallets with mnemonic words will show the user a sequence of 12 to 24 words when first creating a wallet. That sequence of words is the wallet backup and can be used to recover and re-create all the keys in the same or any compatible wallet application. Mnemonic words make it easier for users to back up wallets because they are easy to read and correctly transcribe, as compared to a random sequence of numbers.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
((("brainwallets")))Mnemonic words are often confused with "brainwallets." They are not the same. The primary difference is that a brainwallet consists of words chosen by the user, whereas mnemonic words are created randomly by the wallet and presented to the user. This important difference makes mnemonic words much more secure, because humans are very poor sources of randomness.
|
||||
====
|
||||
|
||||
Mnemonic codes are defined in BIP-39 (see <<appdxbitcoinimpproposals>>). Note that BIP-39 is one implementation of a mnemonic code standard. ((("Electrum wallet", seealso="wallets")))There is a different standard, with a different set of words, used by the Electrum wallet and predating BIP-39. BIP-39 was proposed by the company behind the Trezor hardware wallet and is incompatible with Electrum's implementation. However, BIP-39 has now achieved broad industry support across dozens of interoperable implementations and should be considered the de facto industry standard.
|
||||
|
||||
BIP-39 defines the creation of a mnemonic code and seed, which we describe here in nine steps. For clarity, the process is split into two parts: steps 1 through 6 are shown in <<generating_mnemonic_words>> and steps 7 through 9 are shown in <<mnemonic_to_seed>>.
|
||||
|
||||
[[generating_mnemonic_words]]
|
||||
===== Generating mnemonic words
|
||||
|
||||
Mnemonic words are generated automatically by the wallet using the standardized process defined in BIP-39. The wallet starts from a source of entropy, adds a checksum, and then maps the entropy to a word list:
|
||||
|
||||
1. Create a random sequence (entropy) of 128 to 256 bits.
|
||||
2. Create a checksum of the random sequence by taking the first (entropy-length/32) bits of its SHA256 hash.
|
||||
3. Add the checksum to the end of the random sequence.
|
||||
4. Split the result into 11-bit length segments.
|
||||
5. Map each 11-bit value to a word from the predefined dictionary of 2048 words.
|
||||
6. The mnemonic code is the sequence of words.
|
||||
|
||||
<<generating_entropy_and_encoding>> shows how entropy is used to generate mnemonic words.
|
||||
|
||||
[[generating_entropy_and_encoding]]
|
||||
[role="smallerseventy"]
|
||||
.Generating entropy and encoding as mnemonic words
|
||||
image::images/mbc2_0506.png["Generating entropy and encoding as mnemonic words"]
|
||||
|
||||
<<table_4-5>> shows the relationship between the size of the entropy data and the length of mnemonic codes in words.
|
||||
|
||||
[[table_4-5]]
|
||||
.Mnemonic codes: entropy and word length
|
||||
[options="header"]
|
||||
|=======
|
||||
|Entropy (bits) | Checksum (bits) | Entropy *+* checksum (bits) | Mnemonic length (words)
|
||||
| 128 | 4 | 132 | 12
|
||||
| 160 | 5 | 165 | 15
|
||||
| 192 | 6 | 198 | 18
|
||||
| 224 | 7 | 231 | 21
|
||||
| 256 | 8 | 264 | 24
|
||||
|=======
|
||||
|
||||
[[mnemonic_to_seed]]
|
||||
===== From mnemonic to seed
|
||||
|
||||
((("key-stretching function")))((("PBKDF2 function")))The mnemonic words represent entropy with a length of 128 to 256 bits. The entropy is then used to derive a longer (512-bit) seed through the use of the key-stretching function PBKDF2. The seed produced is then used to build a deterministic wallet and derive its keys.
|
||||
|
||||
((("salts")))((("passphrases")))The key-stretching function takes two parameters: the mnemonic and a _salt_. The purpose of a salt in a key-stretching function is to make it difficult to build a lookup table enabling a brute-force attack. In the BIP-39 standard, the salt has another purpose—it allows the introduction of a passphrase that serves as an additional security factor protecting the seed, as we will describe in more detail in <<mnemonic_passphrase>>.
|
||||
|
||||
The process described in steps 7 through 9 continues from the process described previously in <<generating_mnemonic_words>>:
|
||||
|
||||
++++
|
||||
<ol start="7">
|
||||
<li>The first parameter to the PBKDF2 key-stretching function is the <em>mnemonic</em> produced from step 6.</li>
|
||||
<li>The second parameter to the PBKDF2 key-stretching function is a <em>salt</em>. The salt is composed of the string constant "<code>mnemonic</code>" concatenated with an optional user-supplied passphrase string.</li>
|
||||
<li>PBKDF2 stretches the mnemonic and salt parameters using 2048 rounds of hashing with the HMAC-SHA512 algorithm, producing a 512-bit value as its final output. That 512-bit value is the seed.</li>
|
||||
</ol>
|
||||
++++
|
||||
|
||||
<<fig_5_7>> shows how a mnemonic is used to generate a seed.
|
||||
|
||||
[[fig_5_7]]
|
||||
.From mnemonic to seed
|
||||
image::images/mbc2_0507.png["From mnemonic to seed"]
|
||||
|
||||
[TIP]
|
||||
====
|
||||
The key-stretching function, with its 2048 rounds of hashing, is a very effective protection against brute-force attacks against the mnemonic or the passphrase. It makes it extremely costly (in computation) to try more than a few thousand passphrase and mnemonic combinations, while the number of possible derived seeds is vast (2^512^).
|
||||
====
|
||||
|
||||
Tables pass:[<a data-type="xref" href="#mnemonic_128_no_pass" data-xrefstyle="select: labelnumber">#mnemonic_128_no_pass</a>], pass:[<a data-type="xref" href="#mnemonic_128_w_pass" data-xrefstyle="select: labelnumber">#mnemonic_128_w_pass</a>], and pass:[<a data-type="xref" href="#mnemonic_256_no_pass" data-xrefstyle="select: labelnumber">#mnemonic_256_no_pass</a>] show some examples of mnemonic codes and the seeds they produce (either with or without a passphrase).
|
||||
|
||||
[[mnemonic_128_no_pass]]
|
||||
.128-bit entropy mnemonic code, no passphrase, resulting seed
|
||||
[cols="h,"]
|
||||
|=======
|
||||
| *Entropy input (128 bits)*| +0c1e24e5917779d297e14d45f14e1a1a+
|
||||
| *Mnemonic (12 words)* | +army van defense carry jealous true garbage claim echo media make crunch+
|
||||
| *Passphrase*| (none)
|
||||
| *Seed (512 bits)* | +5b56c417303faa3fcba7e57400e120a0ca83ec5a4fc9ffba757fbe63fbd77a89a1a3be4c67196f57c39+
|
||||
+a88b76373733891bfaba16ed27a813ceed498804c0570+
|
||||
|=======
|
||||
|
||||
[[mnemonic_128_w_pass]]
|
||||
.128-bit entropy mnemonic code, with passphrase, resulting seed
|
||||
[cols="h,"]
|
||||
|=======
|
||||
| *Entropy input (128 bits)*| +0c1e24e5917779d297e14d45f14e1a1a+
|
||||
| *Mnemonic (12 words)* | +army van defense carry jealous true garbage claim echo media make crunch+
|
||||
| *Passphrase*| SuperDuperSecret
|
||||
| *Seed (512 bits)* | +3b5df16df2157104cfdd22830162a5e170c0161653e3afe6c88defeefb0818c793dbb28ab3ab091897d0+
|
||||
+715861dc8a18358f80b79d49acf64142ae57037d1d54+
|
||||
|=======
|
||||
|
||||
|
||||
[[mnemonic_256_no_pass]]
|
||||
.256-bit entropy mnemonic code, no passphrase, resulting seed
|
||||
[cols="h,"]
|
||||
|=======
|
||||
| *Entropy input (256 bits)* | +2041546864449caff939d32d574753fe684d3c947c3346713dd8423e74abcf8c+
|
||||
| *Mnemonic (24 words)* | +cake apple borrow silk endorse fitness top denial coil riot stay wolf
|
||||
luggage oxygen faint major edit measure invite love trap field dilemma oblige+
|
||||
| *Passphrase*| (none)
|
||||
| *Seed (512 bits)* | +3269bce2674acbd188d4f120072b13b088a0ecf87c6e4cae41657a0bb78f5315b33b3a04356e53d062e5+
|
||||
+5f1e0deaa082df8d487381379df848a6ad7e98798404+
|
||||
|=======
|
||||
|
||||
[TIP]
|
||||
====
|
||||
Many wallets do not allow for the creation of wallets with more than a 12 word mnemonic phrase. You will notice from the tables above that despite the unique lengths of entropy input, the seed size remains the same (512 bits). From a security perspective, the amount of entropy actually used for the production of HD wallets is roughly 128 bits, which equals 12 words. Providing more than 12 words produces additional entropy which is unnecessary, and this _unused_ entropy is not used for the derivation of the seed in the way that one might initially suspect. From a usability perspective, 12 words is also easier to write down, back up, and store.
|
||||
====
|
||||
|
||||
[[mnemonic_passphrase]]
|
||||
===== Optional passphrase in BIP-39
|
||||
|
||||
((("passphrases")))The BIP-39 standard allows the use of an optional passphrase in the derivation of the seed. If no passphrase is used, the mnemonic is stretched with a salt consisting of the constant string +"mnemonic"+, producing a specific 512-bit seed from any given mnemonic. If a passphrase is used, the stretching function produces a _different_ seed from that same mnemonic. In fact, given a single mnemonic, every possible passphrase leads to a different seed. Essentially, there is no "wrong" passphrase. All passphrases are valid and they all lead to different seeds, forming a vast set of possible uninitialized wallets. The set of possible wallets is so large (2^512^) that there is no practical possibility of brute-forcing or accidentally guessing one that is in use.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
There are no "wrong" passphrases in BIP-39. Every passphrase leads to some wallet, which unless previously used will be empty.
|
||||
====
|
||||
|
||||
The optional passphrase creates two important features:
|
||||
|
||||
* A second factor (something memorized) that makes a mnemonic useless on its own, protecting mnemonic backups from compromise by a thief.
|
||||
|
||||
* A form of plausible deniability or "duress wallet," where a chosen passphrase leads to a wallet with a small amount of funds used to distract an attacker from the "real" wallet that contains the majority of funds.
|
||||
|
||||
However, it is important to note that the use of a passphrase also introduces the risk of loss:
|
||||
|
||||
* If the wallet owner is incapacitated or dead and no one else knows the passphrase, the mnemonic code is useless and all the funds stored in the wallet are lost forever.
|
||||
|
||||
* Conversely, if the owner backs up the passphrase in the same place as the mnemonic code, it defeats the purpose of a second factor.
|
||||
|
||||
While passphrases are very useful, they should only be used in combination with a carefully planned process for backup and recovery, considering the possibility of surviving the owner and allowing his or her family to recover the cryptocurrency estate.
|
||||
|
||||
===== Working with mnemonic codes
|
||||
|
||||
BIP-39 is implemented as a library in many different programming languages:
|
||||
|
||||
https://github.com/trezor/python-mnemonic[python-mnemonic]:: The reference implementation of the standard by the SatoshiLabs team that proposed BIP-39, in Python
|
||||
|
||||
https://github.com/bitcoinjs/bip39[bitcoinjs/bip39]:: An implementation of BIP-39, as part of the popular bitcoinJS framework, in JavaScript
|
||||
|
||||
https://github.com/libbitcoin/libbitcoin/blob/master/src/wallet/mnemonic.cpp[libbitcoin/mnemonic]:: An implementation of BIP-39, as part of the popular Libbitcoin framework, in pass:[<span class="keep-together">C++</span>]
|
||||
|
||||
==== Creating an HD Wallet from the Seed
|
||||
|
||||
((("wallets", "technology of", "creating HD wallets from root seed")))((("root seeds")))((("hierarchical deterministic (HD) wallets")))HD wallets are created from a single _root seed_, which is a 128-, 256-, or 512-bit random number. Most commonly, this seed is generated from a _mnemonic_ as detailed in the previous section.
|
||||
|
||||
Every key in the HD wallet is deterministically derived from this root seed, which makes it possible to re-create the entire HD wallet from that seed in any compatible HD wallet. This makes it easy to back up, restore, export, and import HD wallets containing thousands or even millions of keys by simply transferring only the mnemonic that the root seed is derived from.
|
||||
|
||||
The process of creating the master keys and master chain code for an HD wallet is shown in <<HDWalletFromSeed>>.
|
||||
|
||||
[[HDWalletFromSeed]]
|
||||
.Creating master keys and chain code from a root seed
|
||||
image::images/mbc2_0509.png["HDWalletFromRootSeed"]
|
||||
|
||||
The root seed is input into the HMAC-SHA512 algorithm and the resulting hash is used to create a _master private key_ (m) and a _master chain code_ (c).
|
||||
|
||||
The master private key (m) then generates a corresponding master public key (M) using the normal elliptic curve multiplication process +m * G+ that we saw in <<pubkey>>.
|
||||
|
||||
The chain code (c) is used to introduce entropy in the function that creates child keys from parent keys, as we will see in the next section.
|
||||
|
||||
===== Private child key derivation
|
||||
|
||||
((("child key derivation (CKD)")))((("public and private keys", "child key derivation (CKD)")))HD wallets use a _child key derivation_ (CKD) function to derive child keys from parent keys.
|
||||
|
||||
The child key derivation functions are based on a one-way hash function that combines:
|
||||
|
||||
* A parent private or public key (ECDSA compressed key)
|
||||
* A seed called a chain code (256 bits)
|
||||
* An index number (32 bits)
|
||||
|
||||
The chain code is used to introduce deterministic random data to the process, so that knowing the index and a child key is not sufficient to derive other child keys. Knowing a child key does not make it possible to find its siblings, unless you also have the chain code. The initial chain code seed (at the root of the tree) is made from the seed, while subsequent child chain codes are derived from each parent chain code.
|
||||
|
||||
These three items (parent key, chain code, and index) are combined and hashed to generate children keys, as follows.
|
||||
|
||||
The parent public key, chain code, and the index number are combined and hashed with the HMAC-SHA512 algorithm to produce a 512-bit hash. This 512-bit hash is split into two 256-bit halves. The right-half 256 bits of the hash output become the chain code for the child. The left-half 256 bits of the hash are added to the parent key to produce the child private key. In <<CKDpriv>>, we see this illustrated with the index set to 0 to produce the "zero" (first by index) child of the parent.
|
||||
|
||||
[[CKDpriv]]
|
||||
.Extending a parent private key to create a child private key
|
||||
image::images/mbc2_0510.png["ChildPrivateDerivation"]
|
||||
|
||||
Changing the index allows us to extend the parent and create the other children in the sequence, e.g., Child 0, Child 1, Child 2, etc. Each parent key can have 2,147,483,647 (2^31^) children (2^31^ is half of the entire 2^32^ range available because the other half is reserved for a special type of derivation we will talk about later in this chapter).
|
||||
|
||||
Repeating the process one level down the tree, each child can in turn become a parent and create its own children, in an infinite number of generations.
|
||||
|
||||
===== Using derived child keys
|
||||
|
||||
Child private keys are indistinguishable from nondeterministic (random) keys. Because the derivation function is a one-way function, the child key cannot be used to find the parent key. The child key also cannot be used to find any siblings. If you have the n~th~ child, you cannot find its siblings, such as the n–1 child or the n+1 child, or any other children that are part of the sequence. Only the parent key and chain code can derive all the children. Without the child chain code, the child key cannot be used to derive any grandchildren either. You need both the child private key and the child chain code to start a new branch and derive grandchildren.
|
||||
|
||||
So what can the child private key be used for on its own? It can be used to make a public key and a Bitcoin address. Then, it can be used to sign transactions to spend anything paid to that address.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
A child private key, the corresponding public key, and the Bitcoin address are all indistinguishable from keys and addresses created randomly. The fact that they are part of a sequence is not visible outside of the HD wallet function that created them. Once created, they operate exactly as "normal" keys.
|
||||
====
|
||||
|
||||
===== Extended keys
|
||||
|
||||
((("public and private keys", "extended keys")))((("extended keys")))As we saw earlier, the key derivation function can be used to create children at any level of the tree, based on the three inputs: a key, a chain code, and the index of the desired child. The two essential ingredients are the key and chain code, and combined these are called an _extended key_. The term "extended key" could also be thought of as "extensible key" because such a key can be used to derive children.
|
||||
|
||||
Extended keys are stored and represented simply as the concatenation of the 256-bit key and 256-bit chain code into a 512-bit sequence. There are two types of extended keys. An extended private key is the combination of a private key and chain code and can be used to derive child private keys (and from them, child public keys). An extended public key is a public key and chain code, which can be used to create child public keys (_public only_), as described in <<public_key_derivation>>.
|
||||
|
||||
Think of an extended key as the root of a branch in the tree structure of the HD wallet. With the root of the branch, you can derive the rest of the branch. The extended private key can create a complete branch, whereas the extended public key can _only_ create a branch of public keys.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
An extended key consists of a private or public key and chain code. An extended key can create children, generating its own branch in the tree structure. Sharing an extended key gives access to the entire branch.
|
||||
====
|
||||
|
||||
Extended keys are encoded using Base58Check, to easily export and import between different BIP-32–compatible wallets. The Base58Check coding for extended keys uses a special version number that results in the prefix "xprv" and "xpub" when encoded in Base58 characters to make them easily recognizable. Because the extended key is 512 or 513 bits, it is also much longer than other Base58Check-encoded strings we have seen previously.
|
||||
|
||||
Here's an example of an extended _private_ key, encoded in Base58Check:
|
||||
|
||||
----
|
||||
xprv9tyUQV64JT5qs3RSTJkXCWKMyUgoQp7F3hA1xzG6ZGu6u6Q9VMNjGr67Lctvy5P8oyaYAL9CAWrUE9i6GoNMKUga5biW6Hx4tws2six3b9c
|
||||
----
|
||||
|
||||
Here's the corresponding extended _public_ key, encoded in Base58Check:
|
||||
|
||||
----
|
||||
xpub67xpozcx8pe95XVuZLHXZeG6XWXHpGq6Qv5cmNfi7cS5mtjJ2tgypeQbBs2UAR6KECeeMVKZBPLrtJunSDMstweyLXhRgPxdp14sk9tJPW9
|
||||
----
|
||||
|
||||
[[public__child_key_derivation]]
|
||||
===== Public child key derivation
|
||||
|
||||
((("public and private keys", "public child key derivation")))As mentioned previously, a very useful characteristic of HD wallets is the ability to derive public child keys from public parent keys, _without_ having the private keys. This gives us two ways to derive a child public key: either from the child private key, or directly from the parent public key.
|
||||
|
||||
An extended public key can be used, therefore, to derive all of the _public_ keys (and only the public keys) in that branch of the HD wallet structure.
|
||||
|
||||
This shortcut can be used to create very secure public key–only deployments where a server or application has a copy of an extended public key and no private keys whatsoever. That kind of deployment can produce an infinite number of public keys and Bitcoin addresses, but cannot spend any of the money sent to those addresses. Meanwhile, on another, more secure server, the extended private key can derive all the corresponding private keys to sign transactions and spend the money.
|
||||
|
||||
One common application of this solution is to install an extended public key on a web server that serves an ecommerce application. The web server can use the public key derivation function to create a new Bitcoin address for every transaction (e.g., for a customer shopping cart). The web server will not have any private keys that would be vulnerable to theft. Without HD wallets, the only way to do this is to generate thousands of Bitcoin addresses on a separate secure server and then preload them on the ecommerce server. That approach is cumbersome and requires constant maintenance to ensure that the ecommerce server doesn't "run out" of addresses.
|
||||
|
||||
((("cold storage")))((("storage", "cold storage")))((("hardware wallets")))Another common application of this solution is for cold-storage or hardware wallets. In that scenario, the extended private key can be stored on a paper wallet or hardware device (such as a Trezor hardware wallet), while the extended public key can be kept online. The user can create "receive" addresses at will, while the private keys are safely stored offline. To spend the funds, the user can use the extended private key on an offline signing Bitcoin client or sign transactions on the hardware wallet device (e.g., Trezor). <<CKDpub>> illustrates the mechanism for extending a parent public key to derive child public keys.
|
||||
|
||||
[[CKDpub]]
|
||||
.Extending a parent public key to create a child public key
|
||||
image::images/mbc2_0511.png["ChildPublicDerivation"]
|
||||
|
||||
===== Hardened child key derivation
|
||||
|
||||
((("public and private keys", "hardened child key derivation")))((("hardened derivation")))The ability to derive a branch of public keys from an xpub is very useful, but it comes with a potential risk. Access to an xpub does not give access to child private keys. However, because the xpub contains the chain code, if a child private key is known, or somehow leaked, it can be used with the chain code to derive all the other child private keys. A single leaked child private key, together with a parent chain code, reveals all the private keys of all the children. Worse, the child private key together with a parent chain code can be used to deduce the parent private key.
|
||||
|
||||
To counter this risk, HD wallets use an alternative derivation function called _hardened derivation_, which "breaks" the relationship between parent public key and child chain code. The hardened derivation function uses the parent private key to derive the child chain code, instead of the parent public key. This creates a "firewall" in the parent/child sequence, with a chain code that cannot be used to compromise a parent or sibling private key. The hardened derivation function looks almost identical to the normal child private key derivation, except that the parent private key is used as input to the hash function, instead of the parent public key, as shown in the diagram in <<CKDprime>>.
|
||||
|
||||
[[CKDprime]]
|
||||
.Hardened derivation of a child key; omits the parent public key
|
||||
image::images/mbc2_0513.png["ChildHardPrivateDerivation"]
|
||||
|
||||
[role="pagebreak-before"]
|
||||
When the hardened private derivation function is used, the resulting child private key and chain code are completely different from what would result from the normal derivation function. The resulting "branch" of keys can be used to produce extended public keys that are not vulnerable, because the chain code they contain cannot be exploited to reveal any private keys. Hardened derivation is therefore used to create a "gap" in the tree above the level where extended public keys are used.
|
||||
|
||||
In simple terms, if you want to use the convenience of an xpub to derive branches of public keys, without exposing yourself to the risk of a leaked chain code, you should derive it from a hardened parent key, rather than a normal (non-hardened) parent key. As a best practice, the level-1 children of the master keys are always derived through the hardened derivation, to prevent compromise of the master keys.
|
||||
|
||||
===== Index numbers for normal and hardened derivation
|
||||
|
||||
The index number used in the derivation function is a 32-bit integer. To easily distinguish between keys derived through the normal derivation function versus keys derived through hardened derivation, this index number is split into two ranges. Index numbers between 0 and 2^31^–1 (0x0 to 0x7FFFFFFF) are used _only_ for normal derivation. Index numbers between 2^31^ and 2^32^–1 (0x80000000 to 0xFFFFFFFF) are used _only_ for hardened derivation. Therefore, if the index number is less than 2^31^, the child is normal, whereas if the index number is equal or above 2^31^, the child is hardened.
|
||||
|
||||
To make the index number easier to read and display, the index number for hardened children is displayed starting from zero, but with a prime symbol. The first normal child key is therefore displayed as 0, whereas the first hardened child (index 0x80000000) is displayed as 0++'++. In sequence then, the second hardened key would have index 0x80000001 and would be displayed as 1++'++, and so on. When you see an HD wallet index i++'++, that means 2^31^+i.
|
||||
|
||||
===== HD wallet key identifier (path)
|
||||
|
||||
((("hierarchical deterministic (HD) wallets")))Keys in an HD wallet are identified using a "path" naming convention, with each level of the tree separated by a slash (/) character (see <<table_4-8>>). Private keys derived from the master private key start with "m." Public keys derived from the master public key start with "M." Therefore, the first child private key of the master private key is m/0. The first child public key is M/0. The second grandchild of the first child is m/0/1, and so on.
|
||||
|
||||
The "ancestry" of a key is read from right to left, until you reach the master key from which it was derived. For example, identifier m/x/y/z describes the private key that is the z-th child of the parent private key m/x/y, which is the y-th child of the parent private key m/x, which is the x-th child of the parent master private key m.
|
||||
|
||||
[[table_4-8]]
|
||||
.HD wallet path examples
|
||||
[options="header"]
|
||||
|=======
|
||||
|HD path | Key described
|
||||
| m/0 | The first (0) child private key from the master private key (m)
|
||||
| m/0/0 | The first (0) child private key from the first child (m/0)
|
||||
| m/0'/0 | The first (0) normal child from the first _hardened_ child (m/0')
|
||||
| m/1/0 | The first (0) child private key from the second child (m/1)
|
||||
| M/23/17/0/0 | The first (0) child public key from the first child (M/23/17/0) from the 18th child (M/23/17) from the 24th child (M/23)
|
||||
|=======
|
||||
|
||||
===== Navigating the HD wallet tree structure
|
||||
|
||||
The HD wallet tree structure offers tremendous flexibility. Each parent extended key can have 4 billion children: 2 billion normal children and 2 billion hardened children. Each of those children can have another 4 billion children, and so on. The tree can be as deep as you want, with an infinite number of generations. With all that flexibility, however, it becomes quite difficult to navigate this infinite tree. It is especially difficult to transfer HD wallets between implementations, because the possibilities for internal organization into branches and subbranches are endless.
|
||||
|
||||
Two BIPs offer a solution to this complexity by creating some proposed standards for the structure of HD wallet trees. BIP-43 proposes the use of the first hardened child index as a special identifier that signifies the "purpose" of the tree structure. Based on BIP-43, an HD wallet should use only one level-1 branch of the tree, with the index number identifying the structure and namespace of the rest of the tree by defining its purpose. For example, an HD wallet using only branch m/i++'++/ is intended to signify a specific purpose and that purpose is identified by index number "i."
|
||||
|
||||
Extending that specification, BIP-44 proposes a multiaccount structure as "purpose" number +44'+ under BIP-43. All HD wallets following the BIP-44 structure are identified by the fact that they only used one branch of the tree: m/44'/.
|
||||
|
||||
BIP-44 specifies the structure as consisting of five predefined tree levels:
|
||||
|
||||
-----
|
||||
m / purpose' / coin_type' / account' / change / address_index
|
||||
-----
|
||||
|
||||
The first-level "purpose" is always set to +44'+. The second-level "coin_type" specifies the type of cryptocurrency coin, allowing for multicurrency HD wallets where each currency has its own subtree under the second level. There are three currencies defined for now: Bitcoin is m/44'/0', Bitcoin Testnet is m/44++'++/1++'++, and Litecoin is m/44++'++/2++'++.
|
||||
|
||||
The third level of the tree is "account," which allows users to subdivide their wallets into separate logical subaccounts, for accounting or organizational purposes. For example, an HD wallet might contain two bitcoin "accounts": m/44++'++/0++'++/0++'++ and m/44++'++/0++'++/1++'++. Each account is the root of its own subtree.
|
||||
|
||||
((("keys and addresses", see="also public and private keys")))On the fourth level, "change," an HD wallet has two subtrees, one for creating receiving addresses and one for creating change addresses. Note that whereas the previous levels used hardened derivation, this level uses normal derivation. This is to allow this level of the tree to export extended public keys for use in a nonsecured environment. Usable addresses are derived by the HD wallet as children of the fourth level, making the fifth level of the tree the "address_index." For example, the third receiving address for bitcoin payments in the primary account would be M/44++'++/0++'++/0++'++/0/2. <<table_4-9>> shows a few more examples.
|
||||
|
||||
[[table_4-9]]
|
||||
.BIP-44 HD wallet structure examples
|
||||
[options="header"]
|
||||
|=======
|
||||
|HD path | Key described
|
||||
| M/44++'++/0++'++/0++'++/0/2 | The third receiving public key for the primary bitcoin account
|
||||
| M/44++'++/0++'++/3++'++/1/14 | The fifteenth change-address public key for the fourth bitcoin account
|
||||
| m/44++'++/2++'++/0++'++/0/1 | The second private key in the Litecoin main account, for signing transactions
|
||||
|=======
|
||||
|
||||
==== Using an Extended Public Key on a Web Store
|
||||
|
||||
((("wallets", "technology of", "using extended public keys on web stores")))Let's see how HD wallets are used by continuing our story with Gabriel's web store.((("use cases", "web store", id="gabrielfivetwo")))
|
||||
|
||||
Gabriel first set up his web store as a hobby, based on a simple hosted Wordpress page. His store was quite basic with only a few pages and an order form with a single Bitcoin address.
|
||||
|
||||
Gabriel used the first Bitcoin address generated by his Trezor device as the main Bitcoin address for his store. This way, all incoming payments would be paid to an address controlled by his Trezor hardware wallet.
|
||||
|
||||
Customers would submit an order using the form and send payment to Gabriel's published Bitcoin address, triggering an email with the order details for Gabriel to process. With just a few orders each week, this system worked well enough.
|
||||
|
||||
However, the little web store became quite successful and attracted many orders from the local community. Soon, Gabriel was overwhelmed. With all the orders paying the same address, it became difficult to correctly match orders and transactions, especially when multiple orders for the same amount came in close together.
|
||||
|
||||
Gabriel's HD wallet offers a much better solution through the ability to derive public child keys without knowing the private keys. Gabriel can load an extended public key (xpub) on his website, which can be used to derive a unique address for every customer order. Gabriel can spend the funds from his Trezor, but the xpub loaded on the website can only generate addresses and receive funds. This feature of HD wallets is a great security feature. Gabriel's website does not contain any private keys and therefore does not need high levels of security.
|
||||
|
||||
To export the xpub, Gabriel uses the Trezor Suite desktop app in conjunction with the Trezor hardware wallet. The Trezor device must be plugged in for the public keys to be exported. Note that hardware wallets will never export private keys—those always remain on the device. <<export_xpub>> shows what Gabriel sees in Trezor Suite when exporting the xpub.
|
||||
|
||||
[[export_xpub]]
|
||||
.Exporting an xpub from a Trezor hardware wallet
|
||||
image::images/mbc2_0512.png["Exporting the xpub from the Trezor"]
|
||||
|
||||
Gabriel copies the xpub to his web store's bitcoin shop software. He uses _BTCPay Server_, which is an open source web-store for a variety of web hosting and content platforms. BTCPay Server uses the xpub to generate a unique address for every purchase. ((("", startref="gabrielfivetwo")))
|
||||
|
||||
===== Account Discovery and Management
|
||||
|
||||
Gabriel's business is flourishing. He has provided his extended public key (xpub) to _BTCPay Server_, which is generating unique addresses for customers to his website. Every time a customer to Gabriel's website clicks on the "Checkout" button with a specified payment modality (in this case, bitcoin), _BTCPay Server_ generates a new address for that customer. More specifically, _BTCPay Server_ iterates on the _address_index_ tree to create a new address to display to the customer, as defined by BIP-44. If the customer decides to switch payment methods or abandon the transaction entirely, this Bitcoin address goes unused and will not be used for another customer right away.
|
||||
|
||||
At a single moment in time, Gabriel's website may have a large volume of outstanding addresses for customers making purchases, some of which may go unused and eventually expire. Once these addresses expire, _BTCPay Server_ will go back to reuse these addresses to fill the gap in _address_index_, but it becomes clear how there can be gaps between the _address_index_ leaves of the hierarchical deterministic tree where the money is actually located.
|
||||
|
||||
Let's say that Gabriel is interested in viewing his total amount of bitcoin earned on a watch-only wallet (one that allows you to view transaction history, but not spend funds) that is separate from BTCPay Server but also conforms to the BIP-44 standard. How should this separate wallet go about searching for funds in this vast hierarchical tree, and when should it stop looking? Most wallets will typically follow an iterative process that utilizes a predefined limit, known as the _gap limit_. If, while searching for used addresses, the wallet doesn't find used addresses in a row beyond this limit number, it will stop searching the address chain. The default gap limit is typically set to 20. This is detailed in [[bip-44]]https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki[BIP-44].
|
||||
|
||||
[TIP]
|
||||
====
|
||||
Gap limits explain the phenomenon whereby the importing of a wallet may show an incorrect or zero balance. The funds are not lost, but rather, the wallet importing function has not traversed enough leaves to fully detect funds. Many wallets allow this default gap limit to be changed, and Gabriel may need to increase this limit to allow his wallet to fully import his transaction history.
|
||||
====
|
@ -1,336 +0,0 @@
|
||||
[[bitcoin_network_ch08]]
|
||||
== The Bitcoin Network
|
||||
|
||||
=== Peer-to-Peer Network Architecture
|
||||
|
||||
((("Bitcoin network", "peer-to-peer architecture")))((("peer-to-peer (P2P)")))Bitcoin is structured as a peer-to-peer network architecture on top of the internet. The term peer-to-peer, or P2P, means that the computers that participate in the network are peers to each other, that they are all equal, that there are no "special" nodes, and that all nodes share the burden of providing network services. The network nodes interconnect in a mesh network with a "flat" topology. There is no server, no centralized service, and no hierarchy within the network. Nodes in a P2P network both provide and consume services at the same time with reciprocity acting as the incentive for participation. P2P networks are inherently resilient, decentralized, and open. A preeminent example of a P2P network architecture was the early internet itself, where nodes on the IP network were equal. Today's internet architecture is more hierarchical, but the Internet Protocol still retains its flat-topology essence. Beyond bitcoin, the largest and most successful application of P2P technologies is file sharing, with Napster as the pioneer and BitTorrent as the most recent evolution of the architecture.
|
||||
|
||||
Bitcoin's P2P network architecture is much more than a topology choice. Bitcoin is a P2P digital cash system by design, and the network architecture is both a reflection and a foundation of that core characteristic. Decentralization of control is a core design principle that can only be achieved and maintained by a flat, decentralized P2P consensus network.
|
||||
|
||||
((("Bitcoin network", "defined")))The term "Bitcoin network" refers to the collection of nodes running the bitcoin P2P protocol. In addition to the bitcoin P2P protocol, there are other protocols such as Stratum that are used for mining and lightweight or mobile wallets. These additional protocols are provided by gateway routing servers that access the Bitcoin network using the bitcoin P2P protocol and then extend that network to nodes running other protocols. For example, Stratum servers connect Stratum mining nodes via the Stratum protocol to the main Bitcoin network and bridge the Stratum protocol to the bitcoin P2P protocol. We use the term "extended Bitcoin network" to refer to the overall network that includes the bitcoin P2P protocol, pool-mining protocols, the Stratum protocol, and any other related protocols connecting the components of the Bitcoin system.
|
||||
|
||||
=== Node Types and Roles
|
||||
|
||||
((("Bitcoin network", "node types and roles", id="BNnode08")))((("Bitcoin nodes", "types and roles", id="BNtype08")))Although nodes in the bitcoin P2P network are equal, they may take on different roles depending on the functionality they are supporting. A Bitcoin node is a collection of functions: routing, the blockchain database, mining, and wallet services. A full node with all four of these functions is shown in <<full_node_reference>>.
|
||||
|
||||
[[full_node_reference]]
|
||||
[role="smallerfifty"]
|
||||
.A Bitcoin network node with all four functions: wallet, miner, full blockchain database, and network routing
|
||||
image::images/mbc2_0801.png["FullNodeReferenceClient_Small"]
|
||||
|
||||
All nodes include the routing function to participate in the network and might include other functionality. All nodes validate and propagate transactions and blocks, and discover and maintain connections to peers. In the full-node example in <<full_node_reference>>, the routing function is indicated by a circle named "Network Routing Node" or with the letter "N."
|
||||
|
||||
((("full-node clients")))Some nodes, called full nodes, also maintain a complete and up-to-date copy of the blockchain. Full nodes can autonomously and authoritatively verify any transaction without external reference. ((("simplified-payment-verification (SPV)")))Some nodes maintain only a subset of the blockchain and verify transactions using a method called _simplified payment verification_, or SPV. ((("lightweight clients")))These nodes are known as SPV nodes or lightweight nodes. In the full-node example in the figure, the full-node blockchain database function is indicated by a circle called "Full Blockchain" or the letter "B." In <<bitcoin_network>>, SPV nodes are drawn without the "B" circle, showing that they do not have a full copy of the blockchain.
|
||||
|
||||
((("Bitcoin nodes", "mining nodes")))((("mining and consensus", "mining nodes")))((("Proof-of-Work algorithm")))((("mining and consensus", "Proof-of-Work algorithm")))Mining nodes compete to create new blocks by running specialized hardware to solve the Proof-of-Work algorithm. Some mining nodes are also full nodes, maintaining a full copy of the blockchain, while others are lightweight nodes participating in pool mining and depending on a pool server to maintain a full node. The mining function is shown in the full node as a circle called "Miner" or the letter "M."
|
||||
|
||||
User wallets might be part of a full node, as is usually the case with desktop Bitcoin clients. Increasingly, many user wallets, especially those running on resource-constrained devices such as smartphones, are SPV nodes. The wallet function is shown in <<full_node_reference>> as a circle called "Wallet" or the letter "W."
|
||||
|
||||
In addition to the main node types on the bitcoin P2P protocol, there are servers and nodes running other protocols, such as specialized mining pool protocols and lightweight client-access protocols.
|
||||
|
||||
<<node_type_ledgend>> shows the most common node types on the extended Bitcoin network.
|
||||
|
||||
=== The Extended Bitcoin Network
|
||||
|
||||
((("", startref="BNnode08")))((("", startref="BNtype08")))((("Bitcoin network", "extended network activities")))The main Bitcoin network, running the bitcoin P2P protocol, consists of between 5,000 and 8,000 listening nodes running various versions of the bitcoin reference client (Bitcoin Core) and a few hundred nodes running various other implementations of the bitcoin P2P protocol, such as Bitcoin Classic, Bitcoin Unlimited, BitcoinJ, Libbitcoin, btcd, and bcoin. A small percentage of the nodes on the bitcoin P2P network are also mining nodes, competing in the mining process, validating transactions, and creating new blocks. Various large companies interface with the Bitcoin network by running full-node clients based on the Bitcoin Core client, with full copies of the blockchain and a network node, but without mining or wallet functions. These nodes act as network edge routers, allowing various other services (exchanges, wallets, block explorers, merchant payment processing) to be built on top.
|
||||
|
||||
The extended Bitcoin network includes the network running the bitcoin P2P protocol, described earlier, as well as nodes running specialized protocols. Attached to the main bitcoin P2P network are a number of pool servers and protocol gateways that connect nodes running other protocols. These other protocol nodes are mostly pool mining nodes (see <<mining>>) and lightweight wallet clients, which do not carry a full copy of the blockchain.
|
||||
|
||||
<<bitcoin_network>> shows the extended Bitcoin network with the various types of nodes, gateway servers, edge routers, and wallet clients and the various protocols they use to connect to each other.
|
||||
|
||||
[[node_type_ledgend]]
|
||||
.Different types of nodes on the extended Bitcoin network
|
||||
image::images/mbc2_0802.png["BitcoinNodeTypes"]
|
||||
|
||||
[[bitcoin_network]]
|
||||
.The extended Bitcoin network showing various node types, gateways, and protocols
|
||||
image::images/mbc2_0803.png["BitcoinNetwork"]
|
||||
|
||||
=== Bitcoin Relay Networks
|
||||
|
||||
((("Bitcoin network", "Bitcoin Relay Networks")))((("relay networks")))While the bitcoin P2P network serves the general needs of a broad variety of node types, it exhibits too high network latency for the specialized needs of bitcoin mining nodes.
|
||||
|
||||
((("propagation", "relay networks and")))Bitcoin miners are engaged in a time-sensitive competition to solve the Proof-of-Work problem and extend the blockchain (see <<mining>>). While participating in this competition, bitcoin miners must minimize the time between the propagation of a winning block and the beginning of the next round of competition. In mining, network latency is directly related to profit margins.
|
||||
|
||||
A _Bitcoin Relay Network_ is a network that attempts to minimize the latency in the transmission of blocks between miners. The original https://www.bitcoinrelaynetwork.org[Bitcoin Relay Network] was created by core developer Matt Corallo in 2015 to enable fast synchronization of blocks between miners with very low latency. The network consisted of several specialized nodes hosted on the Amazon Web Services infrastructure around the world and served to connect the majority of miners and mining pools.
|
||||
|
||||
((("Fast Internet Bitcoin Relay Engine (FIBRE)")))((("Compact Block optimization")))The original Bitcoin Relay Network was replaced in 2016 with the introduction of the _Fast Internet Bitcoin Relay Engine_ or https://bitcoinfibre.org[_FIBRE_], also created by core developer Matt Corallo. FIBRE is a UDP-based relay network that relays blocks within a network of nodes. FIBRE implements _compact block_ optimization to further reduce the amount of data transmitted and the network latency.
|
||||
|
||||
Relay networks are not replacements for bitcoin's P2P network. Instead they are overlay networks that provide additional connectivity between nodes with specialized needs. Like freeways are not replacements for rural roads, but rather shortcuts between two points with heavy traffic, you still need small roads to connect to the freeways.
|
||||
|
||||
=== Network Discovery
|
||||
|
||||
((("Bitcoin network", "extended network discovery", id="BNextend08")))((("Bitcoin nodes", "network discovery", id="BNodiscover08")))When a new node boots up, it must discover other Bitcoin nodes on the network in order to participate. To start this process, a new node must discover at least one existing node on the network and connect to it. The geographic location of other nodes is irrelevant; the Bitcoin network topology is not geographically defined. Therefore, any existing Bitcoin nodes can be selected at random.
|
||||
|
||||
To connect to a known peer, nodes establish a TCP connection, usually to port 8333 (the port generally known as the one used by bitcoin), or an alternative port if one is provided. Upon establishing a connection, the node will start a "handshake" (see <<network_handshake>>) by transmitting a +version+ message, which contains basic identifying information, including:
|
||||
|
||||
+nVersion+:: The bitcoin P2P protocol version the client "speaks" (e.g., 70002)
|
||||
+nLocalServices+:: A list of local services supported by the node, currently just +NODE_NETWORK+
|
||||
+nTime+:: The current time
|
||||
+addrYou+:: The IP address of the remote node as seen from this node
|
||||
+addrMe+:: The IP address of the local node, as discovered by the local node
|
||||
+subver+:: A sub-version showing the type of software running on this node (e.g., pass:[<span class="keep-together"><code>/Satoshi:0.9.2.1/</code></span>])
|
||||
+BestHeight+:: The block height of this node's blockchain
|
||||
|
||||
(See https://bit.ly/1qlsC7w[GitHub] for an example of the +version+ network message.)
|
||||
|
||||
The +version+ message is always the first message sent by any peer to another peer. The local peer receiving a +version+ message will examine the remote peer's reported +nVersion+ and decide if the remote peer is compatible. If the remote peer is compatible, the local peer will acknowledge the +version+ message and establish a connection by sending a +verack+ message.
|
||||
|
||||
How does a new node find peers? The first method is to query DNS using a number of "DNS seeds," which are DNS servers that provide a list of IP addresses of Bitcoin nodes. Some of those DNS seeds provide a static list of IP addresses of stable bitcoin listening nodes. Some of the DNS seeds are custom implementations of BIND (Berkeley Internet Name Daemon) that return a random subset from a list of Bitcoin node addresses collected by a crawler or a long-running Bitcoin node. The Bitcoin Core client contains the names of nine different DNS seeds. The diversity of ownership and diversity of implementation of the different DNS seeds offers a high level of reliability for the initial bootstrapping process. In the Bitcoin Core client, the option to use the DNS seeds is controlled by the option switch +-dnsseed+ (set to 1 by default, to use the DNS seed).
|
||||
|
||||
Alternatively, a bootstrapping node that knows nothing of the network must be given the IP address of at least one Bitcoin node, after which it can establish connections through further introductions. The command-line argument +-seednode+ can be used to connect to one node just for introductions using it as a seed. After the initial seed node is used to form introductions, the client will disconnect from it and use the newly discovered peers.
|
||||
|
||||
[[network_handshake]]
|
||||
.The initial handshake between peers
|
||||
image::images/mbc2_0804.png["NetworkHandshake"]
|
||||
|
||||
Once one or more connections are established, the new node will send an +addr+ message containing its own IP address to its neighbors. The neighbors will, in turn, forward the +addr+ message to their neighbors, ensuring that the newly connected node becomes well known and better connected. Additionally, the newly connected node can send +getaddr+ to the neighbors, asking them to return a list of IP addresses of other peers. That way, a node can find peers to connect to and advertise its existence on the network for other nodes to find it. <<address_propagation>> ((("propagation", "address propagation and discovery")))shows the address discovery protocol.
|
||||
|
||||
|
||||
[[address_propagation]]
|
||||
.Address propagation and discovery
|
||||
image::images/mbc2_0805.png["AddressPropagation"]
|
||||
|
||||
A node must connect to a few different peers in order to establish diverse paths into the Bitcoin network. Paths are not persistent—nodes come and go—and so the node must continue to discover new nodes as it loses old connections as well as assist other nodes when they bootstrap. Only one connection is needed to bootstrap, because the first node can offer introductions to its peer nodes and those peers can offer further introductions. It's also unnecessary and wasteful of network resources to connect to more than a handful of nodes. After bootstrapping, a node will remember its most recent successful peer connections, so that if it is rebooted it can quickly reestablish connections with its former peer network. If none of the former peers respond to its connection request, the node can use the seed nodes to bootstrap again.
|
||||
|
||||
On a node running the Bitcoin Core client, you can list the peer connections with the command +getpeerinfo+:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
$ bitcoin-cli getpeerinfo
|
||||
----
|
||||
[source,json]
|
||||
----
|
||||
[
|
||||
{
|
||||
"addr" : "85.213.199.39:8333",
|
||||
"services" : "00000001",
|
||||
"lastsend" : 1405634126,
|
||||
"lastrecv" : 1405634127,
|
||||
"bytessent" : 23487651,
|
||||
"bytesrecv" : 138679099,
|
||||
"conntime" : 1405021768,
|
||||
"pingtime" : 0.00000000,
|
||||
"version" : 70002,
|
||||
"subver" : "/Satoshi:0.9.2.1/",
|
||||
"inbound" : false,
|
||||
"startingheight" : 310131,
|
||||
"banscore" : 0,
|
||||
"syncnode" : true
|
||||
},
|
||||
{
|
||||
"addr" : "58.23.244.20:8333",
|
||||
"services" : "00000001",
|
||||
"lastsend" : 1405634127,
|
||||
"lastrecv" : 1405634124,
|
||||
"bytessent" : 4460918,
|
||||
"bytesrecv" : 8903575,
|
||||
"conntime" : 1405559628,
|
||||
"pingtime" : 0.00000000,
|
||||
"version" : 70001,
|
||||
"subver" : "/Satoshi:0.8.6/",
|
||||
"inbound" : false,
|
||||
"startingheight" : 311074,
|
||||
"banscore" : 0,
|
||||
"syncnode" : false
|
||||
}
|
||||
]
|
||||
----
|
||||
|
||||
To override the automatic management of peers and to specify a list of IP addresses, users can provide the option +-connect=<IPAddress>+ and specify one or more IP addresses. If this option is used, the node will only connect to the selected IP addresses, instead of discovering and maintaining the peer connections automatically.
|
||||
|
||||
If there is no traffic on a connection, nodes will periodically send a message to maintain the connection. If a node has not communicated on a connection for more than 90 minutes, it is assumed to be disconnected and a new peer will be sought. Thus, the network dynamically adjusts to transient nodes and network problems, and can organically grow and shrink as needed without any central control.((("", startref="BNextend08")))((("", startref="BNodiscover08")))
|
||||
|
||||
=== Full Nodes
|
||||
|
||||
((("Bitcoin network", "full nodes")))((("full-node clients")))((("blockchain (the)", "full blockchain nodes")))Full nodes are nodes that maintain a full blockchain with all transactions. More accurately, they probably should be called "full blockchain nodes." In the early years of bitcoin, all nodes were full nodes and currently the Bitcoin Core client is a full blockchain node. In the past two years, however, new forms of Bitcoin clients have been introduced that do not maintain a full blockchain but run as lightweight clients. We'll examine these in more detail in the next section.
|
||||
|
||||
((("blocks", "genesis block")))((("genesis block")))((("blockchain (the)", "genesis block")))Full blockchain nodes maintain a complete and up-to-date copy of the Bitcoin blockchain with all the transactions, which they independently build and verify, starting with the very first block (genesis block) and building up to the latest known block in the network. A full blockchain node can independently and authoritatively verify any transaction without recourse or reliance on any other node or source of information. The full blockchain node relies on the network to receive updates about new blocks of transactions, which it then verifies and incorporates into its local copy of the blockchain.
|
||||
|
||||
((("Bitcoin nodes", "full nodes")))Running a full blockchain node gives you the pure bitcoin experience: independent verification of all transactions without the need to rely on, or trust, any other systems. It's easy to tell if you're running a full node because it requires more than one hundred gigabytes of persistent storage (disk space) to store the full blockchain. If you need a lot of disk and it takes two to three days to sync to the network, you are running a full node. That is the price of complete independence and freedom from central authority.
|
||||
|
||||
((("Satoshi client")))There are a few alternative implementations of full blockchain Bitcoin clients, built using different programming languages and software architectures. However, the most common implementation is the reference client Bitcoin Core, also known as the Satoshi client. More than 75% of the nodes on the Bitcoin network run various versions of Bitcoin Core. It is identified as "Satoshi" in the sub-version string sent in the +version+ message and shown by the command +getpeerinfo+ as we saw earlier; for example, +/Satoshi:0.8.6/+.
|
||||
|
||||
=== Exchanging "Inventory"
|
||||
|
||||
((("Bitcoin network", "syncing the blockchain")))The first thing a full node will do once it connects to peers is try to construct a complete blockchain. If it is a brand-new node and has no blockchain at all, it only knows one block, the genesis block, which is statically embedded in the client software. Starting with block #0 (the genesis block), the new node will have to download hundreds of thousands of blocks to synchronize with the network and reestablish the full blockchain.
|
||||
|
||||
((("blockchain (the)", "syncing the blockchain")))((("syncing")))The process of syncing the blockchain starts with the +version+ message, because that contains +BestHeight+, a node's current blockchain height (number of blocks). A node will see the +version+ messages from its peers, know how many blocks they each have, and be able to compare to how many blocks it has in its own blockchain. Peered nodes will exchange a +getblocks+ message that contains the hash (fingerprint) of the top block on their local blockchain. One of the peers will be able to identify the received hash as belonging to a block that is not at the top, but rather belongs to an older block, thus deducing that its own local blockchain is longer than its peer's.
|
||||
|
||||
The peer that has the longer blockchain has more blocks than the other node and can identify which blocks the other node needs in order to "catch up." It will identify the first 500 blocks to share and transmit their hashes using an +inv+ (inventory) message. The node missing these blocks will then retrieve them, by issuing a series of +getdata+ messages requesting the full block data and identifying the requested blocks using the hashes from the +inv+ message.
|
||||
|
||||
Let's assume, for example, that a node only has the genesis block. It will then receive an +inv+ message from its peers containing the hashes of the next 500 blocks in the chain. It will start requesting blocks from all of its connected peers, spreading the load and ensuring that it doesn't overwhelm any peer with requests. The node keeps track of how many blocks are "in transit" per peer connection, meaning blocks that it has requested but not received, checking that it does not exceed a limit (+MAX_BLOCKS_IN_TRANSIT_PER_PEER+). This way, if it needs a lot of blocks, it will only request new ones as previous requests are fulfilled, allowing the peers to control the pace of updates and not overwhelm the network. As each block is received, it is added to the blockchain, as we will see in <<blockchain>>. As the local blockchain is gradually built up, more blocks are requested and received, and the process continues until the node catches up to the rest of the network.
|
||||
|
||||
This process of comparing the local blockchain with the peers and retrieving any missing blocks happens any time a node goes offline for any period of time. Whether a node has been offline for a few minutes and is missing a few blocks, or a month and is missing a few thousand blocks, it starts by sending +getblocks+, gets an +inv+ response, and starts downloading the missing blocks. <<inventory_synchronization>> shows the inventory and block propagation protocol.
|
||||
|
||||
[[inventory_synchronization]]
|
||||
[role="smallerfifty"]
|
||||
.Node synchronizing the blockchain by retrieving blocks from a peer
|
||||
image::images/mbc2_0806.png["InventorySynchronization"]
|
||||
|
||||
[[spv_nodes]]
|
||||
=== Simplified Payment Verification (SPV) Nodes
|
||||
|
||||
((("Bitcoin network", "SPV nodes", id="BNspvnodes08")))((("Bitcoin nodes", "SPV nodes", id="BNospv08")))((("simplified-payment-verification (SPV)", id="simple08")))Not all nodes have the ability to store the full blockchain. Many Bitcoin clients are designed to run on space- and power-constrained devices, such as smartphones, tablets, or embedded systems. For such devices, a _simplified payment verification_ (SPV) method is used to allow them to operate without storing the full blockchain. These types of clients are called SPV clients or lightweight clients. As bitcoin adoption surges, the SPV node is becoming the most common form of Bitcoin node, especially for bitcoin wallets.
|
||||
|
||||
SPV nodes download only the block headers and do not download the transactions included in each block. The resulting chain of blocks, without transactions, is 1,000 times smaller than the full blockchain. SPV nodes cannot construct a full picture of all the UTXOs that are available for spending because they do not know about all the transactions on the network. SPV nodes verify transactions using a slightly different method that relies on peers to provide partial views of relevant parts of the blockchain on demand.
|
||||
|
||||
As an analogy, a full node is like a tourist in a strange city, equipped with a detailed map of every street and every address. By comparison, an SPV node is like a tourist in a strange city asking random strangers for turn-by-turn directions while knowing only one main avenue. Although both tourists can verify the existence of a street by visiting it, the tourist without a map doesn't know what lies down any of the side streets and doesn't know what other streets exist. Positioned in front of 23 Church Street, the tourist without a map cannot know if there are a dozen other "23 Church Street" addresses in the city and whether this is the right one. The mapless tourist's best chance is to ask enough people and hope some of them are not trying to mug him.
|
||||
|
||||
SPV verifies transactions by reference to their _depth_ in the blockchain instead of their _height_. Whereas a full blockchain node will construct a fully verified chain of thousands of blocks and transactions reaching down the blockchain (back in time) all the way to the genesis block, an SPV node will verify the chain of all blocks (but not all transactions) and link that chain to the transaction of interest.
|
||||
|
||||
For example, when examining a transaction in block 300,000, a full node links all 300,000 blocks down to the genesis block and builds a full database of UTXO, establishing the validity of the transaction by confirming that the UTXO remains unspent. An SPV node cannot validate whether the UTXO is unspent. Instead, the SPV node will establish a link between the transaction and the block that contains it, using a _merkle path_ (see <<merkle_trees>>). Then, the SPV node waits until it sees the six blocks 300,001 through 300,006 piled on top of the block containing the transaction and verifies it by establishing its depth under blocks 300,006 to 300,001. The fact that other nodes on the network accepted block 300,000 and then did the necessary work to produce six more blocks on top of it is proof, by proxy, that the transaction was not a double-spend.
|
||||
|
||||
An SPV node cannot be persuaded that a transaction exists in a block when the transaction does not in fact exist. The SPV node establishes the existence of a transaction in a block by requesting a merkle path proof and by validating the Proof-of-Work in the chain of blocks. However, a transaction's existence can be "hidden" from an SPV node. An SPV node can definitely prove that a transaction exists but cannot verify that a transaction, such as a double-spend of the same UTXO, doesn't exist because it doesn't have a record of all transactions. This vulnerability can be used in a denial-of-service attack or for a double-spending attack against SPV nodes. To defend against this, an SPV node needs to connect randomly to several nodes, to increase the probability that it is in contact with at least one honest node. This need to randomly connect means that SPV nodes also are vulnerable to network partitioning attacks or Sybil attacks, where they are connected to fake nodes or fake networks and do not have access to honest nodes or the real Bitcoin network.
|
||||
|
||||
For most practical purposes, well-connected SPV nodes are secure enough, striking a balance between resource needs, practicality, and security. For infallible security, however, nothing beats running a full blockchain node.
|
||||
|
||||
[TIP]
|
||||
====
|
||||
A full blockchain node verifies a transaction by checking the entire chain of thousands of blocks below it in order to guarantee that the UTXO is not spent, whereas an SPV node checks how deep the block is buried by a handful of blocks above it.
|
||||
====
|
||||
|
||||
To get the block headers, SPV nodes use a +getheaders+ message instead of +getblocks+. The responding peer will send up to 2,000 block headers using a single +headers+ message. The process is otherwise the same as that used by a full node to retrieve full blocks. SPV nodes also set a filter on the connection to peers, to filter the stream of future blocks and transactions sent by the peers. Any transactions of interest are retrieved using a +getdata+ request. The peer generates a +tx+ message containing the transactions, in response. <<spv_synchronization>> shows the synchronization of block headers.
|
||||
|
||||
Because SPV nodes need to retrieve specific transactions in order to selectively verify them, they also create a privacy risk. Unlike full blockchain nodes, which collect all transactions within each block, the SPV node's requests for specific data can inadvertently reveal the addresses in their wallet. For example, a third party monitoring a network could keep track of all the transactions requested by a wallet on an SPV node and use those to associate Bitcoin addresses with the user of that wallet, destroying the user's privacy.
|
||||
|
||||
[[spv_synchronization]]
|
||||
.SPV node synchronizing the block headers
|
||||
image::images/mbc2_0807.png["SPVSynchronization"]
|
||||
|
||||
Shortly after the introduction of SPV/lightweight nodes, bitcoin developers added a feature called _bloom filters_ to address the privacy risks of SPV nodes. Bloom filters allow SPV nodes to receive a subset of the transactions without revealing precisely which addresses they are interested in, through a filtering mechanism that uses probabilities rather than fixed patterns.((("", startref="BNspvnodes08")))((("", startref="simple08")))
|
||||
|
||||
[[bloom_filters]]
|
||||
=== Bloom Filters
|
||||
|
||||
((("Bitcoin network", "bloom filters", id="BNebloom08")))((("bloom filters", id="bloom08")))((("privacy, maintaining", id="privacy08")))((("security", "maintaining privacy", id="Sprivacy08")))A bloom filter is a probabilistic search filter that offers an efficient way to express a search pattern while protecting privacy. They are used by SPV nodes to ask their peers for transactions matching a specific pattern, without revealing exactly which addresses, keys, or transactions they are searching for.
|
||||
|
||||
In our previous analogy, a tourist without a map is asking for directions to a specific address, "23 Church St." If she asks strangers for directions to this street, she inadvertently reveals her destination. A bloom filter is like asking, "Are there any streets in this neighborhood whose name ends in R-C-H?" A question like that reveals slightly less about the desired destination than asking for "23 Church St." Using this technique, a tourist could specify the desired address in more detail such as "ending in U-R-C-H" or less detail as "ending in H." By varying the precision of the search, the tourist reveals more or less information, at the expense of getting more or less specific results. If she asks a less specific pattern, she gets a lot more possible addresses and better privacy, but many of the results are irrelevant. If she asks for a very specific pattern, she gets fewer results but loses privacy.
|
||||
|
||||
Bloom filters serve this function by allowing an SPV node to specify a search pattern for transactions that can be tuned toward precision or privacy. A more specific bloom filter will produce accurate results, but at the expense of revealing what patterns the SPV node is interested in, thus revealing the addresses owned by the user's wallet. A less specific bloom filter will produce more data about more transactions, many irrelevant to the node, but will allow the node to maintain better privacy.
|
||||
|
||||
==== How Bloom Filters Work
|
||||
|
||||
Bloom filters are implemented as a variable-size array of N binary digits (a bit field) and a variable number of M hash functions. The hash functions are designed to always produce an output that is between 1 and N, corresponding to the array of binary digits. The hash functions are generated deterministically, so that any node implementing a bloom filter will always use the same hash functions and get the same results for a specific input. By choosing different length (N) bloom filters and a different number (M) of hash functions, the bloom filter can be tuned, varying the level of accuracy and therefore privacy.
|
||||
|
||||
In <<bloom1>>, we use a very small array of 16 bits and a set of three hash functions to demonstrate how bloom filters work.
|
||||
|
||||
[[bloom1]]
|
||||
.An example of a simplistic bloom filter, with a 16-bit field and three hash functions
|
||||
image::images/mbc2_0808.png["Bloom1"]
|
||||
|
||||
The bloom filter is initialized so that the array of bits is all zeros. To add a pattern to the bloom filter, the pattern is hashed by each hash function in turn. Applying the first hash function to the input results in a number between 1 and N. The corresponding bit in the array (indexed from 1 to N) is found and set to +1+, thereby recording the output of the hash function. Then, the next hash function is used to set another bit and so on. Once all M hash functions have been applied, the search pattern will be "recorded" in the bloom filter as M bits that have been changed from +0+ to +1+.
|
||||
|
||||
<<bloom2>> is an example of adding a pattern "A" to the simple bloom filter shown in <<bloom1>>.
|
||||
|
||||
Adding a second pattern is as simple as repeating this process. The pattern is hashed by each hash function in turn and the result is recorded by setting the bits to +1+. Note that as a bloom filter is filled with more patterns, a hash function result might coincide with a bit that is already set to +1+, in which case the bit is not changed. In essence, as more patterns record on overlapping bits, the bloom filter starts to become saturated with more bits set to +1+ and the accuracy of the filter decreases. This is why the filter is a probabilistic data structure—it gets less accurate as more patterns are added. The accuracy depends on the number of patterns added versus the size of the bit array (N) and number of hash functions (M). A larger bit array and more hash functions can record more patterns with higher accuracy. A smaller bit array or fewer hash functions will record fewer patterns and produce less accuracy.
|
||||
|
||||
[[bloom2]]
|
||||
.Adding a pattern "A" to our simple bloom filter
|
||||
image::images/mbc2_0809.png["Bloom2"]
|
||||
|
||||
<<bloom3>> is an example of adding a second pattern "B" to the simple bloom filter.
|
||||
|
||||
[[bloom3]]
|
||||
[role="smallereighty"]
|
||||
.Adding a second pattern "B" to our simple bloom filter
|
||||
image::images/mbc2_0810.png["Bloom3"]
|
||||
|
||||
To test if a pattern is part of a bloom filter, the pattern is hashed by each hash function and the resulting bit pattern is tested against the bit array. If all the bits indexed by the hash functions are set to +1+, then the pattern is _probably_ recorded in the bloom filter. Because the bits may be set because of overlap from multiple patterns, the answer is not certain, but is rather probabilistic. In simple terms, a bloom filter positive match is a "Maybe, Yes."
|
||||
|
||||
<<bloom4>> is an example of testing the existence of pattern "X" in the simple bloom filter. The corresponding bits are set to +1+, so the pattern is probably a match.
|
||||
|
||||
[[bloom4]]
|
||||
[role="smallereighty"]
|
||||
.Testing the existence of pattern "X" in the bloom filter. The result is a probabilistic positive match, meaning "Maybe."
|
||||
image::images/mbc2_0811.png["Bloom4"]
|
||||
|
||||
On the contrary, if a pattern is tested against the bloom filter and any one of the bits is set to +0+, this proves that the pattern was not recorded in the bloom filter. A negative result is not a probability, it is a certainty. In simple terms, a negative match on a bloom filter is a "Definitely Not!"
|
||||
|
||||
<<bloom5>> is an example of testing the existence of pattern "Y" in the simple bloom filter. One of the corresponding bits is set to +0+, so the pattern is definitely not a match.
|
||||
|
||||
[[bloom5]]
|
||||
.Testing the existence of pattern "Y" in the bloom filter. The result is a definitive negative match, meaning "Definitely Not!"
|
||||
image::images/mbc2_0812.png[]
|
||||
|
||||
=== How SPV Nodes Use Bloom Filters
|
||||
|
||||
Bloom filters are used to filter the transactions (and blocks containing them) that an SPV node receives from its peers, selecting only transactions of interest to the SPV node without revealing which addresses or keys it is interested in.
|
||||
|
||||
((("transaction IDs (txid)")))An SPV node will initialize a bloom filter as "empty"; in that state the bloom filter will not match any patterns. The SPV node will then make a list of all the addresses, keys, and hashes that it is interested in. It will do this by extracting the public key hash and script hash and transaction IDs from any UTXO controlled by its wallet. The SPV node then adds each of these to the bloom filter, so that the bloom filter will "match" if these patterns are present in a transaction, without revealing the patterns themselves.
|
||||
|
||||
((("Bitcoin nodes", "full nodes")))The SPV node will then send a +filterload+ message to the peer, containing the bloom filter to use on the connection. On the peer, bloom filters are checked against each incoming transaction. The full node checks several parts of the transaction against the bloom filter, looking for a match including:
|
||||
|
||||
* The transaction ID
|
||||
* The data components from the locking scripts of each of the transaction outputs (every key and hash in the script)
|
||||
* Each of the transaction inputs
|
||||
* Each of the input signature data components (or witness scripts)
|
||||
|
||||
By checking against all these components, bloom filters can be used to match public key hashes, scripts, +OP_RETURN+ values, public keys in signatures, or any future component of a smart contract or complex script.
|
||||
|
||||
After a filter is established, the peer will then test each transaction's output against the bloom filter. Only transactions that match the filter are sent to the node.
|
||||
|
||||
In response to a +getdata+ message from the node, peers will send a +merkleblock+ message that contains only block headers for blocks matching the filter and a merkle path (see <<merkle_trees>>) for each matching transaction. The peer will then also send +tx+ messages containing the transactions matched by the filter.
|
||||
|
||||
As the full node sends transactions to the SPV node, the SPV node discards any false positives and uses the correctly matched transactions to update its UTXO set and wallet balance. As it updates its own view of the UTXO set, it also modifies the bloom filter to match any future transactions referencing the UTXO it just found. The full node then uses the new bloom filter to match new transactions and the whole process repeats.
|
||||
|
||||
The node setting the bloom filter can interactively add patterns to the filter by sending a +filteradd+ message. To clear the bloom filter, the node can send a +filterclear+ message. Because it is not possible to remove a pattern from a bloom filter, a node has to clear and resend a new bloom filter if a pattern is no longer desired.
|
||||
|
||||
The network protocol and bloom filter mechanism for SPV nodes is defined in https://bit.ly/1x6qCiO[BIP-37 (Peer Services)].((("", startref="BNebloom08")))((("", startref="bloom08")))
|
||||
|
||||
|
||||
=== SPV Nodes and Privacy
|
||||
|
||||
Nodes that implement SPV have weaker privacy than a full node. A full node receives all transactions and therefore reveals no information about whether it is using some address in its wallet. An SPV node receives a filtered list of transactions related to the addresses that are in its wallet. As a result, it reduces the privacy of the owner.
|
||||
|
||||
Bloom filters are a way to reduce the loss of privacy. Without them, an SPV node would have to explicitly list the addresses it was interested in, creating a serious breach of privacy. However, even with bloom filters, an adversary monitoring the traffic of an SPV client or connected to it directly as a node in the P2P network can collect enough information over time to learn the addresses in the wallet of the SPV client.
|
||||
|
||||
=== Encrypted and Authenticated Connections
|
||||
|
||||
((("Bitcoin network", "encrypted connections")))((("encryption")))((("authentication")))Most new users of bitcoin assume that the network communications of a Bitcoin node are encrypted. In fact, the original implementation of bitcoin communicates entirely in the clear. While this is not a major privacy concern for full nodes, it is a big problem for SPV nodes.
|
||||
|
||||
As a way to increase the privacy and security of the bitcoin P2P network, there are two solutions that provide encryption of the communications: _Tor Transport_ and _P2P Authentication and Encryption_ with BIP-150/151.
|
||||
|
||||
==== Tor Transport
|
||||
|
||||
((("Tor network")))((("The Onion Routing network (Tor)")))Tor, which stands for _The Onion Routing network_, is a software project and network that offers encryption and encapsulation of data through randomized network paths that offer anonymity, untraceability and privacy.
|
||||
|
||||
Bitcoin Core offers several configuration options that allow you to run a Bitcoin node with its traffic transported over the Tor network. In addition, Bitcoin Core can also offer a Tor hidden service allowing other Tor nodes to connect to your node directly over Tor.
|
||||
|
||||
As of Bitcoin Core version 0.12, a node will offer a hidden Tor service automatically if it is able to connect to a local Tor service. If you have Tor installed and the Bitcoin Core process runs as a user with adequate permissions to access the Tor authentication cookie, it should work automatically. Use the +debug+ flag to turn on Bitcoin Core's debugging for the Tor service like this:
|
||||
|
||||
----
|
||||
$ bitcoind --daemon --debug=tor
|
||||
----
|
||||
|
||||
You should see "tor: ADD_ONION successful" in the logs, indicating that Bitcoin Core has added a hidden service to the Tor network.
|
||||
|
||||
You can find more instructions on running Bitcoin Core as a Tor hidden service in the Bitcoin Core documentation (_docs/tor.md_) and various online tutorials.
|
||||
|
||||
==== Peer-to-Peer Authentication and Encryption
|
||||
|
||||
((("Peer-to-Peer authentication and encryption")))((("bitcoin improvement proposals", "Peer Authentication (BIP-150)")))((("bitcoin improvement proposals", "Peer-to-Peer Communication Encryption (BIP-151)")))Two Bitcoin Improvement Proposals, BIP-150 and BIP-151, add support for P2P authentication and encryption in the bitcoin P2P network. These two BIPs define optional services that may be offered by compatible Bitcoin nodes. BIP-151 enables negotiated encryption for all communications between two nodes that support BIP-151. BIP-150 offers optional peer authentication that allows nodes to authenticate each other's identity using ECDSA and private keys. BIP-150 requires that prior to authentication the two nodes have established encrypted communications as per BIP-151.
|
||||
|
||||
As of February 2021, BIP-150 and BIP-151 are not implemented in Bitcoin Core. However, the two proposals have been implemented by at least one alternative Bitcoin client named bcoin.
|
||||
|
||||
BIP-150 and BIP-151 allow users to run SPV clients that connect to a trusted full node, using encryption and authentication to protect the privacy of the SPV client.
|
||||
|
||||
Additionally, authentication can be used to create networks of trusted Bitcoin nodes and prevent Man-in-the-Middle attacks. Finally, P2P encryption, if deployed broadly, would strengthen the resistance of bitcoin to traffic analysis and privacy-eroding surveillance, especially in totalitarian countries where internet use is heavily controlled and monitored.
|
||||
|
||||
((("", startref="BNospv08")))((("", startref="privacy08")))((("", startref="Sprivacy08")))The standard is defined in https://github.com/bitcoin/bips/blob/master/bip-0150.mediawiki[BIP-150 (Peer Authentication)] and https://github.com/bitcoin/bips/blob/master/bip-0151.mediawiki[BIP-151 (Peer-to-Peer Communication Encryption)].
|
||||
|
||||
=== Transaction Pools
|
||||
|
||||
((("Bitcoin network", "transaction pools")))((("transaction pools")))((("memory pools (mempools)")))Almost every node on the Bitcoin network maintains a temporary list of unconfirmed transactions called the _memory pool_, _mempool_, or _transaction pool_. Nodes use this pool to keep track of transactions that are known to the network but are not yet included in the blockchain. For example, a wallet node will use the transaction pool to track incoming payments to the user's wallet that have been received on the network but are not yet confirmed.
|
||||
|
||||
As transactions are received and verified, they are added to the transaction pool and relayed to the neighboring nodes to propagate on the network.
|
||||
|
||||
((("orphan pools")))((("transactions", "orphaned")))Some node implementations also maintain a separate pool of orphaned transactions. If a transaction's inputs refer to a transaction that is not yet known, such as a missing parent, the orphan transaction will be stored temporarily in the orphan pool until the parent transaction arrives.
|
||||
|
||||
When a transaction is added to the transaction pool, the orphan pool is checked for any orphans that reference this transaction's outputs (its children). Any matching orphans are then validated. If valid, they are removed from the orphan pool and added to the transaction pool, completing the chain that started with the parent transaction. In light of the newly added transaction, which is no longer an orphan, the process is repeated recursively looking for any further descendants, until no more descendants are found. Through this process, the arrival of a parent transaction triggers a cascade reconstruction of an entire chain of interdependent transactions by re-uniting the orphans with their parents all the way down the chain.
|
||||
|
||||
Both the transaction pool and orphan pool (where implemented) are stored in local memory and are not saved on persistent storage; rather, they are dynamically populated from incoming network messages. When a node starts, both pools are empty and are gradually populated with new transactions received on the network.
|
||||
|
||||
Some implementations of the Bitcoin client also maintain an UTXO database or pool, which is the set of all unspent outputs on the blockchain. Bitcoin Core users will find it in the +chainstate/+ folder of their client's data directory. Although the name "UTXO pool" sounds similar to the transaction pool, it represents a different set of data. Unlike the transaction and orphan pools, the UTXO pool is not initialized empty but instead contains millions of entries of unspent transaction outputs, everything that is unspent from all the way back to the genesis block. The UTXO pool may be housed in local memory or as an indexed database table on persistent storage.
|
||||
|
||||
Whereas the transaction and orphan pools represent a single node's local perspective and might vary significantly from node to node depending upon when the node was started or restarted, the UTXO pool represents the emergent consensus of the network and therefore will vary little between nodes. Furthermore, the transaction and orphan pools only contain unconfirmed transactions, while the UTXO pool only contains confirmed outputs.
|
@ -0,0 +1,685 @@
|
||||
[[tx_fees]]
|
||||
== Transaction Fees
|
||||
|
||||
++++
|
||||
<p class="fix_tracking">
|
||||
The digital signature we saw Alice create in <a data-type="xref" href="#c_signatures">#c_signatures</a> only
|
||||
proves that she knows her private key and that she committed to a
|
||||
transaction that pays Bob. She can create another signature that
|
||||
instead commits to a transaction paying Carol—a transaction that spends
|
||||
the same output (bitcoins) that she used to pay Bob. Those two
|
||||
transactions are now <em>conflicting transactions</em> because only one
|
||||
transaction spending a particular output can be included in the valid
|
||||
blockchain with the most proof of work—the blockchain that full nodes
|
||||
use to determine which keys control which bitcoins.
|
||||
</p>
|
||||
++++
|
||||
|
||||
To((("conflicting transactions")))((("transactions", "conflicts in"))) protect himself against conflicting transactions, it would be wise
|
||||
for Bob to wait until the transaction from Alice is included in the
|
||||
blockchain to a sufficient depth before he considers the money he
|
||||
received as his to spend (see <<confirmations>>).
|
||||
For Alice's transaction to be included in the
|
||||
blockchain, it must be included in a _block_ of transactions. There are
|
||||
a limited number of((("blocks", "transactions in")))((("transactions", "in blocks", secondary-sortas="blocks"))) blocks produced in a given amount of time, and each
|
||||
block only has a limited amount of space. Only the miner who creates
|
||||
that block gets to choose which transactions to include. Miners may
|
||||
select transactions by any criteria they want, including refusing to
|
||||
include any transactions at all.
|
||||
|
||||
++++
|
||||
<div data-type="note">
|
||||
<p class="fix_tracking"> When we say "transactions" in this chapter, we refer to every
|
||||
transaction in a block except for the first transaction. The first
|
||||
transaction in a block is a <em>coinbase transaction</em>, described in
|
||||
<a data-type="xref" href="#coinbase_transactions">#coinbase_transactions</a>, which allows the miner of the block to
|
||||
collect their reward for producing the block. Unlike other
|
||||
transactions, a coinbase transaction doesn't spend the output of a
|
||||
previous transaction and is also an exception to several other rules
|
||||
that apply to other transactions. Coinbase transactions don't pay
|
||||
transaction fees, don't need to be fee bumped, aren't subject to
|
||||
transaction pinning, and are largely uninteresting to the following
|
||||
discussion about fees—so we're going to ignore them in this chapter.
|
||||
</p>
|
||||
</div>
|
||||
++++
|
||||
|
||||
|
||||
The criterion that almost all miners use to select which transactions to
|
||||
include in their blocks is to maximize their revenue. Bitcoin was
|
||||
specifically designed to accommodate this by providing a mechanism that
|
||||
allows a transaction to give money to the miner who includes that
|
||||
transaction in a block. We call that mechanism _transaction fees_,
|
||||
although it's not a fee in the usual sense of that word. It's not an
|
||||
amount set by the protocol or by any particular miner--it's much more
|
||||
like a bid in an auction. The good being purchased is the portion of
|
||||
limited space in a block that a transaction will consume. Miners choose
|
||||
the set of transactions whose bids will allow them to earn the greatest
|
||||
revenue.
|
||||
|
||||
In this chapter, we'll explore various aspects of those
|
||||
bids--transaction fees--and how they influence the creation and
|
||||
management of Bitcoin transactions.
|
||||
|
||||
=== Who Pays the Transaction Fee?
|
||||
|
||||
Most ((("transaction fees", "responsibility for", id="fees-responsibility")))((("payments", "transaction fees", see="transaction fees")))((("fees", see="transaction fees")))payment systems involve some sort of fee for transacting, but
|
||||
often this fee is hidden from typical buyers. For example, a merchant
|
||||
may advertise the same item for the same price whether you pay with cash
|
||||
or a credit card even though their payment processor may charge them
|
||||
a higher fee for credit transactions than their bank charges them for
|
||||
cash deposits.
|
||||
|
||||
In Bitcoin, every spend of bitcoins must be authenticated (typically
|
||||
with a signature), so it's not possible for a transaction to pay a fee
|
||||
without the permission of the spender. It is possible for the receiver
|
||||
of a transaction to pay a fee in a different transaction--and we'll see
|
||||
that in use later--but if we want a single transaction to pay its own
|
||||
fee, that fee needs to be something agreed upon by the spender. It
|
||||
can't be hidden.
|
||||
|
||||
Bitcoin transactions are designed so that it doesn't take any extra
|
||||
space in a transaction for a spender to commit to the fee it pays. That
|
||||
means that, even though it's possible to pay the fee in a different
|
||||
transaction, it's most efficient (and thus cheapest) to pay the fee in a
|
||||
single transaction.
|
||||
|
||||
In Bitcoin,
|
||||
the fee is a bid and the amount paid contributes to determining how long
|
||||
it will take the transaction to confirm. Both spenders and receivers of
|
||||
a payment typically have an interest in having it confirming quickly, so
|
||||
normally allowing only spenders to choose fees can sometimes be a
|
||||
problem; we'll look at a solution to that problem in <<cpfp>>. However,
|
||||
in many common payment flows, the parties with the highest desire to see a
|
||||
transaction confirm quickly--that is, the parties who would be the most
|
||||
willing to pay higher fees--are the spenders.
|
||||
|
||||
For those reasons, both technical and practical, it is customary in
|
||||
Bitcoin for spenders to pay transaction fees. There are exceptions,
|
||||
such as for merchants that accept unconfirmed transactions and in
|
||||
protocols that don't immediately broadcast [.keep-together]#transactions# after they are
|
||||
signed (preventing the spender from being able to choose an appropriate
|
||||
fee for the current market). We'll explore those exceptions((("transaction fees", "responsibility for", startref="fees-responsibility"))) later.
|
||||
|
||||
=== Fees and Fee Rates
|
||||
|
||||
Each ((("transaction fees", "fee rates", id="fees-rates")))((("fee rates", id="fee-rate")))transaction only pays a single fee--it doesn't matter how large the
|
||||
transaction is. However, the larger transactions become, the fewer of
|
||||
them a miner will be able to fit in a block. For that reason, miners
|
||||
evaluate transactions the same way you might comparison shop between
|
||||
several equivalent items at the market: they divide the price by the
|
||||
quantity.
|
||||
|
||||
Whereas you might divide the cost of several different bags of rice by
|
||||
each bag's weight to find the lowest price per weight (best deal), miners
|
||||
divide the fee of a transaction by its size (also called its weight) to
|
||||
find the highest fee per weight (most revenue). In Bitcoin, we use the
|
||||
term _fee rate_ for a transaction's size divided by weight. Due to
|
||||
changes in Bitcoin over the years, fee rate can be expressed in
|
||||
different units:
|
||||
|
||||
- BTC/Bytes (a legacy unit rarely used anymore)
|
||||
- BTC/Kilobytes (a legacy unit rarely used anymore)
|
||||
- BTC/Vbytes (rarely used)
|
||||
- BTC/Kilo-vbyte (used mainly in Bitcoin Core)
|
||||
- Satoshi/Vbyte (most commonly used today)
|
||||
- Satoshi/Weight (also commonly used today)
|
||||
|
||||
We recommend either the sat/vbyte or sat/weight units for displaying
|
||||
fee rates.
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
Be careful ((("absurd fees")))((("excessive fees")))((("transaction fees", "overpaying")))((("overpaying transaction fees")))accepting input for fee rates. If a user copies and pastes a
|
||||
fee rate printed in one denominator into a field using a different
|
||||
denominator, they could overpay fees by 1,000 times. If they instead
|
||||
switch the numerator, they could theoretically overpay by 100,000,000
|
||||
times. Wallets should make it hard for the user to pay an excessive
|
||||
fee rate and may want to prompt the user to confirm any fee rate that was
|
||||
not generated by the wallet itself using a trusted data source.
|
||||
|
||||
An excessive fee, also called an _absurd fee_, is any fee rate that's
|
||||
significantly higher than the amount that fee rate estimators currently
|
||||
expect is necessary to get a transaction confirmed in the next block.
|
||||
Note that wallets should not entirely prevent users from choosing an
|
||||
excessive fee rate--they should only make using such a fee rate hard to do
|
||||
by accident. There are legitimate reasons for users to overpay fees on
|
||||
rare occasions.
|
||||
====
|
||||
|
||||
=== Estimating Appropriate Fee Rates
|
||||
|
||||
We've ((("estimating fee rates", id="estimate-fee-rate")))established that you can pay a lower fee rate if you're willing to
|
||||
wait longer for your transaction to be confirmed, with the exception
|
||||
that paying too low of a fee rate could result in your transaction never
|
||||
confirming. Because fee rates are bids in an open auction for block
|
||||
space, it's not possible to perfectly predict what fee rate you need to
|
||||
pay to get your transaction confirmed by a certain time. However, we
|
||||
can generate a rough estimate based on what fee rates other transactions
|
||||
have paid in the recent past.
|
||||
|
||||
A full node can record three pieces of information about each
|
||||
transactions it sees: the time (block height) when it first received
|
||||
that transaction, the block height when that transaction was confirmed,
|
||||
and the fee rate paid by that transaction. By grouping together
|
||||
transactions that arrived at similar heights, were confirmed at similar
|
||||
heights, and which paid similar fees, we can calculate how many blocks it
|
||||
took to confirm transactions paying a certain fee rate. We can then
|
||||
assume that a transaction paying a similar fee rate now will take a
|
||||
similar number of blocks to confirm. Bitcoin Core includes a fee rate
|
||||
estimator that uses these principles, which can be called using the
|
||||
`estimatesmartfee` RPC with a parameter specifying how many blocks
|
||||
you're willing to wait before the transaction is highly likely to
|
||||
confirm (for example, 144 blocks is about 1 day):
|
||||
|
||||
----
|
||||
$ bitcoin-cli -named estimatesmartfee conf_target=144
|
||||
{
|
||||
"feerate": 0.00006570,
|
||||
"blocks": 144
|
||||
}
|
||||
----
|
||||
|
||||
Many web-based services also provide fee estimation as an API. For a
|
||||
current list, see https://oreil.ly/TB6IN.
|
||||
|
||||
As mentioned, fee rate estimation can never be perfect. One common
|
||||
problem is that the fundamental demand might change, adjusting the
|
||||
equilibrium and either increasing prices (fees) to new heights or
|
||||
decreasing them toward the minimum.
|
||||
If fee rates go down, then a transaction
|
||||
that previously paid a normal fee rate might now be paying a high fee
|
||||
rate and it will be confirmed earlier than expected. There's no way to
|
||||
lower the fee rate on a transaction you've already sent, so you're stuck
|
||||
paying a higher fee rate. But, when fee rates go up, there's a need for
|
||||
methods to be able to increase the fee rates on those transactions,
|
||||
which is called _fee bumping_. There are two commonly used types of fee
|
||||
bumping in Bitcoin, replace by fee (RBF) and child pays for ((("fee rates", startref="fee-rate")))((("transaction fees", "fee rates", startref="fees-rates")))parent
|
||||
(CPFP).
|
||||
|
||||
[[rbf]]
|
||||
=== Replace By Fee (RBF) Fee Bumping
|
||||
|
||||
To((("transaction fees", "fee bumping", "RBF (replace by fee)", id="transaction-fees-bump-rbf")))((("fee bumping", "RBF (replace by fee)", id="fee-bump-rbf")))((("RBF (replace by fee) fee bumping", id="rbf-ch9"))) increase the fee of a transaction using RBF fee bumping, you create
|
||||
a conflicting version of the transaction that pays a higher fee. Two
|
||||
or more transactions are considered((("conflicting transactions")))((("transactions", "conflicts in"))) to be _conflicting transactions_ if
|
||||
only one of them can be included in a valid blockchain, forcing a miner
|
||||
to choose only one of them. Conflicts occur when two or more transactions
|
||||
each try to spend one of the same UTXOs, i.e., they each include an input
|
||||
that has the same outpoint (reference to the output of a previous
|
||||
transaction).
|
||||
|
||||
To prevent someone from consuming large amounts of bandwidth by creating
|
||||
an unlimited number of conflicting transactions and sending them through
|
||||
the network of relaying full nodes, Bitcoin Core and other full nodes
|
||||
that support transaction replacement require each replacement
|
||||
transaction to pay a higher fee rate than the transaction being
|
||||
replaced. Bitcoin Core also currently requires the replacement
|
||||
transaction to pay a higher total fee than the original transaction, but
|
||||
this requirement has undesired side effects and developers have been
|
||||
looking for ways to remove it at the time of writing.
|
||||
|
||||
Bitcoin Core((("Bitcoin Core", "RBF variants", id="bitcoin-core-rbf"))) currently supports two variations of RBF:
|
||||
|
||||
Opt-in RBF::
|
||||
An unconfirmed transaction can signal to miners and full nodes that
|
||||
the creator of the transaction wants to allow it to be replaced by a
|
||||
higher fee rate version. This signal and the rules for using it
|
||||
are specified in BIP125. As of this writing, this has been enabled by
|
||||
default in Bitcoin Core for several years.
|
||||
|
||||
Full RBF::
|
||||
Any unconfirmed transaction can be replaced by a higher fee rate
|
||||
version. As of this writing, this can be optionally enabled in
|
||||
Bitcoin Core (but it is disabled by default).
|
||||
|
||||
.Why Are There Two Variants of RBF?
|
||||
****
|
||||
The reason for the two different versions of RBF is that full RBF has
|
||||
been controversial. Early versions of Bitcoin allowed transaction
|
||||
replacement, but this behavior was disabled for several releases. During
|
||||
that time, a miner or full node using the software now called Bitcoin
|
||||
Core would not replace the first version of an unconfirmed transaction
|
||||
they received with any different version. Some merchants came to expect
|
||||
this behavior: they assumed that any valid unconfirmed transaction that
|
||||
paid an appropriate fee rate would eventually become a confirmed
|
||||
transaction, so they provided their goods or services shortly after
|
||||
receiving such an unconfirmed transaction.
|
||||
|
||||
However, there's no way for the Bitcoin protocol to guarantee that any
|
||||
unconfirmed transaction will eventually be confirmed. As mentioned
|
||||
earlier in this chapter, every miner gets to choose for themselves which
|
||||
transactions they will try to confirm--including which versions of those
|
||||
transactions. Bitcoin Core is open source software, so anyone with a
|
||||
copy of its source code can add (or remove) transaction replacement.
|
||||
Even if Bitcoin Core wasn't open source, Bitcoin is an open protocol
|
||||
that can be reimplemented from scratch by a sufficiently competent
|
||||
programmer, allowing the reimplementor to include or not include
|
||||
transaction replacement.
|
||||
|
||||
Transaction replacement breaks the assumption of some merchants that
|
||||
every reasonable unconfirmed transaction will eventually be confirmed.
|
||||
An alternative version of a transaction can pay the same outputs as the
|
||||
original, but it isn't required to pay any of those outputs. If the
|
||||
first version of an unconfirmed transaction pays a merchant, the second
|
||||
version might not pay them. If the merchant provided goods or services
|
||||
based on the first version, but the second version gets confirmed, then
|
||||
the merchant will not receive payment for its costs.
|
||||
|
||||
Some merchants, and people supporting them, requested that transaction
|
||||
replacement not be reenabled in Bitcoin Core. Other people pointed out
|
||||
that transaction replacement provides benefits, including the ability to
|
||||
fee bump transactions that initially paid too low of a fee rate.
|
||||
|
||||
Eventually, developers working on Bitcoin Core implemented a compromise:
|
||||
instead of allowing every unconfirmed transaction to be replaced (full
|
||||
RBF), they only programmed Bitcoin Core to allow replacement of
|
||||
transactions that signaled they wanted to allow replacement (opt-in RBF).
|
||||
Merchants can check the transactions they receive for the opt-in
|
||||
signal and treat those transactions differently than those without the
|
||||
signal.
|
||||
|
||||
This doesn't change the fundamental concern: anyone can still alter
|
||||
their copy of Bitcoin Core, or create a reimplementation, to allow full
|
||||
RBF--and some developers even did this, but seemingly few people used
|
||||
their software.
|
||||
|
||||
After several years, developers working on Bitcoin Core changed the
|
||||
compromise slightly. In addition to keeping opt-in RBF by default, they
|
||||
added an option that allows users to enable full RBF. If enough mining
|
||||
hash rate and relaying full nodes enable this option, it will be
|
||||
possible for any unconfirmed transaction to eventually be replaced by a
|
||||
version paying a higher fee rate. As of this writing, it's not clear
|
||||
whether or not that has happened ((("Bitcoin Core", "RBF variants", startref="bitcoin-core-rbf")))yet.
|
||||
****
|
||||
|
||||
As a user, if you plan to use RBF fee bumping, you will first need to
|
||||
choose a wallet that supports it, such as one of the wallets listed as
|
||||
having "Sending support" on
|
||||
https://oreil.ly/IhMzx.
|
||||
|
||||
As a developer, if you plan to implement RBF fee bumping, you will first
|
||||
need to decide whether to perform opt-in RBF or full RBF. At the time
|
||||
of writing, opt-in RBF is the only method that's sure to work. Even if
|
||||
full RBF becomes reliable, there will likely be several years where
|
||||
replacements of opt-in transactions get confirmed slightly faster than
|
||||
full-RBF replacements. If you choose opt-in RBF, your wallet will need
|
||||
to implement the signaling specified in BIP125, which is a simple
|
||||
modification to any one of the sequence fields in a transaction (see
|
||||
<<sequence>>). If you choose full RBF, you don't need to include any
|
||||
signaling in your transactions. Everything else related to RBF is the
|
||||
same for both approaches.
|
||||
|
||||
When you need to fee bump a transaction, you will simply create a new
|
||||
transaction that spends at least one of the same UTXOs as the original
|
||||
transaction you want to replace. You will likely want to keep the
|
||||
same outputs in the transaction that pay the receiver (or receivers).
|
||||
You may pay the increased fee by reducing the value of your change
|
||||
output or by adding additional inputs to the transaction. Developers
|
||||
should provide users with a fee-bumping interface that does all of this
|
||||
work for them and simply asks them (or suggests to them) how much the
|
||||
fee rate should be increased.
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
Be very careful when creating more than one replacement of the same
|
||||
transaction. You must ensure than all versions of the transactions
|
||||
conflict with each other. If they aren't all conflicts, it may be
|
||||
possible for multiple separate transactions to confirm, leading you to
|
||||
overpay the receivers. For example:
|
||||
|
||||
- Transaction version 0 includes input _A_.
|
||||
- Transaction version 1 includes inputs _A_ and _B_ (e.g., you had to add
|
||||
input _B_ to pay the extra fees)
|
||||
- Transaction version 2 includes inputs _B_ and _C_ (e.g., you had to add input
|
||||
_C_ to pay the extra fees but _C_ was large enough that you no longer
|
||||
need input _A_).
|
||||
|
||||
In this scenario, any miner who saved version 0 of the transaction
|
||||
will be able to confirm both it and version 2 of the transaction. If
|
||||
both versions pay the same receivers, they'll be paid twice (and the
|
||||
miner will receive transaction fees from two separate transactions).
|
||||
|
||||
A simple method to avoid this problem is to ensure the replacement
|
||||
transaction always includes all of the same inputs as the previous
|
||||
version of the transaction.
|
||||
====
|
||||
|
||||
The advantage of RBF fee bumping over other types of fee bumping is that
|
||||
it can be very efficient at using block space. Often, a replacement
|
||||
transaction is the same size as the transaction it replaces. Even when
|
||||
it's larger, it's often the same size as the transaction the user would
|
||||
have created if they had paid the increased fee rate in the first place.
|
||||
|
||||
The fundamental disadvantage of RBF fee bumping is that it can normally
|
||||
only be performed by the creator of the transaction--the person or
|
||||
people who were required to provide signatures or other authentication
|
||||
data for the transaction. An exception to this is transactions that
|
||||
were designed to allow additional inputs to be added by using sighash
|
||||
flags (see <<sighash_types>>), but that presents its own challenges. In
|
||||
general, if you're the receiver of an unconfirmed transaction and you
|
||||
want to make it confirm faster (or at all), you can't use an RBF fee
|
||||
bump; you need some other method.
|
||||
|
||||
There are additional problems ((("transaction fees", "fee bumping", "RBF (replace by fee)", startref="transaction-fees-bump-rbf")))((("fee bumping", "RBF (replace by fee)", startref="fee-bump-rbf")))((("RBF (replace by fee) fee bumping", startref="rbf-ch9")))with RBF that we'll explore in <<transaction_pinning>>.
|
||||
|
||||
[[cpfp]]
|
||||
=== Child Pays for Parent (CPFP) Fee Bumping
|
||||
|
||||
Anyone ((("transaction fees", "fee bumping", "CPFP (child pays for parent)", id="transaction-fees-bump-cpfp")))((("fee bumping", "CPFP (child pays for parent)", id="fee-bump-cpfp")))((("CPFP (child pays for parent) fee bumping", id="cpfp-ch9")))who receives the output of an unconfirmed transaction can
|
||||
incentivize miners to confirm that transaction by spending that output.
|
||||
The transaction you want to get confirmed is called the _parent
|
||||
transaction_. A transaction that spends an output of the parent
|
||||
transaction is called a _child transaction_.
|
||||
|
||||
As we learned in <<outpoints>>, every input in a confirmed transaction
|
||||
must reference the unspent output of a transaction that appears earlier
|
||||
in the blockchain (whether earlier in the same block or in a previous
|
||||
block). That means a miner who wants to confirm a child transaction
|
||||
must also ensure that its parent transaction is confirmed. If the
|
||||
parent transaction hasn't been confirmed yet but the child transaction
|
||||
pays a high enough fee, the miner can consider whether it would be
|
||||
profitable to confirm both of them in the same block.
|
||||
|
||||
To evaluate the profitability of mining both a parent and child
|
||||
transaction, the miner looks at them as a _package of transactions_ with
|
||||
an aggregate size and aggregate fees, from which the fees can be divided
|
||||
by the size to calculate((("package fee rate"))) a _package fee rate_. The miner can then sort
|
||||
all of the individual transactions and transaction packages they know
|
||||
about by fee rate and include the highest-revenue ones in the block
|
||||
they're attempting to mine, up to the maximum size (weight) allowed to
|
||||
be included in a block. To find even more packages that might be
|
||||
profitable to mine, the miner can evaluate packages across multiple
|
||||
generations (e.g., an unconfirmed parent transaction being combined with
|
||||
both its child and grandchild). This is ((("ancestor fee rate mining")))((("CPFP (child pays for parent) fee bumping", "ancestor fee rate mining")))called _ancestor fee rate
|
||||
mining_.
|
||||
|
||||
Bitcoin Core has implemented ancestor fee rate mining for many years,
|
||||
and it's believed that almost all miners use it at the time of writing.
|
||||
That means it's practical for wallets to use this feature to fee bump an
|
||||
incoming transaction by using a child transaction to pay for its parent
|
||||
(CPFP).
|
||||
|
||||
CPFP has several advantages over RBF. Anyone who receives an output
|
||||
from a transaction can use CPFP--that includes both the receivers of
|
||||
payments and the spender (if the spender included a change output). It
|
||||
also doesn't require replacing the original transaction, which makes it
|
||||
less disruptive to some merchants than RBF.
|
||||
|
||||
The primary disadvantage of CPFP compared to RBF is that CPFP typically
|
||||
uses more block space. In RBF, a fee bump transaction is often the same
|
||||
size as the transaction it replaces. In CPFP, a fee bump adds a whole
|
||||
separate transaction. Using extra block space requires paying extra
|
||||
fees beyond the cost of the fee bump.
|
||||
|
||||
There are several challenges with CPFP, some of which we'll explore in
|
||||
<<transaction_pinning>>. One other problem that we
|
||||
specifically need to mention is the minimum relay fee rate problem,
|
||||
which is addressed by ((("transaction fees", "fee bumping", "CPFP (child pays for parent)", startref="transaction-fees-bump-cpfp")))((("fee bumping", "CPFP (child pays for parent)", startref="fee-bump-cpfp")))((("CPFP (child pays for parent) fee bumping", startref="cpfp-ch9")))package relay.
|
||||
|
||||
=== Package Relay
|
||||
|
||||
Early versions((("transaction fees", "package relay", id="transaction-fee-package-relay")))((("package relay", id="package-relay"))) of Bitcoin Core didn't place any limits on the number of
|
||||
unconfirmed transactions they stored for later relay and mining in their
|
||||
mempools (see <<mempool>>). Of course, computers have physical limits, whether
|
||||
it's the memory (RAM) or disk space--it's not possible for a full node
|
||||
to store an unlimited number of unconfirmed transactions. Later
|
||||
versions of Bitcoin Core limited the size of the mempool to hold about
|
||||
one day's worth of transactions, storing only the transactions or packages
|
||||
with the highest fee rate.
|
||||
|
||||
That works extremely well for most things, but it creates a dependency
|
||||
problem. In order to calculate the fee rate for a transaction package,
|
||||
we need both the parent and descendant transactions--but if the parent
|
||||
transaction doesn't pay a high enough fee rate, it won't be kept in a
|
||||
node's mempool. If a node receives a child transaction without having
|
||||
access to its parent, it can't do anything with that transaction.
|
||||
|
||||
The solution to this problem is the ability to relay transactions as a
|
||||
package, called _package relay_, allowing the receiving node to evaluate
|
||||
the fee rate of the entire package before operating on any individual
|
||||
transaction. As of this writing, developers working on Bitcoin Core
|
||||
have made significant progress on implementing package relay, and a
|
||||
limited early version of it may be available by the time this book is
|
||||
published.
|
||||
|
||||
Package relay is especially important for protocols based on
|
||||
time-sensitive presigned transactions, such as Lightning Network (LN). In
|
||||
non-cooperative cases, some presigned transactions can't be fee bumped
|
||||
using RBF, forcing them to depend on CPFP. In those protocols, some
|
||||
transactions may also be created long before they need to be broadcast,
|
||||
making it effectively impossible to estimate an appropriate fee rate.
|
||||
If a presigned transaction pays a fee rate below the amount necessary to
|
||||
get into a node's mempool, there's no way to fee bump it with a child.
|
||||
If that prevents the transaction from confirming in time, an honest user
|
||||
might lose money. Package relay is the solution for this critical
|
||||
problem.
|
||||
|
||||
[[transaction_pinning]]
|
||||
=== Transaction Pinning
|
||||
|
||||
++++
|
||||
<p class="fix_tracking">
|
||||
Although both RBF and CPFP fee bumping work in the basic cases we
|
||||
described, there are rules related to both
|
||||
methods that are designed to prevent denial-of-service attacks on miners
|
||||
and relaying full nodes. An unfortunate side effect of those rules
|
||||
is that they can sometimes prevent someone from being able to use fee
|
||||
bumping. Making it impossible or difficult to fee bump a transaction is
|
||||
called <em>transaction pinning</em>.</p>
|
||||
++++
|
||||
|
||||
One((("transaction fees", "fee bumping", "transaction pinning", id="transaction-fee-bump-pin")))((("fee bumping", "transaction pinning", id="fee-bump-pin")))((("transaction pinning", id="transaction-pin")))((("RBF (replace by fee) fee bumping", "transaction pinning", id="rbf-pin")))((("CPFP (child pays for parent) fee bumping", "transaction pinning", id="cpfp-pin"))) of the major denial of service concerns revolves around the effect of
|
||||
transaction relationships. Whenever the output of a transaction is
|
||||
spent, that transaction's identifier (txid) is referenced by the child
|
||||
transaction. However, when a transaction is replaced, the replacement
|
||||
has a different txid. If that replacement transaction gets confirmed,
|
||||
none of its descendants can be included in the same blockchain. It's
|
||||
possible to re-create and re-sign the descendant transactions, but that's
|
||||
not guaranteed to happen. This has related but divergent implications
|
||||
for RBF and CPFP:
|
||||
|
||||
- In the context of RBF, when Bitcoin Core accepts a replacement
|
||||
transaction, it keeps things simple by forgetting about the original
|
||||
transaction and all descendant transactions that depended on that
|
||||
original. To ensure that it's more profitable for miners to accept
|
||||
replacements, Bitcoin Core only accepts a replacement transaction if it
|
||||
pays more fees than all the transactions that will be forgotten.
|
||||
+
|
||||
The downside of this approach is that Alice can create a small
|
||||
transaction that pays Bob. Bob can then use his output to create a
|
||||
large child transaction. If Alice then wants to replace her original
|
||||
transaction, she needs to pay a fee that's larger than what both she and
|
||||
Bob originally paid. For example, if Alice's original transaction was
|
||||
about 100 vbytes and Bob's transaction was about 100,000 vbytes, and
|
||||
they both used the same fee rate, Alice now needs to pay more than 1,000
|
||||
times as much as she originally paid in order to RBF fee bump her
|
||||
transaction.
|
||||
|
||||
- In the context of CPFP, any time the node considers including a
|
||||
package in a block, it must remove the transactions in that package
|
||||
from any other package it wants to consider for the same block. For
|
||||
example, if a child transaction pays for 25 ancestors, and each of
|
||||
those ancestors has 25 other children, then including the package in
|
||||
the block requires updating approximately 625 packages (25^2^).
|
||||
Similarly, if a transaction with 25 descendants is removed from a
|
||||
node's mempool (such as for being included in a block), and each of
|
||||
those descendants has 25 other ancestors, another 625 packages need to
|
||||
be updated. Each time we double our parameter (e.g., from 25 to 50),
|
||||
we quadruple the amount of work our node needs to perform.
|
||||
+
|
||||
Additionally, a transaction and all of its descendants is not
|
||||
useful to keep in a mempool long term if an alternative version of
|
||||
that transaction is mined--none of those transactions can now be
|
||||
confirmed unless there's a rare blockchain reorganization. Bitcoin
|
||||
Core will remove from its mempool every transaction that can no longer
|
||||
be confirmed on the current blockchain. At it's worst, that can
|
||||
waste an enormous amount of your node's bandwidth and possibly be used
|
||||
to prevent transactions from propagating correctly.
|
||||
+
|
||||
To prevent these problems, and other related
|
||||
problems, Bitcoin Core limits a parent transaction to having a maximum
|
||||
of 25 ancestors or descendants in its mempool and limits the
|
||||
total size of all those transactions to 100,000 vbytes. The downside
|
||||
of this approach is that users are prevented from creating CPFP fee
|
||||
bumps if a transaction already has too many descendants (or if it and
|
||||
its descendants are too large).
|
||||
|
||||
Transaction pinning can happen by accident, but it also represents a
|
||||
serious vulnerability for multiparty time-sensitive protocols such as
|
||||
LN. If your counterparty can prevent one of your
|
||||
transactions from confirming by a deadline, they may be able to steal
|
||||
money from you.
|
||||
|
||||
Protocol developers have been working on mitigating problems with
|
||||
transaction pinning for several years. One partial solution is
|
||||
described in <<cpfp_carve_out>>. Several other solutions have been
|
||||
proposed, and at least one solution is being actively ((("transaction fees", "fee bumping", "transaction pinning", startref="transaction-fee-bump-pin")))((("fee bumping", "transaction pinning", startref="fee-bump-pin")))((("transaction pinning", startref="transaction-pin")))((("RBF (replace by fee) fee bumping", "transaction pinning", startref="rbf-pin")))((("CPFP (child pays for parent) fee bumping", "transaction pinning", startref="cpfp-pin")))((("transaction fees", "fee bumping", "CPFP carve outs", id="transaction-fee-bump-carveout")))((("fee bumping", "CPFP carve outs", id="fee-bump-carveout")))((("carve outs (CPFP)", id="carveout")))((("CPFP (child pays for parent) fee bumping", "carve outs", id="cpfp-carveout")))developed as of
|
||||
this writing—https://oreil.ly/300dv[ephemeral anchors].
|
||||
|
||||
[[cpfp_carve_out]]
|
||||
=== CPFP Carve Out and Anchor Outputs
|
||||
|
||||
++++
|
||||
<p class="fix_tracking2">
|
||||
In 2018, developers working on LN had a problem.
|
||||
Their protocol uses transactions that require signatures from two
|
||||
different parties. Neither party wants to trust the other, so they sign
|
||||
transactions at a point in the protocol when trust isn't needed,
|
||||
allowing either of them to broadcast one of those transactions at a
|
||||
later time when the other party may not want to (or be able to) fulfill
|
||||
its obligations. The problem with this approach is that the
|
||||
transactions might need to be broadcast at an unknown time, far in the future, beyond any
|
||||
reasonable ability to estimate an appropriate fee rate for the
|
||||
transactions.</p>
|
||||
++++
|
||||
|
||||
In theory, the developers could have designed their transactions to
|
||||
allow fee bumping with either RBF (using special sighash flags) or CPFP,
|
||||
but both of those protocols are vulnerable to transaction pinning.
|
||||
Given that the involved transactions are time sensitive, allowing a
|
||||
counterparty to use transaction pinning to delay confirmation of a
|
||||
transaction can easily lead to a repeatable exploit that malicious
|
||||
parties could use to steal money from honest parties.
|
||||
|
||||
LN developer Matt Corallo proposed a solution: give the rules for CPFP
|
||||
fee bumping a special exception, called _CPFP carve out_. The normal
|
||||
rules for CPFP forbid the inclusion of an additional descendant if it
|
||||
would cause a parent transaction to have 26 or more descendants or if it
|
||||
would cause a parent and all of its descendants to exceed 100,000 vbytes
|
||||
in size. Under the rules of CPFP carve out, a single additional
|
||||
transaction up to 1,000 vbytes in size can be added to a package even if
|
||||
it would exceed the other limits as long as it is a direct child of an
|
||||
unconfirmed transaction with no unconfirmed ancestors.
|
||||
|
||||
++++
|
||||
<p class="fix_tracking">
|
||||
For example, Bob and Mallory both co-sign a transaction with two
|
||||
outputs, one to each of them. Mallory broadcasts that transaction and
|
||||
uses her output to attach either 25 child transactions or any smaller
|
||||
number of child transactions equaling 100,000 vbytes in size. Without
|
||||
carve-out, Bob would be unable to attach another child transaction to
|
||||
his output for CPFP fee bumping. With carve-out, he can spend one of
|
||||
the two outputs in the transaction, the one that belongs to him, as long
|
||||
as his child transaction is less than 1,000 vbytes in size (which should
|
||||
be more than enough space).</p>
|
||||
++++
|
||||
|
||||
It's not allowed to use CPFP carve-out more than once, so it only works
|
||||
for two-party protocols. There have been proposals to extend it to
|
||||
protocols involving more participants, but there hasn't been much demand
|
||||
for that and developers are focused on building more generic solutions
|
||||
to transaction pinning attacks.
|
||||
|
||||
As of this writing, most popular LN implementations use a transaction
|
||||
template called _anchor outputs_, which is designed to be used ((("anchor outputs (CPFP)")))((("transaction fees", "fee bumping", "CPFP carve outs", startref="transaction-fee-bump-carveout")))((("fee bumping", "CPFP carve outs", startref="fee-bump-carveout")))((("carve outs (CPFP)", startref="carveout")))((("CPFP (child pays for parent) fee bumping", "carve outs", startref="cpfp-carveout")))with CPFP
|
||||
carve out.
|
||||
|
||||
=== Adding Fees to Transactions
|
||||
|
||||
The data((("transaction fees", "change outputs and")))((("change output", "transaction fees and")))((("outputs", "transaction fees and")))((("inputs", "transaction fees and"))) structure of transactions does not have a field for fees.
|
||||
Instead, fees are implied as the difference between the sum of inputs
|
||||
and the sum of outputs. Any excess amount that remains after all outputs
|
||||
have been deducted from all inputs is the fee that is collected by the
|
||||
miners:
|
||||
|
||||
[latexmath]
|
||||
++++
|
||||
\begin{equation}
|
||||
{Fees = Sum(Inputs) - Sum(Outputs)}
|
||||
\end{equation}
|
||||
++++
|
||||
|
||||
|
||||
This is a somewhat confusing element of transactions and an important
|
||||
point to understand because if you are constructing your own
|
||||
transactions, you must ensure you do not inadvertently include a very
|
||||
large fee by underspending the inputs. That means that you must account
|
||||
for all inputs, if necessary, by creating change, or you will end up
|
||||
giving the miners a very big tip!
|
||||
|
||||
For example, if you spend a 20-bitcoin UTXO to make a 1-bitcoin
|
||||
payment, you must include a 19-bitcoin change output back to your
|
||||
wallet. Otherwise, the 19-bitcoin "leftover" will be counted as a
|
||||
transaction fee and will be collected by the miner who mines your
|
||||
transaction in a block. Although you will receive priority processing
|
||||
and make a miner very happy, this is probably not what you intended.
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
If you forget to add a
|
||||
change output in a manually constructed transaction, you will be paying
|
||||
the change as a transaction fee. "Keep the change!" might not be what
|
||||
you intended.
|
||||
====
|
||||
|
||||
[[fee_sniping]]
|
||||
=== Timelock Defense Against Fee Sniping
|
||||
|
||||
Fee sniping ((("transaction fees", "fee sniping", id="transaction-fee-sniping")))((("fee sniping", id="fee-snipe")))((("timelocks", "fee sniping and", id="timelock-fee-snipe")))((("lock time", "fee sniping and", id="lock-time-fee-snipe")))is a theoretical
|
||||
attack scenario where miners attempting to rewrite past blocks "snipe"
|
||||
higher-fee transactions from future blocks to maximize their
|
||||
[.keep-together]#profitability.#
|
||||
|
||||
For example, let's say the highest block in existence is block
|
||||
#100,000. If instead of attempting to mine block #100,001 to extend the
|
||||
chain, some miners attempt to remine #100,000. These miners can choose
|
||||
to include any valid transaction (that hasn't been mined yet) in their
|
||||
candidate block #100,000. They don't have to remine the block with the
|
||||
same transactions. In fact, they have the incentive to select the most
|
||||
profitable (highest fee per kB) transactions to include in their block.
|
||||
They can include any transactions that were in the "old" block
|
||||
#100,000, as well as any transactions from the current mempool.
|
||||
Essentially they have the option to pull transactions from the "present"
|
||||
into the rewritten "past" when they re-create block #100,000.
|
||||
|
||||
Today, this attack is not very lucrative because the block subsidy is much
|
||||
higher than total fees per block. But at some point in the future,
|
||||
transaction fees will be the majority of the reward (or even the
|
||||
entirety of the reward). At that time, this scenario becomes inevitable.
|
||||
|
||||
Several wallets discourage fee sniping by creating transactions with a
|
||||
lock time that limits those transactions to being included in the next
|
||||
block or any later block. In our
|
||||
scenario, our wallet would set lock time to 100,001 on any
|
||||
transaction it created. Under normal circumstances, this lock time has
|
||||
no effect—the transactions could only be included in block
|
||||
#100,001 anyway; it's the next block.
|
||||
|
||||
But under a reorganization attack, the miners would not be able to pull
|
||||
high-fee transactions from the mempool because all those transactions
|
||||
would be timelocked to block #100,001. They can only remine #100,000
|
||||
with whatever transactions were valid at that time, essentially gaining
|
||||
no new fees.
|
||||
|
||||
This does not entirely prevent fee sniping, but it does make it less
|
||||
profitable in some cases and can help preserve the stability of the
|
||||
Bitcoin network as the block subsidy declines. We recommend all wallets
|
||||
implement anti-fee sniping when it doesn't interfere with the wallet's
|
||||
other uses of the lock time field.
|
||||
|
||||
As Bitcoin continues to mature, and as the subsidy continues to decline,
|
||||
fees become more and more important to Bitcoin users, both in their
|
||||
day-to-day use for getting transactions confirmed quickly and in
|
||||
providing an incentive for miners to continue securing Bitcoin
|
||||
transactions with new proof of work.
|
@ -1,78 +0,0 @@
|
||||
[[ch11]]
|
||||
== Bitcoin Security
|
||||
|
||||
Securing bitcoin is challenging because bitcoin is not an abstract reference to value, like a balance in a bank account. Bitcoin is very much like digital cash or gold. You've probably heard the expression, "Possession is nine-tenths of the law." Well, in bitcoin, possession is ten-tenths of the law. Possession of the keys to unlock the bitcoin is equivalent to possession of cash or a chunk of precious metal. You can lose it, misplace it, have it stolen, or accidentally give the wrong amount to someone. In every one of these cases, users have no recourse, just as if they dropped cash on a public sidewalk.
|
||||
|
||||
However, bitcoin has capabilities that cash, gold, and bank accounts do not. A bitcoin wallet, containing your keys, can be backed up like any file. It can be stored in multiple copies, even printed on paper for hard-copy backup. You can't "back up" cash, gold, or bank accounts. Bitcoin is different enough from anything that has come before that we need to think about bitcoin security in a novel way too.
|
||||
|
||||
=== Security Principles
|
||||
|
||||
((("security", "security principles", id="Sprinc11")))((("decentralized systems", "security of")))The core principle in bitcoin is decentralization and it has important implications for security. A centralized model, such as a traditional bank or payment network, depends on access control and vetting to keep bad actors out of the system. By comparison, a decentralized system like bitcoin pushes the responsibility and control to the users. Because security of the network is based on Proof-of-Work, not access control, the network can be open and no encryption is required for bitcoin traffic.
|
||||
|
||||
On a traditional payment network, such as a credit card system, the payment is open-ended because it contains the user's private identifier (the credit card number). After the initial charge, anyone with access to the identifier can "pull" funds and charge the owner again and again. Thus, the payment network has to be secured end-to-end with encryption and must ensure that no eavesdroppers or intermediaries can compromise the payment traffic, in transit or when it is stored (at rest). If a bad actor gains access to the system, he can compromise current transactions _and_ payment tokens that can be used to create new transactions. Worse, when customer data is compromised, the customers are exposed to identity theft and must take action to prevent fraudulent use of the compromised accounts.
|
||||
|
||||
Bitcoin is dramatically different. A bitcoin transaction authorizes only a specific value to a specific recipient and cannot be forged or modified. It does not reveal any private information, such as the identities of the parties, and cannot be used to authorize additional payments. Therefore, a bitcoin payment network does not need to be encrypted or protected from eavesdropping. In fact, you can broadcast bitcoin transactions over an open public channel, such as unsecured WiFi or Bluetooth, with no loss of security.
|
||||
|
||||
Bitcoin's decentralized security model puts a lot of power in the hands of the users. With that power comes responsibility for maintaining the secrecy of the keys. For most users that is not easy to do, especially on general-purpose computing devices such as internet-connected smartphones or laptops. Although bitcoin's decentralized model prevents the type of mass compromise seen with credit cards, many users are not able to adequately secure their keys and get hacked, one by one.
|
||||
|
||||
|
||||
==== Developing Bitcoin Systems Securely
|
||||
|
||||
((("decentralized systems", "bitcoin as")))The most important principle for bitcoin developers is decentralization. Most developers will be familiar with centralized security models and might be tempted to apply these models to their bitcoin applications, with disastrous results.
|
||||
|
||||
Bitcoin's security relies on decentralized control over keys and on independent transaction validation by miners. If you want to leverage bitcoin's security, you need to ensure that you remain within the bitcoin security model. In simple terms: don't take control of keys away from users and don't take transactions off the blockchain.
|
||||
|
||||
For example, many early bitcoin exchanges concentrated all user funds in a single "hot" wallet with keys stored on a single server. Such a design removes control from users and centralizes control over keys in a single system. Many such systems have been hacked, with disastrous consequences for their customers.
|
||||
|
||||
((("transactions", "off blockchain")))((("off-blockchain transactions")))Another common mistake is to take transactions "off blockchain" in a misguided effort to reduce transaction fees or accelerate transaction processing. An "off blockchain" system will record transactions on an internal, centralized ledger and only occasionally synchronize them to the Bitcoin blockchain. This practice, again, substitutes decentralized bitcoin security with a proprietary and centralized approach. When transactions are off blockchain, improperly secured centralized ledgers can be falsified, diverting funds and depleting reserves, unnoticed.
|
||||
|
||||
Unless you are prepared to invest heavily in operational security, multiple layers of access control, and audits (as the traditional banks do) you should think very carefully before taking funds outside of bitcoin's decentralized security context. Even if you have the funds and discipline to implement a robust security model, such a design merely replicates the fragile model of traditional financial networks, plagued by identity theft, corruption, and embezzlement. To take advantage of bitcoin's unique decentralized security model, you have to avoid the temptation of centralized architectures that might feel familiar but ultimately subvert bitcoin's security.
|
||||
|
||||
==== The Root of Trust
|
||||
|
||||
((("root of trust concept")))Traditional security architecture is based upon a concept called the _root of trust_, which is a trusted core used as the foundation for the security of the overall system or application. Security architecture is developed around the root of trust as a series of concentric circles, like layers in an onion, extending trust outward from the center. Each layer builds upon the more-trusted inner layer using access controls, digital signatures, encryption, and other security primitives. As software systems become more complex, they are more likely to contain bugs, which make them vulnerable to security compromise. As a result, the more complex a software system becomes, the harder it is to secure. The root of trust concept ensures that most of the trust is placed within the least complex part of the system, and therefore least vulnerable, parts of the system, while more complex software is layered around it. This security architecture is repeated at different scales, first establishing a root of trust within the hardware of a single system, then extending that root of trust through the operating system to higher-level system services, and finally across many servers layered in concentric circles of diminishing trust.
|
||||
|
||||
((("mining and consensus", "security and consensus")))Bitcoin security architecture is different. In bitcoin, the consensus system creates a trusted public ledger that is completely decentralized. A correctly validated blockchain uses the genesis block as the root of trust, building a chain of trust up to the current block. Bitcoin systems can and should use the blockchain as their root of trust. When designing a complex bitcoin application that consists of services on many different systems, you should carefully examine the security architecture in order to ascertain where trust is being placed. Ultimately, the only thing that should be explicitly trusted is a fully validated blockchain. If your application explicitly or implicitly vests trust in anything but the blockchain, that should be a source of concern because it introduces vulnerability. A good method to evaluate the security architecture of your application is to consider each individual component and evaluate a hypothetical scenario where that component is completely compromised and under the control of a malicious actor. Take each component of your application, in turn, and assess the impacts on the overall security if that component is compromised. If your application is no longer secure when components are compromised, that shows you have misplaced trust in those components. A bitcoin application without vulnerabilities should be vulnerable only to a compromise of the bitcoin consensus mechanism, meaning that its root of trust is based on the strongest part of the bitcoin security architecture.
|
||||
|
||||
The numerous examples of hacked bitcoin exchanges serve to underscore this point because their security architecture and design fails even under the most casual scrutiny. These centralized implementations had invested trust explicitly in numerous components outside the Bitcoin blockchain, such as hot wallets, centralized ledger databases, vulnerable encryption keys, and similar schemes.((("", startref="Sprinc11")))
|
||||
|
||||
|
||||
=== User Security Best Practices
|
||||
|
||||
((("security", "user security best practices", id="Suser11")))((("use cases", "user security best practices", id="UCsecurity11")))Humans have used physical security controls for thousands of years. By comparison, our experience with digital security is less than 50 years old. Modern general-purpose operating systems are not very secure and not particularly suited to storing digital money. Our computers are constantly exposed to external threats via always-on internet connections. They run thousands of software components from hundreds of authors, often with unconstrained access to the user's files. A single piece of rogue software, among the many thousands installed on your computer, can compromise your keyboard and files, stealing any bitcoin stored in wallet applications. The level of computer maintenance required to keep a computer virus-free and trojan-free is beyond the skill level of all but a tiny minority of computer users.
|
||||
|
||||
Despite decades of research and advancements in information security, digital assets are still woefully vulnerable to a determined adversary. Even the most highly protected and restricted systems, in financial services companies, intelligence agencies, and defense contractors, are frequently breached. Bitcoin creates digital assets that have intrinsic value and can be stolen and diverted to new owners instantly and irrevocably. This creates a massive incentive for hackers. Until now, hackers had to convert identity information or account tokens—such as credit cards and bank accounts—into value after compromising them. Despite the difficulty of fencing and laundering financial information, we have seen ever-escalating thefts. Bitcoin escalates this problem because it doesn't need to be fenced or laundered; it is intrinsic value within a digital asset.
|
||||
|
||||
Fortunately, bitcoin also creates the incentives to improve computer security. Whereas previously the risk of computer compromise was vague and indirect, bitcoin makes these risks clear and obvious. Holding bitcoin on a computer serves to focus the user's mind on the need for improved computer security. As a direct result of the proliferation and increased adoption of bitcoin and other digital currencies, we have seen an escalation in both hacking techniques and security solutions. In simple terms, hackers now have a very juicy target and users have a clear incentive to defend themselves.
|
||||
|
||||
Over the past three years, as a direct result of bitcoin adoption, we have seen tremendous innovation in the realm of information security in the form of hardware encryption, key storage and hardware wallets, multisignature technology, and digital escrow. In the following sections we will examine various best practices for practical user security.
|
||||
|
||||
==== Physical Bitcoin Storage
|
||||
|
||||
((("storage", "physical bitcoin storage")))((("paper wallets")))((("wallets", "types of", "paper wallets")))((("paper wallets", see="also wallets")))Because most users are far more comfortable with physical security than information security, a very effective method for protecting bitcoin is to convert them into physical form. Bitcoin keys are nothing more than long numbers. This means that they can be stored in a physical form, such as printed on paper or etched on a metal coin. Securing the keys then becomes as simple as physically securing the printed copy of the bitcoin keys. A set of bitcoin keys that is printed on paper is called a "paper wallet," and there are many free tools that can be used to create them. I personally keep the vast majority of my bitcoin (99% or more) stored on paper wallets, encrypted with BIP-38, with multiple copies locked in safes. ((("cold storage")))((("storage", "cold storage")))Keeping bitcoin offline is called _cold storage_ and it is one of the most effective security techniques. A cold storage system is one where the keys are generated on an offline system (one never connected to the internet) and stored offline either on paper or on digital media, such as a USB memory stick.
|
||||
|
||||
==== Hardware Wallets
|
||||
|
||||
((("wallets", "types of", "hardware wallets")))((("hardware wallets")))In the long term, bitcoin security increasingly will take the form of hardware tamper-proof wallets. Unlike a smartphone or desktop computer, a bitcoin hardware wallet has just one purpose: to hold bitcoin securely. Without general-purpose software to compromise and with limited interfaces, hardware wallets can deliver an almost foolproof level of security to nonexpert users. I expect to see hardware wallets become the predominant method of bitcoin storage. For an example of such a hardware wallet, see the https://trezor.io/[Trezor].
|
||||
|
||||
==== Balancing Risk
|
||||
|
||||
((("risk, balancing and diversifying", seealso="security")))Although most users are rightly concerned about bitcoin theft, there is an even bigger risk. Data files get lost all the time. If they contain bitcoin, the loss is much more painful. In the effort to secure their bitcoin wallets, users must be very careful not to go too far and end up losing the bitcoin. In July 2011, a well-known bitcoin awareness and education project lost almost 7,000 bitcoin. In their effort to prevent theft, the owners had implemented a complex series of encrypted backups. In the end they accidentally lost the encryption keys, making the backups worthless and losing a fortune. Like hiding money by burying it in the desert, if you secure your bitcoin too well you might not be able to find it again.
|
||||
|
||||
==== Diversifying Risk
|
||||
|
||||
Would you carry your entire net worth in cash in your wallet? Most people would consider that reckless, yet bitcoin users often keep all their bitcoin in a single wallet. Instead, users should spread the risk among multiple and diverse bitcoin wallets. Prudent users will keep only a small fraction, perhaps less than 5%, of their bitcoin in an online or mobile wallet as "pocket change." The rest should be split between a few different storage mechanisms, such as a desktop wallet and offline (cold storage).
|
||||
|
||||
==== Multisig and Governance
|
||||
|
||||
((("multisig addresses")))((("addresses", "multisig addresses")))Whenever a company or individual stores large amounts of bitcoin, they should consider using a multisignature Bitcoin address. Multisignature addresses secure funds by requiring a minimum number of signatures to make a payment. The signing keys should be stored in a number of different locations and under the control of different people. In a corporate environment, for example, the keys should be generated independently and held by several company executives, to ensure no single person can compromise the funds. Multisignature addresses can also offer redundancy, where a single person holds several keys that are stored in different locations.
|
||||
|
||||
==== Survivability
|
||||
|
||||
((("survivability")))((("digital asset executors")))((("passwords", "survivability and")))((("security", "passwords")))One important security consideration that is often overlooked is availability, especially in the context of incapacity or death of the key holder. Bitcoin users are told to use complex passwords and keep their keys secure and private, not sharing them with anyone. Unfortunately, that practice makes it almost impossible for the user's family to recover any funds if the user is not available to unlock them. In most cases, in fact, the families of bitcoin users might be completely unaware of the existence of the bitcoin funds.
|
||||
|
||||
If you have a lot of bitcoin, you should consider sharing access details with a trusted relative or lawyer. A more complex survivability scheme can be set up with multi-signature access and estate planning through a lawyer specialized as a "digital asset executor."((("", startref="Suser11")))((("", startref="UCsecurity11")))
|
||||
|
||||
=== Conclusion
|
||||
|
||||
Bitcoin is a completely new, unprecedented, and complex technology. Over time we will develop better security tools and practices that are easier to use by nonexperts. For now, bitcoin users can use many of the tips discussed here to enjoy a secure and trouble-free bitcoin experience.
|
@ -1,409 +0,0 @@
|
||||
[[ch12]]
|
||||
== Blockchain Applications
|
||||
|
||||
Let's now build on our understanding of bitcoin by looking at it as an _application platform_. Nowadays, many people use the term "blockchain" to refer to any application platform that shares the design principles of bitcoin. The term is often misused and applied to many things that fail to deliver the primary features that bitcoin's blockchain delivers.
|
||||
|
||||
In this chapter we will look at the features offered by the Bitcoin blockchain, as an application platform. We will consider the application building _primitives_, which form the building blocks of any blockchain application. We will look at several important applications that use these primitives, such as payment (state) channels and routed payment channels (Lightning Network).
|
||||
|
||||
=== Introduction
|
||||
|
||||
((("blockchain applications", "benefits of Bitcoin system")))The Bitcoin system was designed as a decentralized currency and payment system. However, most of its functionality is derived from much lower-level constructs that can be used for much broader applications. Bitcoin wasn't built with components such as accounts, users, balances, and payments. Instead, it uses a transactional scripting language with low-level cryptographic functions, as we saw in <<transactions>>. Just as the higher-level concepts of accounts, balances, and payments can be derived from these basic primitives, so can many other complex applications. Thus, the Bitcoin blockchain can become an application platform offering trust services to applications, such as smart contracts, far surpassing the original purpose of digital currency and payments.
|
||||
|
||||
=== Building Blocks (Primitives)
|
||||
|
||||
((("blockchain applications", "building blocks for (primitives)")))((("primitives")))When operating correctly and over the long term, the Bitcoin system offers certain guarantees, which can be used as building blocks to create applications. These include:
|
||||
|
||||
No Double-Spend:: The most fundamental guarantee of bitcoin's decentralized consensus algorithm ensures that no UTXO can be spent twice.
|
||||
|
||||
Immutability:: Once a transaction is recorded in the blockchain and sufficient work has been added with subsequent blocks, the transaction's data becomes immutable. Immutability is underwritten by energy, as rewriting the blockchain requires the expenditure of energy to produce Proof-of-Work. The energy required and therefore the degree of immutability increases with the amount of work committed on top of the block containing a transaction.
|
||||
|
||||
Neutrality:: The decentralized Bitcoin network propagates valid transactions regardless of the origin or content of those transactions. This means that anyone can create a valid transaction with sufficient fees and trust they will be able to transmit that transaction and have it included in the blockchain at any time.
|
||||
|
||||
Secure Timestamping:: The consensus rules reject any block whose timestamp is too far in the past or future. This ensures that timestamps on blocks can be trusted. The timestamp on a block implies an unspent-before guarantee for the inputs of all included transactions.
|
||||
|
||||
Authorization:: Digital signatures, validated in a decentralized network, offer authorization guarantees. Scripts that contain a requirement for a digital signature cannot be executed without authorization by the holder of the private key implied in the script.
|
||||
|
||||
Auditability:: All transactions are public and can be audited. All transactions and blocks can be linked back in an unbroken chain to the genesis block.
|
||||
|
||||
Accounting:: In any transaction (except the coinbase transaction) the value of inputs is equal to the value of outputs plus fees. It is not possible to create or destroy bitcoin value in a transaction. The outputs cannot exceed the inputs.
|
||||
|
||||
Nonexpiration:: A valid transaction does not expire. If it is valid today, it will be valid in the near future, as long as the inputs remain unspent and the consensus rules do not change.
|
||||
|
||||
Integrity:: A bitcoin transaction signed with +SIGHASH_ALL+ or parts of a transaction signed by another +SIGHASH+ type cannot be modified without invalidating the signature, thus invalidating the transaction itself.
|
||||
|
||||
Transaction Atomicity:: Bitcoin transactions are atomic. They are either valid and confirmed (mined) or not. Partial transactions cannot be mined and there is no interim state for a transaction. At any point in time a transaction is either mined, or not.
|
||||
|
||||
Discrete (Indivisible) Units of Value:: Transaction outputs are discrete and indivisible units of value. They can either be spent or unspent, in full. They cannot be divided or partially spent.
|
||||
|
||||
Quorum of Control:: Multisignature constraints in scripts impose a quorum of authorization, predefined in the multisignature scheme. The M-of-N requirement is enforced by the consensus rules.
|
||||
|
||||
Timelock/Aging:: Any script clause containing a relative or absolute timelock can only be executed after its age exceeds the time specified.
|
||||
|
||||
Replication:: The decentralized storage of the blockchain ensures that when a transaction is mined, after sufficient confirmations, it is replicated across the network and becomes durable and resilient to power loss, data loss, etc.
|
||||
|
||||
Forgery Protection:: A transaction can only spend existing, validated outputs. It is not possible to create or counterfeit value.
|
||||
|
||||
Consistency:: In the absence of miner partitions, blocks that are recorded in the blockchain are subject to reorganization or disagreement with exponentially decreasing likelihood, based on the depth at which they are recorded. Once deeply recorded, the computation and energy required to change makes change practically infeasible.
|
||||
|
||||
Recording External State:: A transaction can commit a data value, via +OP_RETURN+, representing a state transition in an external state machine.
|
||||
|
||||
Predictable Issuance:: Less than 21 million bitcoin will be issued, at a predictable rate.
|
||||
|
||||
The list of building blocks is not complete and more are added with each new feature introduced into bitcoin.
|
||||
|
||||
=== Applications from Building Blocks
|
||||
|
||||
((("blockchain applications", "examples of")))The building blocks offered by bitcoin are elements of a trust platform that can be used to compose applications. Here are some examples of applications that exist today and the building blocks they use:
|
||||
|
||||
Proof-of-Existence (Digital Notary):: ((("digital notary services")))((("Proof of Existence")))Immutability + Timestamp + Durability. A digital fingerprint can be committed with a transaction to the blockchain, proving that a document existed (Timestamp) at the time it was recorded. The fingerprint cannot be modified ex-post-facto (Immutability) and the proof will be stored permanently (Durability).
|
||||
|
||||
Kickstarter (Lighthouse):: Consistency + Atomicity + Integrity. If you sign one input and the output (Integrity) of a fundraiser transaction, others can contribute to the fundraiser but it cannot be spent (Atomicity) until the goal (output value) is funded (Consistency).
|
||||
|
||||
Payment Channels:: ((("payment (state) channels", "building blocks (primitives) used in")))Quorum of Control + Timelock + No Double Spend + Nonexpiration + Censorship Resistance + Authorization. A multisig 2-of-2 (Quorum) with a timelock (Timelock) used as the "settlement" transaction of a payment channel can be held (Nonexpiration) and spent at any time (Censorship Resistance) by either party (Authorization). The two parties can then create commitment transactions that double-spend (No Double-Spend) the settlement on a shorter timelock (Timelock).
|
||||
|
||||
=== Counterparty
|
||||
|
||||
((("blockchain applications", "Counterparty")))((("Counterparty")))((("smart contracts")))((("Ethereum Virtual Machine (EVM)")))((("extrinsic asset management")))((("virtual asset management")))Counterparty is a protocol layer built on top of bitcoin. The Counterparty protocol offers the ability to create and trade virtual assets and tokens. In addition, Counterparty offers a decentralized exchange for assets. Counterparty is also implementing smart contracts, based on the Ethereum Virtual Machine (EVM).
|
||||
|
||||
Counterparty embeds metadata in bitcoin transactions, using the +OP_RETURN+ opcode or 1-of-N multisignature addresses that encode metadata in the place of public keys. Using these mechanisms, Counterparty implements a protocol layer encoded in bitcoin transactions. The additional protocol layer can be interpreted by applications that are Counterparty-aware, such as wallets and blockchain explorers, or any application built using the Counterparty libraries.
|
||||
|
||||
((("digital ownership")))Counterparty can be used as a platform for other applications and services, in turn. For example, Tokenly is a platform built on top of Counterparty that allows content creators, artists, and companies to issue tokens that express digital ownership and can be used to rent, access, trade, or shop for content, products, and services. Other applications leveraging Counterparty include games (Spells of Genesis) and grid computing projects (Folding Coin).
|
||||
|
||||
More details about Counterparty can be found at https://counterparty.io. The open source project can be found at https://github.com/CounterpartyXCP[].
|
||||
|
||||
[[state_channels]]
|
||||
=== Payment Channels and State Channels
|
||||
|
||||
_Payment channels_ ((("blockchain applications", "payment (state) channels", id="BCApayment12")))((("payment (state) channels", "defined")))are a trustless mechanism for exchanging bitcoin transactions between two parties, outside of the Bitcoin blockchain. These transactions, which would be valid if settled on the Bitcoin blockchain, are held off-chain instead, acting as _promissory notes_ for eventual batch settlement. Because the transactions are not settled, they can be exchanged without the usual settlement latency, allowing extremely high transaction throughput, low (submillisecond) latency, and fine (satoshi-level) granularity.
|
||||
|
||||
Actually, the term _channel_ is a metaphor. State channels are virtual constructs represented by the exchange of state between two parties, outside of the blockchain. There are no "channels" per se and the underlying data transport mechanism is not the channel. We use the term channel to represent the relationship and shared state between two parties, outside of the blockchain.
|
||||
|
||||
((("payment (state) channels", "concept of")))To further explain this concept, think of a TCP stream. From the perspective of higher-level protocols it is a "socket" connecting two applications across the internet. But if you look at the network traffic, a TCP stream is just a virtual channel over IP packets. Each endpoint of the TCP stream sequences and assembles IP packets to create the illusion of a stream of bytes. Underneath, it's all disconnected packets. Similarly, a payment channel is just a series of transactions. If properly sequenced and connected, they create redeemable obligations that you can trust even though you don't trust the other side of the channel.
|
||||
|
||||
In this section we will look at various forms of payment channels. First, we will examine the mechanisms used to construct a one-way (unidirectional) payment channel for a metered micropayment service, such as streaming video. Then, we will expand on this mechanism and introduce bidirectional payment channels. Finally, we will look at how bidirectional channels can be connected end-to-end to form multihop channels in a routed network, first proposed under the name _Lightning Network_.
|
||||
|
||||
Payment channels are part of the broader concept of a _state channel_, which represents an off-chain alteration of state, secured by eventual settlement in a blockchain. A payment channel is a state channel where the state being altered is the balance of a virtual currency.
|
||||
|
||||
==== State Channels—Basic Concepts and Terminology
|
||||
|
||||
((("payment (state) channels", "terminology")))A state channel is established between two parties, through a transaction that locks a shared state on the blockchain. This is called the _funding transaction_ or _anchor transaction_. This single transaction must be transmitted to the network and mined to establish the channel. In the example of a payment channel, the locked state is the initial balance (in currency) of the channel.
|
||||
|
||||
The two parties then exchange signed transactions, called _commitment transactions_, that alter the initial state. These transactions are valid transactions in that they _could_ be submitted for settlement by either party, but instead are held off-chain by each party pending the channel closure. State updates can be created as fast as each party can create, sign, and transmit a transaction to the other party. In practice this means that thousands of transactions per second can be exchanged.
|
||||
|
||||
When exchanging commitment transactions the two parties also invalidate the previous states, so that the most up-to-date commitment transaction is always the only one that can be redeemed. This prevents either party from cheating by unilaterally closing the channel with an expired prior state that is more favorable to them than the current state. We will examine the various mechanisms that can be used to invalidate prior state in the rest of this chapter.
|
||||
|
||||
Finally, the channel can be closed either cooperatively, by submitting a final _settlement transaction_ to the blockchain, or unilaterally, by either party submitting the last commitment transaction to the blockchain. A unilateral close option is needed in case one of the parties unexpectedly disconnects. The settlement transaction represents the final state of the channel and is settled on the blockchain.
|
||||
|
||||
In the entire lifetime of the channel, only two transactions need to be submitted for mining on the blockchain: the funding and settlement transactions. In between these two states, the two parties can exchange any number of commitment transactions that are never seen by anyone else, nor submitted to the blockchain.
|
||||
|
||||
<<payment_channel>> illustrates a payment channel between Bob and Alice, showing the funding, commitment, and settlement transactions.((("use cases", "buying coffee", startref="alicetwelve")))
|
||||
|
||||
[[payment_channel]]
|
||||
.A payment channel between Bob and Alice, showing the funding, commitment, and settlement transactions
|
||||
image::images/mbc2_1201.png["A payment channel between Bob and Alice, showing the funding, commitment, and settlement transactions"]
|
||||
|
||||
==== Simple Payment Channel Example
|
||||
|
||||
((("payment (state) channels", "example of", id="PSCexample12")))To explain state channels, we start with a very simple example. We demonstrate a one-way channel, meaning that value is flowing in one direction only. We will also start with the naive assumption that no one is trying to cheat, to keep things simple. Once we have the basic channel idea explained, we will then look at what it takes to make it trustless so that neither party _can_ cheat, even if they are trying to.
|
||||
|
||||
For this example we will assume two participants: Emma and Fabian. Fabian offers a video streaming service that is billed by the second using a micropayment channel. Fabian charges 0.01 millibit (0.00001 BTC) per second of video, equivalent to 36 millibits (0.036 BTC) per hour of video. Emma is a user who purchases this streaming video service from Fabian. <<emma_fabian_streaming_video>> shows Emma buying the video streaming service from Fabian using a payment channel.
|
||||
|
||||
[[emma_fabian_streaming_video]]
|
||||
.Emma purchases streaming video from Fabian with a payment channel, paying for each second of video
|
||||
image::images/mbc2_1202.png["Emma purchases streaming video from Fabian with a payment channel, paying for each second of video"]
|
||||
|
||||
In this example, Fabian and Emma are using special software that handles both the payment channel and the video streaming. Emma is running the software in her browser, Fabian is running it on a server. The software includes basic bitcoin wallet functionality and can create and sign bitcoin transactions. Both the concept and the term "payment channel" are completely hidden from the users. What they see is video that is paid for by the second.
|
||||
|
||||
To set up the payment channel, Emma and Fabian establish a 2-of-2 multisignature address, with each of them holding one of the keys. From Emma's perspective, the software in her browser presents a QR code with a P2SH address (starting with "3"), and asks her to submit a "deposit" for up to 1 hour of video. The address is then funded by Emma. Emma's transaction, paying to the multisignature address, is the funding or anchor transaction for the payment channel.
|
||||
|
||||
For this example, let's say that Emma funds the channel with 36 millibits (0.036 BTC). This will allow Emma to consume _up to_ 1 hour of streaming video. The funding transaction in this case sets the maximum amount that can be transmitted in this channel, setting the _channel capacity_.
|
||||
|
||||
The funding transaction consumes one or more inputs from Emma's wallet, sourcing the funds. It creates one output with a value of 36 millibits paid to the multisignature 2-of-2 address controlled jointly between Emma and Fabian. It may have additional outputs for change back to Emma's wallet.
|
||||
|
||||
Once the funding transaction is confirmed, Emma can start streaming video. Emma's software creates and signs a commitment transaction that changes the channel balance to credit 0.01 millibit to Fabian's address and refund 35.99 millibits back to Emma. The transaction signed by Emma consumes the 36 millibits output created by the funding transaction and creates two outputs: one for her refund, the other for Fabian's payment. The transaction is only partially signed—it requires two signatures (2-of-2), but only has Emma's signature. When Fabian's server receives this transaction, it adds the second signature (for the 2-of-2 input) and returns it to Emma together with 1 second worth of video. Now both parties have a fully signed commitment transaction that either can redeem, representing the correct up-to-date balance of the channel. Neither party broadcasts this transaction to the network.
|
||||
|
||||
In the next round, Emma's software creates and signs another commitment transaction (commitment #2) that consumes the _same_ 2-of-2 output from the funding transaction. The second commitment transaction allocates one output of 0.02 millibits to Fabian's address and one output of 35.98 millibits back to Emma's address. This new transaction is payment for two cumulative seconds of video. Fabian's software signs and returns the second commitment transaction, together with another second of video.
|
||||
|
||||
In this way, Emma's software continues to send commitment transactions to Fabian's server in exchange for streaming video. The balance of the channel gradually accumulates in favor of Fabian, as Emma consumes more seconds of video. Let's say Emma watches 600 seconds (10 minutes) of video, creating and signing 600 commitment transactions. The last commitment transaction (#600) will have two outputs, splitting the balance of the channel, 6 millibits to Fabian and 30 millibits to Emma.
|
||||
|
||||
Finally, Emma selects "Stop" to stop streaming video. Either Fabian or Emma can now transmit the final state transaction for settlement. This last transaction is the _settlement transaction_ and pays Fabian for all the video Emma consumed, refunding the remainder of the funding transaction to Emma.
|
||||
|
||||
<<video_payment_channel>> shows the channel between Emma and Fabian and the commitment transactions that update the balance of the channel.
|
||||
|
||||
In the end, only two transactions are recorded on the blockchain: the funding transaction that established the channel and a settlement transaction that allocated the final balance correctly between the two participants.((("", startref="PSCexample12")))
|
||||
|
||||
[[video_payment_channel]]
|
||||
.Emma's payment channel with Fabian, showing the commitment transactions that update the balance of the channel
|
||||
image::images/mbc2_1203.png["Emma's payment channel with Fabian, showing the commitment transactions that update the balance of the channel"]
|
||||
|
||||
==== Making Trustless Channels
|
||||
|
||||
((("payment (state) channels", "making trustless channels", id="PSCtrust12")))The channel we just described works, but only if both parties cooperate, without any failures or attempts to cheat. Let's look at some of the scenarios that break this channel and see what is needed to fix those:
|
||||
|
||||
* Once the funding transaction happens, Emma needs Fabian's signature to get any money back. If Fabian disappears, Emma's funds are locked in a 2-of-2 and effectively lost. This channel, as constructed, leads to a loss of funds if one of the parties disconnects before there is at least one commitment transaction signed by both parties.
|
||||
|
||||
* While the channel is running, Emma can take any of the commitment transactions Fabian has countersigned and transmit one to the blockchain. Why pay for 600 seconds of video, if she can transmit commitment transaction #1 and only pay for 1 second of video? The channel fails because Emma can cheat by broadcasting a prior commitment that is in her favor.
|
||||
|
||||
Both of these problems can be solved with timelocks—let's look at how we could use transaction-level timelocks (+nLocktime+).
|
||||
|
||||
Emma cannot risk funding a 2-of-2 multisig unless she has a guaranteed refund. To solve this problem, Emma constructs the funding and refund transactions at the same time. She signs the funding transaction but doesn't transmit it to anyone. Emma transmits only the refund transaction to Fabian and obtains his signature.
|
||||
|
||||
The refund transaction acts as the first commitment transaction and its timelock establishes the upper bound for the channel's life. In this case, Emma could set the +nLocktime+ to 30 days or 4320 blocks into the future. All subsequent commitment transactions must have a shorter timelock, so that they can be redeemed before the refund transaction.
|
||||
|
||||
Now that Emma has a fully signed refund transaction, she can confidently transmit the signed funding transaction knowing that she can eventually, after the timelock expires, redeem the refund transaction even if Fabian disappears.
|
||||
|
||||
Every commitment transaction the parties exchange during the life of the channel will be timelocked into the future. But the delay will be slightly shorter for each commitment so the most recent commitment can be redeemed before the prior commitment it invalidates. Because of the nLockTime, neither party can successfully propagate any of the commitment transactions until their timelock expires. If all goes well, they will cooperate and close the channel gracefully with a settlement transaction, making it unnecessary to transmit an intermediate commitment transaction. If not, the most recent commitment transaction can be propagated to settle the account and invalidate all prior commitment transactions.
|
||||
|
||||
For example, if commitment transaction #1 is timelocked to 4320 blocks in the future, then commitment transaction #2 is timelocked to 4319 blocks in the future. Commitment transaction #600 can be spent 600 blocks before commitment transaction #1 becomes valid.
|
||||
|
||||
<<timelocked_commitments>> shows each commitment transaction setting a shorter timelock, allowing it to be spent before the previous commitments become valid.
|
||||
|
||||
[[timelocked_commitments]]
|
||||
.Each commitment sets a shorter timelock, allowing it to be spent before the previous commitments become valid
|
||||
image::images/mbc2_1204.png["Each commitment sets a shorter timelock, allowing it to be spent before the previous commitments become valid"]
|
||||
|
||||
Each subsequent commitment transaction must have a shorter timelock so that it may be broadcast before its predecessors and before the refund transaction. The ability to broadcast a commitment earlier ensures it will be able to spend the funding output and preclude any other commitment transaction from being redeemed by spending the output. The guarantees offered by the Bitcoin blockchain, preventing double-spends and enforcing timelocks, effectively allow each commitment transaction to invalidate its predecessors.
|
||||
|
||||
State channels use timelocks to enforce smart contracts across a time dimension. In this example we saw how the time dimension guarantees that the most recent commitment transaction becomes valid before any earlier commitments. Thus, the most recent commitment transaction can be transmitted, spending the inputs and invalidating prior commitment transactions. The enforcement of smart contracts with absolute timelocks protects against cheating by one of the parties. This implementation needs nothing more than absolute transaction-level timelocks (+nLocktime+). Next, we will see how script-level timelocks, +CHECKLOCKTIMEVERIFY+ and +CHECKSEQUENCEVERIFY+, can be used to construct more flexible, useful, and sophisticated state channels.
|
||||
|
||||
The first form of unidirectional payment channel was demonstrated as a prototype video streaming application in 2015 by an Argentinian team of developers.
|
||||
|
||||
Timelocks are not the only way to invalidate prior commitment transactions. In the next sections we will see how a revocation key can be used to achieve the same result. Timelocks are effective but they have two distinct disadvantages. By establishing a maximum timelock when the channel is first opened, they limit the lifetime of the channel. Worse, they force channel implementations to strike a balance between allowing long-lived channels and forcing one of the participants to wait a very long time for a refund in case of premature closure. For example, if you allow the channel to remain open for 30 days, by setting the refund timelock to 30 days, if one of the parties disappears immediately the other party must wait 30 days for a refund. The more distant the endpoint, the more distant the refund.
|
||||
|
||||
The second problem is that since each subsequent commitment transaction must decrement the timelock, there is an explicit limit on the number of commitment transactions that can be exchanged between the parties. For example, a 30-day channel, setting a timelock of 4320 blocks into the future, can only accommodate 4320 intermediate commitment transactions before it must be closed. There is a danger in setting the timelock commitment transaction interval at 1 block. By setting the timelock interval between commitment transactions to 1 block, a developer is creating a very high burden for the channel participants who have to be vigilant, remain online and watching, and be ready to transmit the right commitment transaction at any time.
|
||||
|
||||
Now that we understand how timelocks can be used to invalidate prior commitments, we can see the difference between closing the channel cooperatively and closing it unilaterally by broadcasting a commitment transaction. All commitment transactions are timelocked, therefore broadcasting a commitment transaction will always involve waiting until the timelock has expired. But if the two parties agree on what the final balance is and know they both hold commitment transactions that will eventually make that balance a reality, they can construct a settlement transaction without a timelock representing that same balance. In a cooperative close, either party takes the most recent commitment transaction and builds a settlement transaction that is identical in every way except that it omits the timelock. Both parties can sign this settlement transaction knowing there is no way to cheat and get a more favorable balance. By cooperatively signing and transmitting the settlement transaction they can close the channel and redeem their balance immediately. Worst case, one of the parties can be petty, refuse to cooperate, and force the other party to do a unilateral close with the most recent commitment transaction. But if they do that, they have to wait for their funds too.((("", startref="PSCtrust12")))
|
||||
|
||||
==== Asymmetric Revocable Commitments
|
||||
|
||||
((("payment (state) channels", "asymmetric revocable commitments", id="PSCaymetric12")))A better way to handle the prior commitment states is to explicitly revoke them. However, this is not easy to achieve. A key characteristic of bitcoin is that once a transaction is valid, it remains valid and does not expire. The only way to cancel a transaction is by double-spending its inputs with another transaction before it is mined. That's why we used timelocks in the simple payment channel example above to ensure that more recent commitments could be spent before older commitments were valid. However, sequencing commitments in time creates a number of constraints that make payment channels difficult to use.
|
||||
|
||||
Even though a transaction cannot be canceled, it can be constructed in such a way as to make it undesirable to use. The way we do that is by giving each party a _revocation key_ that can be used to punish the other party if they try to cheat. This mechanism for revoking prior commitment transactions was first proposed as part of the Lightning Network.
|
||||
|
||||
To explain revocation keys, we will construct a more complex payment channel between two exchanges run by Hitesh and Irene. Hitesh and Irene run bitcoin exchanges in India and the USA, respectively. Customers of Hitesh's Indian exchange often send payments to customers of Irene's USA exchange and vice versa. Currently, these transactions occur on the Bitcoin blockchain, but this means paying fees and waiting several blocks for confirmations. Setting up a payment channel between the exchanges will significantly reduce the cost and accelerate the transaction flow.
|
||||
|
||||
Hitesh and Irene start the channel by collaboratively constructing a funding transaction, each funding the channel with 5 bitcoin.
|
||||
The initial balance is 5 bitcoin for Hitesh and 5 bitcoin for Irene. The funding transaction locks the channel state in a 2-of-2 multisig, just like in the example of a simple channel.
|
||||
|
||||
The funding transaction may have one or more inputs from Hitesh (adding up to 5 bitcoin or more), and one or more inputs from Irene (adding up to 5 bitcoin or more). The inputs have to slightly exceed the channel capacity in order to cover the transaction fees. The transaction has one output that locks the 10 total bitcoin to a 2-of-2 multisig address controlled by both Hitesh and Irene. The funding transaction may also have one or more outputs returning change to Hitesh and Irene if their inputs exceeded their intended channel contribution. This is a single transaction with inputs offered and signed by two parties. It has to be constructed in collaboration and signed by each party before it is transmitted.
|
||||
|
||||
Now, instead of creating a single commitment transaction that both parties sign, Hitesh and Irene create two different commitment transactions that are _asymmetric_.
|
||||
|
||||
Hitesh has a commitment transaction with two outputs. The first output pays Irene the 5 bitcoin she is owed _immediately_. The second output pays Hitesh the 5 bitcoin he is owed, but only after a timelock of 1000 blocks. The transaction outputs look like this:
|
||||
|
||||
----
|
||||
Input: 2-of-2 funding output, signed by Irene
|
||||
|
||||
Output 0 <5 bitcoin>:
|
||||
<Irene's Public Key> CHECKSIG
|
||||
|
||||
Output 1 <5 bitcoin>:
|
||||
<1000 blocks>
|
||||
CHECKSEQUENCEVERIFY
|
||||
DROP
|
||||
<Hitesh's Public Key> CHECKSIG
|
||||
----
|
||||
|
||||
Irene has a different commitment transaction with two outputs. The first output pays Hitesh the 5 bitcoin he is owed immediately. The second output pays Irene the 5 bitcoin she is owed but only after a timelock of 1000 blocks. The commitment transaction Irene holds (signed by Hitesh) looks like this:
|
||||
|
||||
----
|
||||
Input: 2-of-2 funding output, signed by Hitesh
|
||||
|
||||
Output 0 <5 bitcoin>:
|
||||
<Hitesh's Public Key> CHECKSIG
|
||||
|
||||
Output 1 <5 bitcoin>:
|
||||
<1000 blocks>
|
||||
CHECKSEQUENCEVERIFY
|
||||
DROP
|
||||
<Irene's Public Key> CHECKSIG
|
||||
----
|
||||
|
||||
This way, each party has a commitment transaction, spending the 2-of-2 funding output. This input is signed by the _other_ party. At any time the party holding the transaction can also sign (completing the 2-of-2) and broadcast. However, if they broadcast the commitment transaction, it pays the other party immediately whereas they have to wait for a timelock to expire. By imposing a delay on the redemption of one of the outputs, we put each party at a slight disadvantage when they choose to unilaterally broadcast a commitment transaction. But a time delay alone isn't enough to encourage fair conduct.
|
||||
|
||||
<<asymmetric_commitments>> shows two asymmetric commitment transactions, where the output paying the holder of the commitment is delayed.
|
||||
|
||||
[[asymmetric_commitments]]
|
||||
.Two asymmetric commitment transactions with delayed payment for the party holding the transaction
|
||||
image::images/mbc2_1205.png["Two asymmetric commitment transactions with delayed payment for the party holding the transaction"]
|
||||
|
||||
Now we introduce the final element of this scheme: a revocation key that prevents a cheater from broadcasting an expired commitment. The revocation key allows the wronged party to punish the cheater by taking the entire balance of the channel.
|
||||
|
||||
The revocation key is composed of two secrets, each half generated independently by each channel participant. It is similar to a 2-of-2 multisig, but constructed using elliptic curve arithmetic, so that both parties know the revocation public key but each party knows only half the revocation secret key.
|
||||
|
||||
In each round, both parties reveal their half of the revocation secret to the other party, thereby giving the other party (who now has both halves) the means to claim the penalty output if this revoked transaction is ever broadcast.
|
||||
|
||||
Each of the commitment transactions has a "delayed" output. The redemption script for that output allows one party to redeem it after 1000 blocks, _or_ the other party to redeem it if they have a revocation key, penalizing transmission of a revoked commitment.
|
||||
|
||||
So when Hitesh creates a commitment transaction for Irene to sign, he makes the second output payable to himself after 1000 blocks, or to the revocation public key (of which he only knows half the secret). Hitesh constructs this transaction. He will only reveal his half of the revocation secret to Irene when he is ready to move to a new channel state and wants to revoke this commitment.
|
||||
|
||||
The second output's script looks like this:
|
||||
|
||||
----
|
||||
Output 0 <5 bitcoin>:
|
||||
<Irene's Public Key> CHECKSIG
|
||||
|
||||
Output 1 <5 bitcoin>:
|
||||
IF
|
||||
# Revocation penalty output
|
||||
<Revocation Public Key>
|
||||
ELSE
|
||||
<1000 blocks>
|
||||
CHECKSEQUENCEVERIFY
|
||||
DROP
|
||||
<Hitesh's Public Key>
|
||||
ENDIF
|
||||
CHECKSIG
|
||||
----
|
||||
|
||||
Irene can confidently sign this transaction, since if transmitted it will immediately pay her what she is owed. Hitesh holds the transaction, but knows that if he transmits it in a unilateral channel closing, he will have to wait 1000 blocks to get paid.
|
||||
|
||||
When the channel is advanced to the next state, Hitesh has to _revoke_ this commitment transaction before Irene agrees to sign the next commitment transaction. To do that, all he has to do is send his half of the _revocation key_ to Irene. Once Irene has both halves of the revocation secret key for this commitment, she can sign the next commitment with confidence. She knows that if Hitesh tries to cheat by publishing the prior commitment, she can use the revocation key to redeem Hitesh's delayed output. _If Hitesh cheats, Irene gets BOTH outputs_. Meanwhile, Hitesh only has half the revocation secret for that revocation public key and can't redeem the output until 1000 blocks. Irene will be able to redeem the output and punish Hitesh before the 1000 blocks have elapsed.
|
||||
|
||||
The revocation protocol is bilateral, meaning that in each round, as the channel state is advanced, the two parties exchange new commitments, exchange revocation secrets for the previous commitments, and sign each other's new commitment transactions. As they accept a new state, they make the prior state impossible to use, by giving each other the necessary revocation secrets to punish any cheating.
|
||||
|
||||
Let's look at an example of how it works. One of Irene's customers wants to send 2 bitcoin to one of Hitesh's customers. To transmit 2 bitcoin across the channel, Hitesh and Irene must advance the channel state to reflect the new balance. They will commit to a new state (state number 2) where the channel's 10 bitcoin are split, 7 bitcoin to Hitesh and 3 bitcoin to Irene. To advance the state of the channel, they will each create new commitment transactions reflecting the new channel balance.
|
||||
|
||||
As before, these commitment transactions are asymmetric so that the commitment transaction each party holds forces them to wait if they redeem it. Crucially, before signing new commitment transactions, they must first exchange revocation keys to invalidate the prior commitment. In this particular case, Hitesh's interests are aligned with the real state of the channel and therefore he has no reason to broadcast a prior state. However, for Irene, state number 1 leaves her with a higher balance than state 2. When Irene gives Hitesh the revocation key for her prior commitment transaction (state number 1) she is effectively revoking her ability to profit from regressing the channel to a prior state because with the revocation key, Hitesh can redeem both outputs of the prior commitment transaction without delay. Meaning if Irene broadcasts the prior state, Hitesh can exercise his right to take all of the outputs.
|
||||
|
||||
Importantly, the revocation doesn't happen automatically. While Hitesh has the ability to punish Irene for cheating, he has to watch the blockchain diligently for signs of cheating. If he sees a prior commitment transaction broadcast, he has 1000 blocks to take action and use the revocation key to thwart Irene's cheating and punish her by taking the entire balance, all 10 bitcoin.
|
||||
|
||||
Asymmetric revocable commitments with relative time locks (+CSV+) are a much better way to implement payment channels and a very significant innovation in this technology. With this construct, the channel can remain open indefinitely and can have billions of intermediate commitment transactions. In prototype implementations of Lightning Network, the commitment state is identified by a 48-bit index, allowing more than 281 trillion (2.8 x 10^14^) state transitions in any single channel!((("", startref="PSCaymetric12")))
|
||||
|
||||
==== Hash Time Lock Contracts (HTLC)
|
||||
|
||||
((("Hash Time Lock Contracts (HTLC)")))((("payment (state) channels", "Hash Time Lock Contracts (HTLC)")))Payment channels can be further extended with a special type of smart contract that allows the participants to commit funds to a redeemable secret, with an expiration time. This feature is called a _Hash Time Lock Contract_, or _HTLC_, and is used in both bidirectional and routed payment channels.
|
||||
|
||||
Let's first explain the "hash" part of the HTLC. To create an HTLC, the intended recipient of the payment will first create a secret +R+. They then calculate the hash of this secret +H+:
|
||||
|
||||
----
|
||||
H = Hash(R)
|
||||
----
|
||||
|
||||
This produces a hash +H+ that can be included in an output's locking script. Whoever knows the secret can use it to redeem the output. The secret +R+ is also referred to as a _preimage_ to the hash function. The preimage is just the data that is used as input to a hash function.
|
||||
|
||||
The second part of an HTLC is the "time lock" component. If the secret is not revealed, the payer of the HTLC can get a "refund" after some time. This is achieved with an absolute time lock using +CHECKLOCKTIMEVERIFY+.
|
||||
|
||||
The script implementing an HTLC might look like this:
|
||||
|
||||
----
|
||||
IF
|
||||
# Payment if you have the secret R
|
||||
HASH160 <H> EQUALVERIFY
|
||||
ELSE
|
||||
# Refund after timeout.
|
||||
<locktime> CHECKLOCKTIMEVERIFY DROP
|
||||
<Payer Public Key> CHECKSIG
|
||||
ENDIF
|
||||
----
|
||||
|
||||
Anyone who knows the secret +R+, which when hashed equals to +H+, can redeem this output by exercising the first clause of the +IF+ flow.
|
||||
|
||||
If the secret is not revealed and the HTLC claimed, after a certain number of blocks the payer can claim a refund using the second clause in the +IF+ flow.
|
||||
|
||||
This is a basic implementation of an HTLC. This type of HTLC can be redeemed by _anyone_ who has the secret +R+. An HTLC can take many different forms with slight variations to the script. For example, adding a +CHECKSIG+ operator and a public key in the first clause restricts redemption of the hash to a named recipient, who must also know the secret +R+.((("", startref="BCApayment12")))
|
||||
|
||||
[[lightning_network]]
|
||||
=== Routed Payment Channels (Lightning Network)
|
||||
|
||||
((("blockchain applications", "routed payment channels", seealso="Lightning Network", id="BCAlightning12")))((("routed payment channels", see="Lightning Network")))((("Lightning Network", "defined")))The Lightning Network is a proposed routed network of bidirectional payment channels connected end-to-end. A network like this can allow any participant to route a payment from channel to channel without trusting any of the intermediaries. The Lightning Network was https://lightning.network/lightning-network-paper.pdf[first described by Joseph Poon and Thadeus Dryja in February 2015], building on the concept of payment channels as proposed and elaborated upon by many others.
|
||||
|
||||
"Lightning Network" refers to a specific design for a routed payment channel network, which has now been implemented by at least five different open source teams. ((("Basics of Lightning Technology (BOLT)")))The independent implementations are coordinated by a set of interoperability standards described in the https://bit.ly/2rBHeoL[_Basics of Lightning Technology (BOLT)_ paper].
|
||||
|
||||
Prototype implementations of the Lightning Network have been released by several teams.
|
||||
|
||||
The Lightning Network is one possible way of implementing routed payment channels. There are several other designs that aim to achieve similar goals, such as Teechan and Tumblebit.
|
||||
|
||||
==== Basic Lightning Network Example
|
||||
|
||||
((("Lightning Network", "basic example")))Let's see how this works.
|
||||
|
||||
In this example, we have five participants: Alice, Bob, Carol, Diana, and Eric. These five participants have opened payment channels with each other, in pairs. Alice has a payment channel with Bob. Bob is connected to Carol, Carol to Diana, and Diana to Eric. For simplicity let's assume each channel is funded with 2 bitcoin by each participant, for a total capacity of 4 bitcoin in each channel.
|
||||
|
||||
<<lightning_network_fig>> shows five participants in a Lightning Network, connected by bidirectional payment channels that can be linked to make a payment from Alice to Eric (<<lightning_network>>).
|
||||
|
||||
[[lightning_network_fig]]
|
||||
.A series of bidirectional payment channels linked to form a Lightning Network that can route a payment from Alice to Eric
|
||||
image::images/mbc2_1206.png["A series of bi-directional payment channels linked to form a Lightning Network"]
|
||||
|
||||
Alice wants to pay Eric 1 bitcoin. However, Alice is not connected to Eric by a payment channel. Creating a payment channel requires a funding transaction, which must be committed to the Bitcoin blockchain. Alice does not want to open a new payment channel and commit more of her funds. Is there a way to pay Eric, indirectly?
|
||||
|
||||
<<ln_payment_process>> shows the step-by-step process of routing a payment from Alice to Eric, through a series of HTLC commitments on the payment channels connecting the participants.
|
||||
|
||||
[[ln_payment_process]]
|
||||
.Step-by-step payment routing through a Lightning Network
|
||||
image::images/mbc2_1207.png["Step-by-step payment routing through a Lightning Network"]
|
||||
|
||||
Alice is running a Lightning Network (LN) node that is keeping track of her payment channel to Bob and has the ability to discover routes between payment channels. Alice's LN node also has the ability to connect over the internet to Eric's LN node. Eric's LN node creates a secret +R+ using a random number generator. Eric's node does not reveal this secret to anyone. Instead, Eric's node calculates a hash +H+ of the secret +R+ and transmits this hash to Alice's node (see <<ln_payment_process>> step 1).
|
||||
|
||||
Now Alice's LN node constructs a route between Alice's LN node and Eric's LN node. The routing algorithm used will be examined in more detail later, but for now let's assume that Alice's node can find an efficient route.
|
||||
|
||||
Alice's node then constructs an HTLC, payable to the hash +H+, with a 10-block refund timeout (current block + 10), for an amount of 1.003 bitcoin (see <<ln_payment_process>> step 2). The extra 0.003 will be used to compensate the intermediate nodes for their participation in this payment route. Alice offers this HTLC to Bob, deducting 1.003 bitcoin from her channel balance with Bob and committing it to the HTLC. The HTLC has the following meaning: _"Alice is committing 1.003 of her channel balance to be paid to Bob if Bob knows the secret, or refunded back to Alice's balance if 10 blocks elapse."_ The channel balance between Alice and Bob is now expressed by commitment transactions with three outputs: 2 bitcoin balance to Bob, 0.997 bitcoin balance to Alice, 1.003 bitcoin committed in Alice's HTLC. Alice's balance is reduced by the amount committed to the HTLC.
|
||||
|
||||
Bob now has a commitment that if he is able to get the secret +R+ within the next 10 blocks, he can claim the 1.003 locked by Alice. With this commitment in hand, Bob's node constructs an HTLC on his payment channel with Carol. Bob's HTLC commits 1.002 bitcoin to hash +H+ for 9 blocks, which Carol can redeem if she has secret +R+ (see <<ln_payment_process>> step 3). Bob knows that if Carol can claim his HTLC, she has to produce +R+. If Bob has +R+ in nine blocks, he can use it to claim Alice's HTLC to him. He also makes 0.001 bitcoin for committing his channel balance for nine blocks. If Carol is unable to claim his HTLC and he is unable to claim Alice's HTLC, everything reverts back to the prior channel balances and no one is at a loss. The channel balance between Bob and Carol is now: 2 to Carol, 0.998 to Bob, 1.002 committed by Bob to the HTLC.
|
||||
|
||||
Carol now has a commitment that if she gets +R+ within the next nine blocks, she can claim 1.002 bitcoin locked by Bob. Now she can make an HTLC commitment on her channel with Diana. She commits an HTLC of 1.001 bitcoin to hash +H+, for eight blocks, which Diana can redeem if she has secret +R+ (see <<ln_payment_process>> step 4). From Carol's perspective, if this works she is 0.001 bitcoin better off and if it doesn't she loses nothing. Her HTLC to Diana is only viable if +R+ is revealed, at which point she can claim the HTLC from Bob. The channel balance between Carol and Diana is now: 2 to Diana, 0.999 to Carol, 1.001 committed by Carol to the HTLC.
|
||||
|
||||
Finally, Diana can offer an HTLC to Eric, committing 1 bitcoin for seven blocks to hash +H+ (see <<ln_payment_process>> step 5). The channel balance between Diana and Eric is now: 2 to Eric, 1 to Diana, 1 committed by Diana to the HTLC.
|
||||
|
||||
However, at this hop in the route, Eric _has_ secret +R+. He can therefore claim the HTLC offered by Diana. He sends +R+ to Diana and claims the 1 bitcoin, adding it to his channel balance (see <<ln_payment_process>> step 6). The channel balance is now: 1 to Diana, 3 to Eric.
|
||||
|
||||
Now, Diana has secret +R+. Therefore, she can now claim the HTLC from Carol. Diana transmits +R+ to Carol and adds the 1.001 bitcoin to her channel balance (see <<ln_payment_process>> step 7). Now the channel balance between Carol and Diana is: 0.999 to Carol, 3.001 to Diana. Diana has "earned" 0.001 for participating in this payment route.
|
||||
|
||||
Flowing back through the route, the secret +R+ allows each participant to claim the outstanding HTLCs. Carol claims 1.002 from Bob, setting the balance on their channel to: 0.998 to Bob, 3.002 to Carol (see <<ln_payment_process>> step 8). Finally, Bob claims the HTLC from Alice (see <<ln_payment_process>> step 9). Their channel balance is updated as: 0.997 to Alice, 3.003 to Bob.
|
||||
|
||||
Alice has paid Eric 1 bitcoin without opening a channel to Eric. None of the intermediate parties in the payment route had to trust each other. For the short-term commitment of their funds in the channel they are able to earn a small fee, with the only risk being a small delay in refund if the channel was closed or the routed payment failed.
|
||||
|
||||
==== Lightning Network Transport and Routing
|
||||
|
||||
((("Lightning Network", "transport and routing")))All communications between LN nodes are encrypted point-to-point. In addition, nodes have a long-term public key that they use as an identifier and to authenticate each other.
|
||||
|
||||
Whenever a node wishes to send a payment to another node, it must first construct a _path_ through the network by connecting payment channels with sufficient capacity. Nodes advertise routing information, including what channels they have open, how much capacity each channel has, and what fees they charge to route payments. The routing information can be shared in a variety of ways and different routing protocols are likely to emerge as Lightning Network technology advances. Some Lightning Network implementations use the IRC protocol as a convenient mechanism for nodes to announce routing information. Another implementation of route discovery uses a P2P model where nodes propagate channel announcements to their peers, in a "flooding" model, similar to how bitcoin propagates transactions. Future plans include a proposal called https://bit.ly/2r5TACm[Flare], which is a hybrid routing model with local node "neighborhoods" and longer-range beacon nodes.
|
||||
|
||||
In our previous example, Alice's node uses one of these route discovery mechanisms to find one or more paths connecting her node to Eric's node. Once Alice's node has constructed a path, she will initialize that path through the network, by propagating a series of encrypted and nested instructions to connect each of the adjacent payment channels.
|
||||
|
||||
Importantly, this path is only known to Alice's node. All other participants in the payment route see only the adjacent nodes. From Carol's perspective, this looks like a payment from Bob to Diana. Carol does not know that Bob is actually relaying a payment from Alice. She also doesn't know that Diana will be relaying a payment to Eric.
|
||||
|
||||
This is a critical feature of the Lightning Network, because it ensures privacy of payments and makes it very difficult to apply surveillance, censorship, or blacklists. But how does Alice establish this payment path, without revealing anything to the intermediary nodes?
|
||||
|
||||
The Lightning Network implements an onion-routed protocol based on a scheme called https://bit.ly/2q6ZDrP[Sphinx]. This routing protocol ensures that a payment sender can construct and communicate a path through the Lightning Network such that:
|
||||
|
||||
* Intermediate nodes can verify and decrypt their portion of route information and find the next hop.
|
||||
|
||||
* Other than the previous and next hops, they cannot learn about any other nodes that are part of the path.
|
||||
|
||||
* They cannot identify the length of the payment path, or their own position in that path.
|
||||
|
||||
* Each part of the path is encrypted in such a way that a network-level attacker cannot associate the packets from different parts of the path to each other.
|
||||
|
||||
* Unlike Tor (an onion-routed anonymization protocol on the internet), there are no "exit nodes" that can be placed under surveillance. The payments do not need to be transmitted to the Bitcoin blockchain; the nodes just update channel balances.
|
||||
|
||||
Using this onion-routed protocol, Alice wraps each element of the path in a layer of encryption, starting with the end and working backward. She encrypts a message to Eric with Eric's public key. This message is wrapped in a message encrypted to Diana, identifying Eric as the next recipient. The message to Diana is wrapped in a message encrypted to Carol's public key and identifying Diana as the next recipient. The message to Carol is encrypted to Bob's key. Thus, Alice has constructed this encrypted multilayer "onion" of messages. She sends this to Bob, who can only decrypt and unwrap the outer layer. Inside, Bob finds a message addressed to Carol that he can forward to Carol but cannot decipher himself. Following the path, the messages get forwarded, decrypted, forwarded, etc., all the way to Eric. Each participant knows only the previous and next node in each hop.((("", startref="alicetwelve")))
|
||||
|
||||
Each element of the path contains information on the HTLC that must be extended to the next hop, the amount that is being sent, the fee to include, and the CLTV locktime (in blocks) expiration of the HTLC. As the route information propagates, the nodes make HTLC commitments forward to the next hop.
|
||||
|
||||
At this point, you might be wondering how it is possible that the nodes do not know the length of the path and their position in that path. After all, they receive a message and forward it to the next hop. Doesn't it get shorter, allowing them to deduce the path size and their position? To prevent this, the path is always fixed at 20 hops and padded with random data. Each node sees the next hop and a fixed-length encrypted message to forward. Only the final recipient sees that there is no next hop. To everyone else it seems as if there are always 20 more hops to go.
|
||||
|
||||
==== Lightning Network Benefits
|
||||
|
||||
((("Lightning Network", "benefits of")))A Lightning Network is a second-layer routing technology. It can be applied to any blockchain that supports some basic capabilities, such as multisignature transactions, timelocks, and basic smart contracts.
|
||||
|
||||
If a Lightning Network is layered on top of the Bitcoin network, the Bitcoin network can gain a significant increase in capacity, privacy, granularity, and speed, without sacrificing the principles of trustless operation without intermediaries:
|
||||
|
||||
Privacy:: Lightning Network payments are much more private than payments on the Bitcoin blockchain, as they are not public. While participants in a route can see payments propagated across their channels, they do not know the sender or recipient.
|
||||
|
||||
Fungibility:: A Lightning Network makes it much more difficult to apply surveillance and blacklists on bitcoin, increasing the fungibility of the currency.
|
||||
|
||||
Speed:: Bitcoin transactions using Lightning Network are settled in milliseconds, rather than minutes, as HTLCs are cleared without committing transactions to a block.
|
||||
|
||||
Granularity:: A Lightning Network can enable payments at least as small as the bitcoin "dust" limit, perhaps even smaller. Some proposals allow for subsatoshi increments.
|
||||
|
||||
Capacity:: A Lightning Network increases the capacity of the Bitcoin system by several orders of magnitude. There is no practical upper bound to the number of payments per second that can be routed over a Lightning Network, as it depends only on the capacity and speed of each node.
|
||||
|
||||
Trustless Operation:: A Lightning Network uses bitcoin transactions between nodes that operate as peers without trusting each other. Thus, a Lightning Network preserves the principles of the Bitcoin system, while expanding its operating parameters significantly.
|
||||
|
||||
Of course, as mentioned previously, the Lightning Network protocol is not the only way to implement routed payment channels. Other proposed systems include Tumblebit and Teechan. At this time, however, the Lightning Network has already been deployed on testnet. Several different teams have developed competing implementations of LN and are working toward a common interoperability standard (called BOLT). It is likely that Lightning Network will be the first routed payment channel network to be deployed in production.((("", startref="BCAlightning12")))
|
||||
|
||||
=== Conclusion
|
||||
|
||||
We have examined just a few of the emerging applications that can be built using the Bitcoin blockchain as a trust platform. These applications expand the scope of bitcoin beyond payments and beyond financial instruments, to encompass many other applications where trust is critical. By decentralizing the basis of trust, the Bitcoin blockchain is a platform that will spawn many revolutionary applications in a wide variety of industries.
|
@ -0,0 +1,291 @@
|
||||
[[ch11]]
|
||||
== Bitcoin Security
|
||||
|
||||
Securing your bitcoins is challenging because bitcoins are
|
||||
are not like a balance in a bank account. Your bitcoins are very
|
||||
much like digital cash or gold. You've probably heard the expression,
|
||||
"Possession is nine-tenths of the law." Well, in Bitcoin, possession is
|
||||
ten-tenths of the law. Possession of the keys to spend certain bitcoins is
|
||||
equivalent to possession of cash or a chunk of precious metal. You can
|
||||
lose it, misplace it, have it stolen, or accidentally give the wrong
|
||||
amount to someone. In every one of these cases, users have no recourse
|
||||
within the protocol, just as if they dropped cash on a public sidewalk.
|
||||
|
||||
However, the Bitcoin system has capabilities that cash, gold, and bank accounts do
|
||||
not. A Bitcoin wallet, containing your keys, can be backed up like any
|
||||
file. It can be stored in multiple copies, even printed on paper for
|
||||
hard-copy backup. You can't "back up" cash, gold, or bank accounts.
|
||||
Bitcoin is different enough from anything that has come before that we
|
||||
need to think about securing our bitcoins in a novel way too.
|
||||
|
||||
=== Security Principles
|
||||
|
||||
The ((("Bitcoin", "security", "principles of", id="bitcoin-security-principle")))((("security", "principles of", id="security-principle")))((("decentralized consensus", "as security principle", secondary-sortas="security principle", id="decentral-consensus-principle")))core principle in Bitcoin is
|
||||
decentralization and it has important implications for security. A
|
||||
centralized model, such as a traditional bank or payment network,
|
||||
depends on access control and vetting to keep bad actors out of the
|
||||
system. By comparison, a decentralized system like Bitcoin pushes the
|
||||
responsibility and control to the users. Because the security of the network
|
||||
is based on independent verification, the network can be open
|
||||
and no encryption is required for Bitcoin traffic (although encryption
|
||||
can still be useful).
|
||||
|
||||
On a traditional payment network, such as a credit card system, the
|
||||
payment is open-ended because it contains the user's private identifier
|
||||
(the credit card number). After the initial charge, anyone with access
|
||||
to the identifier can "pull" funds and charge the owner again and again.
|
||||
Thus, the payment network has to be secured end-to-end with encryption
|
||||
and must ensure that no eavesdroppers or intermediaries can compromise
|
||||
the payment traffic in transit or when it is stored (at rest). If a bad
|
||||
actor gains access to the system, he can compromise current transactions
|
||||
_and_ payment tokens that can be used to create new transactions. Worse,
|
||||
when customer data is compromised, the customers are exposed to identity
|
||||
theft and must take action to prevent fraudulent use of the compromised
|
||||
accounts.
|
||||
|
||||
Bitcoin is dramatically different. A Bitcoin transaction authorizes only
|
||||
a specific value to a specific recipient and cannot be forged.
|
||||
It does not reveal any private information, such as the
|
||||
identities of the parties, and cannot be used to authorize additional
|
||||
payments. Therefore, a Bitcoin payment network does not need to be
|
||||
encrypted or protected from eavesdropping. In fact, you can broadcast
|
||||
Bitcoin transactions over an open public channel, such as unsecured WiFi
|
||||
or Bluetooth, with no loss of security.
|
||||
|
||||
Bitcoin's decentralized security model puts a lot of power in the hands
|
||||
of the users. With that power comes responsibility for maintaining the
|
||||
secrecy of their keys. For most users that is not easy to do, especially
|
||||
on general-purpose computing devices such as internet-connected
|
||||
smartphones or laptops. Although Bitcoin's decentralized model prevents
|
||||
the type of mass compromise seen with credit cards, many users are not
|
||||
able to adequately secure their keys and get hacked, one by one.
|
||||
|
||||
==== Developing Bitcoin Systems Securely
|
||||
|
||||
A critical principle
|
||||
for Bitcoin developers is decentralization. Most developers will be
|
||||
familiar with centralized security models and might be tempted to apply
|
||||
these models to their Bitcoin applications, with disastrous results.
|
||||
|
||||
Bitcoin's security relies on decentralized control over keys and on
|
||||
independent transaction validation by users. If you want to leverage
|
||||
Bitcoin's security, you need to ensure that you remain within the
|
||||
Bitcoin security model. In simple terms: don't take control of keys away
|
||||
from users and don't outsource validation.
|
||||
|
||||
For example, many early Bitcoin exchanges concentrated all user funds in
|
||||
a single "hot" wallet with keys stored on a single server. Such a design
|
||||
removes control from users and centralizes control over keys in a single
|
||||
system. Many such systems have been hacked, with disastrous consequences
|
||||
for their customers.
|
||||
|
||||
Unless you are prepared to invest heavily in operational security,
|
||||
multiple layers of access control, and audits (as the traditional banks
|
||||
do), you should think very carefully before taking funds outside of
|
||||
Bitcoin's decentralized security context. Even if you have the funds and
|
||||
discipline to implement a robust security model, such a design merely
|
||||
replicates the fragile model of traditional financial networks, plagued
|
||||
by identity theft, corruption, and embezzlement. To take advantage of
|
||||
Bitcoin's unique decentralized security model, you have to avoid the
|
||||
temptation of centralized architectures that might feel familiar but
|
||||
ultimately subvert Bitcoin's ((("decentralized consensus", "as security principle", secondary-sortas="security principle", startref="decentral-consensus-principle")))security.
|
||||
|
||||
==== The Root of Trust
|
||||
|
||||
Traditional ((("root of trust", id="root-trust")))security architecture is based
|
||||
upon a concept called the _root of trust_, which is a trusted core used
|
||||
as the foundation for the security of the overall system or application.
|
||||
Security architecture is developed around the root of trust as a series
|
||||
of concentric circles, like layers in an onion, extending trust outward
|
||||
from the center. Each layer builds upon the more-trusted inner layer
|
||||
using access controls, digital signatures, encryption, and other
|
||||
security primitives. As software systems become more complex, they are
|
||||
more likely to contain bugs, which make them vulnerable to security
|
||||
compromise. As a result, the more complex a software system becomes, the
|
||||
harder it is to secure. The root of trust concept ensures that most of
|
||||
the trust is placed within the least complex part of the system, and
|
||||
therefore the least vulnerable parts of the system, while more complex
|
||||
software is layered around it. This security architecture is repeated at
|
||||
different scales, first establishing a root of trust within the hardware
|
||||
of a single system, then extending that root of trust through the
|
||||
operating system to higher-level system services, and finally across
|
||||
many servers layered in concentric circles of diminishing trust.
|
||||
|
||||
Bitcoin security
|
||||
architecture is different. In Bitcoin, the consensus system creates a
|
||||
trusted blockchain that is completely decentralized. A correctly
|
||||
validated blockchain uses the genesis block as the root of trust,
|
||||
building a chain of trust up to the current block. Bitcoin systems can
|
||||
and should use the blockchain as their root of trust. When designing a
|
||||
complex Bitcoin application that consists of services on many different
|
||||
systems, you should carefully examine the security architecture in order
|
||||
to ascertain where trust is being placed. Ultimately, the only thing
|
||||
that should be explicitly trusted is a fully validated blockchain. If
|
||||
your application explicitly or implicitly vests trust in anything but
|
||||
the blockchain, that should be a source of concern because it introduces
|
||||
vulnerability. A good method to evaluate the security architecture of
|
||||
your application is to consider each individual component and evaluate a
|
||||
hypothetical scenario where that component is completely compromised and
|
||||
under the control of a malicious actor. Take each component of your
|
||||
application, in turn, and assess the impacts on the overall security if
|
||||
that component is compromised. If your application is no longer secure
|
||||
when components are compromised, that shows you have misplaced trust in
|
||||
those components. A Bitcoin application without vulnerabilities should
|
||||
be vulnerable only to a compromise of the Bitcoin consensus mechanism,
|
||||
meaning that its root of trust is based on the strongest part of the
|
||||
Bitcoin security architecture.
|
||||
|
||||
The numerous examples of hacked Bitcoin exchanges serve to underscore
|
||||
this point because their security architecture and design fails even
|
||||
under the most casual scrutiny. These centralized implementations had
|
||||
invested trust explicitly in numerous components outside the Bitcoin
|
||||
blockchain, such as hot wallets, centralized databases,
|
||||
vulnerable encryption keys, and ((("Bitcoin", "security", "principles of", startref="bitcoin-security-principle")))((("security", "principles of", startref="security-principle")))((("root of trust", startref="root-trust")))similar schemes.
|
||||
|
||||
=== User Security Best Practices
|
||||
|
||||
Humans ((("Bitcoin", "security", "best practices", id="bitcoin-security-best-practice")))((("security", "best practices", id="security-best-practice")))((("best practices, security", id="best-practice-security")))have
|
||||
used physical security controls for thousands of years. By comparison,
|
||||
our experience with digital security is less than 50 years old. Modern
|
||||
general-purpose operating systems are not very secure and not
|
||||
particularly suited to storing digital money. Our computers are
|
||||
constantly exposed to external threats via always-on internet
|
||||
connections. They run thousands of software components from hundreds of
|
||||
authors, often with unconstrained access to the user's files. A single
|
||||
piece of rogue software, among the many thousands installed on your
|
||||
computer, can compromise your keyboard and files, stealing any bitcoins
|
||||
stored in wallet applications. The level of computer maintenance
|
||||
required to keep a computer virus-free and trojan-free is beyond the
|
||||
skill level of all but a tiny minority of computer users.
|
||||
|
||||
Despite decades of research and advancements in information security,
|
||||
digital assets are still woefully vulnerable to a determined adversary.
|
||||
Even the most highly protected and restricted systems, in financial
|
||||
services companies, intelligence agencies, and defense contractors, are
|
||||
frequently breached. Bitcoin creates digital assets that have intrinsic
|
||||
value and can be stolen and diverted to new owners instantly and
|
||||
irrevocably. This creates a massive incentive for hackers. Until now,
|
||||
hackers had to convert identity information or account tokens—such as
|
||||
credit cards and bank accounts—into value after compromising them.
|
||||
Despite the difficulty of fencing and laundering financial information,
|
||||
we have seen ever-escalating thefts. Bitcoin escalates this problem
|
||||
because it doesn't need to be fenced or laundered; bitcoins are valuable
|
||||
by themselves.
|
||||
|
||||
Bitcoin also creates the incentives to improve computer
|
||||
security. Whereas previously the risk of computer compromise was vague
|
||||
and indirect, Bitcoin makes these risks clear and obvious. Holding
|
||||
bitcoins on a computer serves to focus the user's mind on the need for
|
||||
improved computer security. As a direct result of the proliferation and
|
||||
increased adoption of Bitcoin and other digital currencies, we have seen
|
||||
an escalation in both hacking techniques and security solutions. In
|
||||
simple terms, hackers now have a very juicy target and users have a
|
||||
clear incentive to defend themselves.
|
||||
|
||||
Over the past three years, as a direct result of Bitcoin adoption, we
|
||||
have seen tremendous innovation in the realm of information security in
|
||||
the form of hardware encryption, key storage and hardware signing devices,
|
||||
multisignature technology, and digital escrow. In the following sections
|
||||
we will examine various best practices for practical user security.
|
||||
|
||||
==== Physical Bitcoin Storage
|
||||
|
||||
Because most ((("bitcoins", "physical storage")))((("physical bitcoin storage")))((("storing bitcoins", id="storing-bitcoin")))users are far more
|
||||
comfortable with physical security than information security, a very
|
||||
effective method for protecting bitcoins is to convert them into physical
|
||||
form. Bitcoin keys, and the seeds used to create them, are nothing more than long numbers. This means that
|
||||
they can be stored in a physical form, such as printed on paper or
|
||||
etched on a metal plate. Securing the keys then becomes as simple as
|
||||
physically securing a printed copy of the key seed. A seed
|
||||
that is printed on paper is called a "paper backup," and
|
||||
many wallets can create them.
|
||||
Keeping bitcoins
|
||||
offline is ((("cold storage")))called _cold storage_ and it is one of the most effective
|
||||
security techniques. A cold storage system is one where the keys are
|
||||
generated on an offline system (one never connected to the internet) and
|
||||
stored offline either on paper or on digital media, such as a USB memory
|
||||
stick.
|
||||
|
||||
==== Hardware Signing Devices
|
||||
|
||||
In the ((("hardware signing devices")))long term, Bitcoin security may increasingly take the
|
||||
form of tamper-proof hardware signing devices. Unlike a smartphone or desktop
|
||||
computer, a Bitcoin hardware signing device only needs to hold keys and
|
||||
use them to generate signatures. Without general-purpose software to
|
||||
compromise and
|
||||
with limited interfaces, hardware signing devices can deliver strong
|
||||
security to nonexpert users. Hardware
|
||||
signing devices may become the predominant method of storing bitcoins.
|
||||
|
||||
==== Ensuring Your Access
|
||||
|
||||
Although
|
||||
most users ((("backing up", "importance of")))are rightly concerned about theft of their bitcoins, there is an even
|
||||
bigger risk. Data files get lost all the time. If they contain Bitcoin keys,
|
||||
the loss is much more painful. In the effort to secure their Bitcoin
|
||||
wallets, users must be very careful not to go too far and end up losing
|
||||
their bitcoins. In July 2011, a well-known Bitcoin awareness and education
|
||||
project lost almost 7,000 bitcoin. In their effort to prevent theft, the
|
||||
owners had implemented a complex series of encrypted backups. In the end
|
||||
they accidentally lost the encryption keys, making the backups worthless
|
||||
and losing a fortune. Like hiding money by burying it in the desert, if
|
||||
you secure your bitcoins too well you might not be able to find them again.
|
||||
|
||||
[WARNING]
|
||||
====
|
||||
To spend bitcoins, you may((("wallets", "recovery codes")))((("recovery codes"))) need to back up more than just your private
|
||||
keys or the BIP32 seed used to derive them. This is especially the case
|
||||
when multisignatures or complex scripts are being used. Most output
|
||||
scripts commit to the actual conditions that must be fulfilled to spend
|
||||
the bitcoins in that output, and it's not possible to fulfill that
|
||||
commitment unless your wallet software can reveal those conditions to
|
||||
the network. Wallet recovery codes must include this information. For
|
||||
more details, see <<ch05_wallets>>.
|
||||
====
|
||||
|
||||
==== Diversifying Risk
|
||||
|
||||
Would you((("risk diversification")))((("storing bitcoins", startref="storing-bitcoin"))) carry your entire net worth in cash in your wallet? Most
|
||||
people would consider that reckless, yet Bitcoin users often keep all
|
||||
their bitcoins using a single wallet application. Instead, users should spread the risk
|
||||
among multiple and diverse Bitcoin applications. Prudent users will keep only
|
||||
a small fraction, perhaps less than 5%, of their bitcoins in an online or
|
||||
mobile wallet as "pocket change." The rest should be split between a few
|
||||
different storage mechanisms, such as a desktop wallet and offline (cold
|
||||
storage).
|
||||
|
||||
==== Multisig and Governance
|
||||
|
||||
Whenever a ((("multisignature addresses")))((("addresses", "multisignature")))company or individual stores large amounts of
|
||||
bitcoins, they should consider using a multisignature Bitcoin address.
|
||||
Multisignature addresses secure funds by requiring more than one
|
||||
signature to make a payment. The signing keys should be stored in a
|
||||
number of different locations and under the control of different people.
|
||||
In a corporate environment, for example, the keys should be generated
|
||||
independently and held by several company executives to ensure that no
|
||||
single person can compromise the funds. Multisignature addresses can
|
||||
also offer redundancy, where a single person holds several keys that are
|
||||
stored in different locations.
|
||||
|
||||
|
||||
==== Survivability
|
||||
|
||||
One important
|
||||
security ((("survivability (of bitcoin access)")))((("estate planning")))consideration that is often overlooked is availability,
|
||||
especially in the context of incapacity or death of the key holder.
|
||||
Bitcoin users are told to use complex passwords and keep their keys
|
||||
secure and private, not sharing them with anyone. Unfortunately, that
|
||||
practice makes it almost impossible for the user's family to recover any
|
||||
funds if the user is not available to unlock them. In most cases, in
|
||||
fact, the families of Bitcoin users might be completely unaware of the
|
||||
existence of the bitcoin funds.
|
||||
|
||||
If you have a lot of bitcoins, you should consider sharing access details
|
||||
with a trusted relative or lawyer. A more complex survivability scheme
|
||||
can be set up with multisignature access and estate planning through a
|
||||
lawyer specialized as a "digital asset executor."
|
||||
|
||||
Bitcoin is a complex new technology that is still being explored by developers. Over
|
||||
time we will develop better security tools and practices that are easier
|
||||
to use by nonexperts. For now, Bitcoin users can use many of the tips
|
||||
discussed here to enjoy a secure and trouble-free Bitcoin ((("Bitcoin", "security", "best practices", startref="bitcoin-security-best-practice")))((("security", "best practices", startref="security-best-practice")))((("best practices, security", startref="best-practice-security")))experience.
|
@ -1,48 +0,0 @@
|
||||
#include <bitcoin/bitcoin.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Private secret key string as base16
|
||||
bc::ec_secret decoded;
|
||||
bc::decode_base16(decoded,
|
||||
"038109007313a5807b2eccc082c8c3fbb988a973cacf1a7df9ce725c31b14776");
|
||||
|
||||
bc::wallet::ec_private secret(
|
||||
decoded, bc::wallet::ec_private::mainnet_p2kh);
|
||||
|
||||
// Get public key.
|
||||
bc::wallet::ec_public public_key(secret);
|
||||
std::cout << "Public key: " << public_key.encoded() << std::endl;
|
||||
|
||||
// Create Bitcoin address.
|
||||
// Normally you can use:
|
||||
// bc::wallet::payment_address payaddr =
|
||||
// public_key.to_payment_address(
|
||||
// bc::wallet::ec_public::mainnet_p2kh);
|
||||
// const std::string address = payaddr.encoded();
|
||||
|
||||
// Compute hash of public key for P2PKH address.
|
||||
bc::data_chunk public_key_data;
|
||||
public_key.to_data(public_key_data);
|
||||
const auto hash = bc::bitcoin_short_hash(public_key_data);
|
||||
|
||||
bc::data_chunk unencoded_address;
|
||||
// Reserve 25 bytes
|
||||
// [ version:1 ]
|
||||
// [ hash:20 ]
|
||||
// [ checksum:4 ]
|
||||
unencoded_address.reserve(25);
|
||||
// Version byte, 0 is normal BTC address (P2PKH).
|
||||
unencoded_address.push_back(0);
|
||||
// Hash data
|
||||
bc::extend_data(unencoded_address, hash);
|
||||
// Checksum is computed by hashing data, and adding 4 bytes from hash.
|
||||
bc::append_checksum(unencoded_address);
|
||||
// Finally we must encode the result in Bitcoin's base58 encoding.
|
||||
assert(unencoded_address.size() == 25);
|
||||
const std::string address = bc::encode_base58(unencoded_address);
|
||||
|
||||
std::cout << "Address: " << address << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,43 +0,0 @@
|
||||
|
||||
# Convert mediawiki list of BIPs to asciidoc table for book appendix
|
||||
# Gnarly hack of regex with no error checking - it worked once
|
||||
|
||||
import re
|
||||
|
||||
regex_num = re.compile("\\|.\\[\\[bip-\\d+.mediawiki\\|(\\d+)\\]\\]")
|
||||
regex_altnum = re.compile("\\D+(\\d+)\\D+")
|
||||
|
||||
bips = []
|
||||
|
||||
f = open('README.mediawiki.txt', 'r')
|
||||
|
||||
line = f.readline()
|
||||
|
||||
while (line[0] != "|"):
|
||||
line = f.readline()
|
||||
|
||||
while (line[1] == '-'):
|
||||
line_num = f.readline()
|
||||
line_layer = f.readline()[2:-1]
|
||||
line_title = f.readline()[2:-1]
|
||||
line_owner = f.readline()[2:-1]
|
||||
line_type = f.readline()[2:-1]
|
||||
line_status = f.readline()[2:-1]
|
||||
line = f.readline()
|
||||
while (line[0] != "|"):
|
||||
line = f.readline()
|
||||
|
||||
num = regex_num.match(line_num)
|
||||
alt_num = regex_altnum.match(line_num)
|
||||
if num:
|
||||
bip_num = num.group(1)
|
||||
elif alt_num:
|
||||
bip_num = alt_num.group(1)
|
||||
|
||||
print("|[[bip-{0}]]https://github.com/bitcoin/bips/blob/master/bip-{0:04d}"
|
||||
".mediawiki[BIP-{0}] |{1} |{2} |{3} |{4} ".format(int(bip_num),
|
||||
line_title,
|
||||
line_owner,
|
||||
line_type,
|
||||
line_status))
|
||||
f.close()
|
@ -1,55 +0,0 @@
|
||||
import ecdsa
|
||||
import os
|
||||
|
||||
# secp256k1, http://www.oid-info.com/get/1.3.132.0.10
|
||||
_p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F
|
||||
_r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
|
||||
_b = 0x0000000000000000000000000000000000000000000000000000000000000007
|
||||
_a = 0x0000000000000000000000000000000000000000000000000000000000000000
|
||||
_Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798
|
||||
_Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8
|
||||
curve_secp256k1 = ecdsa.ellipticcurve.CurveFp(_p, _a, _b)
|
||||
generator_secp256k1 = ecdsa.ellipticcurve.Point(curve_secp256k1, _Gx, _Gy, _r)
|
||||
oid_secp256k1 = (1, 3, 132, 0, 10)
|
||||
SECP256k1 = ecdsa.curves.Curve("SECP256k1", curve_secp256k1,
|
||||
generator_secp256k1, oid_secp256k1)
|
||||
ec_order = _r
|
||||
|
||||
curve = curve_secp256k1
|
||||
generator = generator_secp256k1
|
||||
|
||||
|
||||
def random_secret():
|
||||
# Collect 256 bits of random data from the OS's cryptographically secure
|
||||
# random number generator
|
||||
byte_array = (os.urandom(32)).hex()
|
||||
|
||||
return int(byte_array,16)
|
||||
|
||||
def get_point_pubkey(point):
|
||||
if (point.y() % 2) == 1:
|
||||
key = '03' + '%064x' % point.x()
|
||||
else:
|
||||
key = '02' + '%064x' % point.x()
|
||||
return key
|
||||
|
||||
|
||||
def get_point_pubkey_uncompressed(point):
|
||||
key = ('04' +
|
||||
'%064x' % point.x() +
|
||||
'%064x' % point.y())
|
||||
return key
|
||||
|
||||
# Generate a new private key.
|
||||
secret = random_secret()
|
||||
print("Secret: ", secret)
|
||||
|
||||
# Get the public key point.
|
||||
point = secret * generator
|
||||
print("Elliptic Curve point:", point)
|
||||
|
||||
print("BTC public key:", get_point_pubkey(point))
|
||||
|
||||
# Given the point (x, y) we can create the object using:
|
||||
point1 = ecdsa.ellipticcurve.Point(curve, point.x(), point.y(), ec_order)
|
||||
assert(point1 == point)
|
@ -1,45 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/conformal/btcnet"
|
||||
"github.com/conformal/btcscript"
|
||||
)
|
||||
|
||||
// go run extract-from-pk-script.go
|
||||
|
||||
// This example demonstrates extracting information from a standard public key
|
||||
// script.
|
||||
|
||||
func main() {
|
||||
scriptHex := "76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac"
|
||||
|
||||
ExtractPkScriptAddrs(scriptHex)
|
||||
// Output:
|
||||
// Script Class: pubkeyhash
|
||||
// Addresses: [12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV]
|
||||
// Required Signatures: 1
|
||||
}
|
||||
|
||||
func ExtractPkScriptAddrs(scriptHex string) {
|
||||
script, err := hex.DecodeString(scriptHex)
|
||||
handle(err)
|
||||
|
||||
// Extract and print details from the script.
|
||||
scriptClass, addresses, reqSigs, err := btcscript.ExtractPkScriptAddrs(script, &btcnet.MainNetParams)
|
||||
handle(err)
|
||||
|
||||
fmt.Println("Script Class:", scriptClass)
|
||||
fmt.Println("Addresses:", addresses)
|
||||
fmt.Println("Required Signatures:", reqSigs)
|
||||
}
|
||||
|
||||
func handle(err error) {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
# get unspent outputs from blockchain API
|
||||
|
||||
import json
|
||||
import requests
|
||||
|
||||
# example address
|
||||
address = '1Dorian4RoXcnBv9hnQ4Y2C1an6NJ4UrjX'
|
||||
|
||||
# The API URL is https://blockchain.info/unspent?active=<address>
|
||||
# It returns a JSON object with a list "unspent_outputs", containing UTXO, like this:
|
||||
# { "unspent_outputs":[
|
||||
# {
|
||||
# "tx_hash":"ebadfaa92f1fd29e2fe296eda702c48bd11ffd52313e986e99ddad9084062167",
|
||||
# "tx_index":51919767,
|
||||
# "tx_output_n": 1,
|
||||
# "script":"76a9148c7e252f8d64b0b6e313985915110fcfefcf4a2d88ac",
|
||||
# "value": 8000000,
|
||||
# "value_hex": "7a1200",
|
||||
# "confirmations":28691
|
||||
# },
|
||||
# ...
|
||||
# ]}
|
||||
|
||||
resp = requests.get('https://blockchain.info/unspent?active=%s' % address)
|
||||
utxo_set = json.loads(resp.text)["unspent_outputs"]
|
||||
|
||||
for utxo in utxo_set:
|
||||
print("%s:%d - %ld Satoshis" % (utxo['tx_hash'], utxo['tx_output_n'],
|
||||
utxo['value']))
|
||||
# Or try...
|
||||
# print("{tx_hash}:{tx_output_n} - {value} Satoshis".format(**utxo))
|
@ -1,18 +0,0 @@
|
||||
# example of iterating a nonce in a hashing algorithm's input
|
||||
|
||||
from __future__ import print_function
|
||||
import hashlib
|
||||
|
||||
text = "I am Satoshi Nakamoto"
|
||||
|
||||
# iterate nonce from 0 to 19
|
||||
for nonce in range(20):
|
||||
|
||||
# add the nonce to the end of the text
|
||||
input_data = text + str(nonce)
|
||||
|
||||
# calculate the SHA-256 hash of the input (text+nonce)
|
||||
hash_data = hashlib.sha256(input_data.encode()).hexdigest()
|
||||
|
||||
# show the input and hash result
|
||||
print(input_data, '=>', hash_data)
|
@ -1,46 +0,0 @@
|
||||
from __future__ import print_function
|
||||
import cryptos
|
||||
|
||||
# Generate a random private key
|
||||
valid_private_key = False
|
||||
while not valid_private_key:
|
||||
private_key = cryptos.random_key()
|
||||
decoded_private_key = cryptos.decode_privkey(private_key, 'hex')
|
||||
valid_private_key = 0 < decoded_private_key < cryptos.N
|
||||
|
||||
print("Private Key (hex) is: ", private_key)
|
||||
print("Private Key (decimal) is: ", decoded_private_key)
|
||||
|
||||
# Convert private key to WIF format
|
||||
wif_encoded_private_key = cryptos.encode_privkey(decoded_private_key, 'wif')
|
||||
print("Private Key (WIF) is: ", wif_encoded_private_key)
|
||||
|
||||
# Add suffix "01" to indicate a compressed private key
|
||||
compressed_private_key = private_key + '01'
|
||||
print("Private Key Compressed (hex) is: ", compressed_private_key)
|
||||
|
||||
# Generate a WIF format from the compressed private key (WIF-compressed)
|
||||
wif_compressed_private_key = cryptos.encode_privkey(
|
||||
cryptos.decode_privkey(compressed_private_key, 'hex_compressed'), 'wif_compressed')
|
||||
print("Private Key (WIF-Compressed) is: ", wif_compressed_private_key)
|
||||
|
||||
# Multiply the EC generator point G with the private key to get a public key point
|
||||
public_key = cryptos.fast_multiply(cryptos.G, decoded_private_key)
|
||||
print("Public Key (x,y) coordinates is:", public_key)
|
||||
|
||||
# Encode as hex, prefix 04
|
||||
hex_encoded_public_key = cryptos.encode_pubkey(public_key, 'hex')
|
||||
print("Public Key (hex) is:", hex_encoded_public_key)
|
||||
|
||||
# Compress public key, adjust prefix depending on whether y is even or odd
|
||||
(public_key_x, public_key_y) = public_key
|
||||
compressed_prefix = '02' if (public_key_y % 2) == 0 else '03'
|
||||
hex_compressed_public_key = compressed_prefix + (cryptos.encode(public_key_x, 16).zfill(64))
|
||||
print("Compressed Public Key (hex) is:", hex_compressed_public_key)
|
||||
|
||||
# Generate Bitcoin address from public key
|
||||
print("Bitcoin Address (b58check) is:", cryptos.pubkey_to_address(public_key))
|
||||
|
||||
# Generate compressed Bitcoin address from compressed public key
|
||||
print("Compressed Bitcoin Address (b58check) is:",
|
||||
cryptos.pubkey_to_address(hex_compressed_public_key))
|
@ -1,62 +0,0 @@
|
||||
#include <bitcoin/bitcoin.hpp>
|
||||
|
||||
bc::hash_digest create_merkle(bc::hash_list& merkle)
|
||||
{
|
||||
// Stop if hash list is empty.
|
||||
if (merkle.empty())
|
||||
return bc::null_hash;
|
||||
else if (merkle.size() == 1)
|
||||
return merkle[0];
|
||||
|
||||
// While there is more than 1 hash in the list, keep looping...
|
||||
while (merkle.size() > 1)
|
||||
{
|
||||
// If number of hashes is odd, duplicate last hash in the list.
|
||||
if (merkle.size() % 2 != 0)
|
||||
merkle.push_back(merkle.back());
|
||||
// List size is now even.
|
||||
assert(merkle.size() % 2 == 0);
|
||||
|
||||
// New hash list.
|
||||
bc::hash_list new_merkle;
|
||||
// Loop through hashes 2 at a time.
|
||||
for (auto it = merkle.begin(); it != merkle.end(); it += 2)
|
||||
{
|
||||
// Join both current hashes together (concatenate).
|
||||
bc::data_chunk concat_data(bc::hash_size * 2);
|
||||
auto concat = bc::serializer<
|
||||
decltype(concat_data.begin())>(concat_data.begin());
|
||||
concat.write_hash(*it);
|
||||
concat.write_hash(*(it + 1));
|
||||
// Hash both of the hashes.
|
||||
bc::hash_digest new_root = bc::bitcoin_hash(concat_data);
|
||||
// Add this to the new list.
|
||||
new_merkle.push_back(new_root);
|
||||
}
|
||||
// This is the new list.
|
||||
merkle = new_merkle;
|
||||
|
||||
// DEBUG output -------------------------------------
|
||||
std::cout << "Current merkle hash list:" << std::endl;
|
||||
for (const auto& hash: merkle)
|
||||
std::cout << " " << bc::encode_base16(hash) << std::endl;
|
||||
std::cout << std::endl;
|
||||
// --------------------------------------------------
|
||||
}
|
||||
// Finally we end up with a single item.
|
||||
return merkle[0];
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Replace these hashes with ones from a block to reproduce the same merkle root.
|
||||
bc::hash_list tx_hashes{{
|
||||
bc::hash_literal("0000000000000000000000000000000000000000000000000000000000000000"),
|
||||
bc::hash_literal("0000000000000000000000000000000000000000000000000000000000000011"),
|
||||
bc::hash_literal("0000000000000000000000000000000000000000000000000000000000000022"),
|
||||
}};
|
||||
const bc::hash_digest merkle_root = create_merkle(tx_hashes);
|
||||
std::cout << "Result: " << bc::encode_base16(merkle_root) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
var btc = require('bitcore-lib')
|
||||
var oldAddress = btc.Address.fromString("1Ek9S3QNnutPV7GhtzR8Lr8yKPhxnUP8iw") // here's the old address
|
||||
var oldHash = oldAddress.hashBuffer
|
||||
var segwitP2PKH = Buffer.concat([new Buffer("0014","hex"), oldHash]) // 0x00 + 0x14 (pushdata 20 bytes) + old pubkeyhash
|
||||
var p2shHash = btc.crypto.Hash.sha256ripemd160(segwitP2PKH)
|
||||
var p2shAddress = btc.Address.fromScriptHash(p2shHash)
|
||||
var newAddress = p2shAddress.toString()
|
||||
// 36ghjA1KSAB1jDYD2RdiexEcY7r6XjmDQk
|
@ -1,48 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/conformal/btcnet"
|
||||
"github.com/conformal/btcscript"
|
||||
"github.com/conformal/btcutil"
|
||||
)
|
||||
|
||||
// This example demonstrates creating a script which pays to a Bitcoin address.
|
||||
// It also prints the created script hex and uses the DisasmString function to
|
||||
// display the disassembled script.
|
||||
|
||||
func main() {
|
||||
addressStr := "12gpXQVcCL2qhTNQgyLVdCFG2Qs2px98nV"
|
||||
|
||||
PayToAddrScript(addressStr)
|
||||
// Output:
|
||||
// Script Hex: 76a914128004ff2fcaf13b2b91eb654b1dc2b674f7ec6188ac
|
||||
// Script Disassembly: OP_DUP OP_HASH160 128004ff2fcaf13b2b91eb654b1dc2b674f7ec61 OP_EQUALVERIFY OP_CHECKSIG
|
||||
}
|
||||
|
||||
func PayToAddrScript(addressStr string) {
|
||||
// Parse the address to send the coins to into a btcutil.Address
|
||||
// which is useful to ensure the accuracy of the address and determine
|
||||
// the address type. It is also required for the upcoming call to
|
||||
// PayToAddrScript.
|
||||
address, err := btcutil.DecodeAddress(addressStr, &btcnet.MainNetParams)
|
||||
handle(err)
|
||||
|
||||
// Create a public key script that pays to the address.
|
||||
script, err := btcscript.PayToAddrScript(address)
|
||||
handle(err)
|
||||
fmt.Printf("Script Hex: %x\n", script)
|
||||
|
||||
disasm, err := btcscript.DisasmString(script)
|
||||
handle(err)
|
||||
fmt.Println("Script Disassembly:", disasm)
|
||||
}
|
||||
|
||||
func handle(err error) {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# example of proof-of-work algorithm
|
||||
|
||||
import hashlib
|
||||
import time
|
||||
|
||||
try:
|
||||
long # Python 2
|
||||
xrange
|
||||
except NameError:
|
||||
long = int # Python 3
|
||||
xrange = range
|
||||
|
||||
max_nonce = 2 ** 32 # 4 billion
|
||||
|
||||
|
||||
def proof_of_work(header, difficulty_bits):
|
||||
# calculate the difficulty target
|
||||
target = 2 ** (256 - difficulty_bits)
|
||||
|
||||
for nonce in xrange(max_nonce):
|
||||
hash_result = hashlib.sha256((str(header) + str(nonce)).encode()).hexdigest()
|
||||
|
||||
# check if this is a valid result, equal to or below the target
|
||||
if long(hash_result, 16) <= target:
|
||||
print("Success with nonce %d" % nonce)
|
||||
print("Hash is %s" % hash_result)
|
||||
return (hash_result, nonce)
|
||||
|
||||
print("Failed after %d (max_nonce) tries" % nonce)
|
||||
return nonce
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
nonce = 0
|
||||
hash_result = ''
|
||||
|
||||
# difficulty from 0 to 31 bits
|
||||
for difficulty_bits in xrange(32):
|
||||
difficulty = 2 ** difficulty_bits
|
||||
print("Difficulty: %ld (%d bits)" % (difficulty, difficulty_bits))
|
||||
print("Starting search...")
|
||||
|
||||
# checkpoint the current time
|
||||
start_time = time.time()
|
||||
|
||||
# make a new block which includes the hash from the previous block
|
||||
# we fake a block of transactions - just a string
|
||||
new_block = 'test block with transactions' + hash_result
|
||||
|
||||
# find a valid nonce for the new block
|
||||
(hash_result, nonce) = proof_of_work(new_block, difficulty_bits)
|
||||
|
||||
# checkpoint how long it took to find a result
|
||||
end_time = time.time()
|
||||
|
||||
elapsed_time = end_time - start_time
|
||||
print("Elapsed Time: %.4f seconds" % elapsed_time)
|
||||
|
||||
if elapsed_time > 0:
|
||||
|
||||
# estimate the hashes per second
|
||||
hash_power = float(long(nonce) / elapsed_time)
|
||||
print("Hashing Power: %ld hashes per second" % hash_power)
|
@ -1,44 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from pycoin.key import Key
|
||||
|
||||
from pycoin.key.validate import is_address_valid, is_wif_valid
|
||||
from pycoin.services import spendables_for_address
|
||||
from pycoin.tx.tx_utils import create_signed_tx
|
||||
|
||||
|
||||
def get_address(which):
|
||||
while 1:
|
||||
print("enter the %s address=> " % which, end='')
|
||||
address = input()
|
||||
is_valid = is_address_valid(address)
|
||||
if is_valid:
|
||||
return address
|
||||
print("invalid address, please try again")
|
||||
|
||||
|
||||
src_address = get_address("source")
|
||||
spendables = spendables_for_address(src_address)
|
||||
print(spendables)
|
||||
|
||||
while 1:
|
||||
print("enter the WIF for %s=> " % src_address, end='')
|
||||
wif = input()
|
||||
is_valid = is_wif_valid(wif)
|
||||
if is_valid:
|
||||
break
|
||||
print("invalid wif, please try again")
|
||||
|
||||
key = Key.from_text(wif)
|
||||
if src_address not in (key.address(use_uncompressed=False), key.address(use_uncompressed=True)):
|
||||
print("** WIF doesn't correspond to %s" % src_address)
|
||||
print("The secret exponent is %d" % key.secret_exponent())
|
||||
|
||||
dst_address = get_address("destination")
|
||||
|
||||
tx = create_signed_tx(spendables, payables=[dst_address], wifs=[wif])
|
||||
|
||||
print("here is the signed output transaction")
|
||||
print(tx.as_hex())
|
@ -1,26 +0,0 @@
|
||||
/*
|
||||
Display the genesis block message by Satoshi.
|
||||
*/
|
||||
#include <iostream>
|
||||
#include <bitcoin/bitcoin.hpp>
|
||||
|
||||
int main()
|
||||
{
|
||||
// Create genesis block.
|
||||
bc::chain::block block = bc::chain::block::genesis_mainnet();
|
||||
// Genesis block contains a single coinbase transaction.
|
||||
assert(block.transactions().size() == 1);
|
||||
// Get first transaction in block (coinbase).
|
||||
const bc::chain::transaction& coinbase_tx = block.transactions()[0];
|
||||
// Coinbase tx has a single input.
|
||||
assert(coinbase_tx.inputs().size() == 1);
|
||||
const bc::chain::input& coinbase_input = coinbase_tx.inputs()[0];
|
||||
// Convert the input script to its raw format.
|
||||
const auto prefix = false;
|
||||
const bc::data_chunk& raw_message = coinbase_input.script().to_data(prefix);
|
||||
// Convert this to a std::string.
|
||||
std::string message(raw_message.begin(), raw_message.end());
|
||||
// Display the genesis block message.
|
||||
std::cout << message << std::endl;
|
||||
return 0;
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
# Selects outputs from a UTXO list using a greedy algorithm.
|
||||
|
||||
from sys import argv
|
||||
|
||||
try:
|
||||
long # Python 2
|
||||
except NameError:
|
||||
long = int # Python 3
|
||||
|
||||
|
||||
class OutputInfo:
|
||||
def __init__(self, tx_hash, tx_index, value):
|
||||
self.tx_hash = tx_hash
|
||||
self.tx_index = tx_index
|
||||
self.value = value
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s:%s with %s Satoshis>" % (self.tx_hash, self.tx_index,
|
||||
self.value)
|
||||
|
||||
|
||||
# Select optimal outputs for a send from unspent outputs list.
|
||||
# Returns output list and remaining change to be sent to
|
||||
# a change address.
|
||||
def select_outputs_greedy(unspent, min_value):
|
||||
# Fail if empty.
|
||||
if not unspent:
|
||||
return None
|
||||
# Partition into 2 lists.
|
||||
lessers = [utxo for utxo in unspent if utxo.value < min_value]
|
||||
greaters = [utxo for utxo in unspent if utxo.value >= min_value]
|
||||
key_func = lambda utxo: utxo.value
|
||||
if greaters:
|
||||
# Not-empty. Find the smallest greater.
|
||||
min_greater = min(greaters, key=key_func)
|
||||
change = min_greater.value - min_value
|
||||
return [min_greater], "Change: %d Satoshis" % change
|
||||
# Not found in greaters. Try several lessers instead.
|
||||
# Rearrange them from biggest to smallest. We want to use the least
|
||||
# amount of inputs as possible.
|
||||
lessers.sort(key=key_func, reverse=True)
|
||||
result = []
|
||||
accum = 0
|
||||
for utxo in lessers:
|
||||
result.append(utxo)
|
||||
accum += utxo.value
|
||||
if accum >= min_value:
|
||||
change = accum - min_value
|
||||
return result, "Change: %d Satoshis" % change
|
||||
# No results found.
|
||||
return None, 0
|
||||
|
||||
|
||||
def main():
|
||||
unspent = [
|
||||
OutputInfo("ebadfaa92f1fd29e2fe296eda702c48bd11ffd52313e986e99ddad9084062167", 1, 8000000),
|
||||
OutputInfo("6596fd070679de96e405d52b51b8e1d644029108ec4cbfe451454486796a1ecf", 0, 16050000),
|
||||
OutputInfo("b2affea89ff82557c60d635a2a3137b8f88f12ecec85082f7d0a1f82ee203ac4", 0, 10000000),
|
||||
OutputInfo("7dbc497969c7475e45d952c4a872e213fb15d45e5cd3473c386a71a1b0c136a1", 0, 25000000),
|
||||
OutputInfo("55ea01bd7e9afd3d3ab9790199e777d62a0709cf0725e80a7350fdb22d7b8ec6", 17, 5470541),
|
||||
OutputInfo("12b6a7934c1df821945ee9ee3b3326d07ca7a65fd6416ea44ce8c3db0c078c64", 0, 10000000),
|
||||
OutputInfo("7f42eda67921ee92eae5f79bd37c68c9cb859b899ce70dba68c48338857b7818", 0, 16100000),
|
||||
]
|
||||
target = long(argv[1]) if len(argv) > 1 else 55000000
|
||||
print("For transaction amount %d Satoshis (%f bitcoin) use: " %
|
||||
(target, target / 10.0 ** 8))
|
||||
print(select_outputs_greedy(unspent, target))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -1,73 +0,0 @@
|
||||
#include <random>
|
||||
#include <bitcoin/bitcoin.hpp>
|
||||
|
||||
// The string we are searching for
|
||||
const std::string search = "1kid";
|
||||
|
||||
// Generate a random secret key. A random 32 bytes.
|
||||
bc::ec_secret random_secret(std::default_random_engine& engine);
|
||||
// Extract the Bitcoin address from an EC secret.
|
||||
std::string bitcoin_address(const bc::ec_secret& secret);
|
||||
// Case insensitive comparison with the search string.
|
||||
bool match_found(const std::string& address);
|
||||
|
||||
int main()
|
||||
{
|
||||
// random_device on Linux uses "/dev/urandom"
|
||||
// CAUTION: Depending on implementation this RNG may not be secure enough!
|
||||
// Do not use vanity keys generated by this example in production
|
||||
std::random_device random;
|
||||
std::default_random_engine engine(random());
|
||||
|
||||
// Loop continuously...
|
||||
while (true)
|
||||
{
|
||||
// Generate a random secret.
|
||||
bc::ec_secret secret = random_secret(engine);
|
||||
// Get the address.
|
||||
std::string address = bitcoin_address(secret);
|
||||
// Does it match our search string? (1kid)
|
||||
if (match_found(address))
|
||||
{
|
||||
// Success!
|
||||
std::cout << "Found vanity address! " << address << std::endl;
|
||||
std::cout << "Secret: " << bc::encode_base16(secret) << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// Should never reach here!
|
||||
return 0;
|
||||
}
|
||||
|
||||
bc::ec_secret random_secret(std::default_random_engine& engine)
|
||||
{
|
||||
// Create new secret...
|
||||
bc::ec_secret secret;
|
||||
// Iterate through every byte setting a random value...
|
||||
for (uint8_t& byte: secret)
|
||||
byte = engine() & 255;
|
||||
// Return result.
|
||||
return secret;
|
||||
}
|
||||
|
||||
std::string bitcoin_address(const bc::ec_secret& secret)
|
||||
{
|
||||
// Convert secret to payment address
|
||||
bc::wallet::ec_private private_key(secret);
|
||||
bc::wallet::payment_address payaddr(private_key);
|
||||
// Return encoded form.
|
||||
return payaddr.encoded();
|
||||
}
|
||||
|
||||
bool match_found(const std::string& address)
|
||||
{
|
||||
auto addr_it = address.begin();
|
||||
// Loop through the search string comparing it to the lower case
|
||||
// character of the supplied address.
|
||||
for (auto it = search.begin(); it != search.end(); ++it, ++addr_it)
|
||||
if (*it != std::tolower(*addr_it))
|
||||
return false;
|
||||
// Reached end of search string, so address matches.
|
||||
return true;
|
||||
}
|
||||
|
@ -1,86 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/conformal/btcrpcclient"
|
||||
"github.com/conformal/btcutil"
|
||||
"github.com/conformal/btcwire"
|
||||
)
|
||||
|
||||
// This example demonstrates a connection to the Bitcoin network
|
||||
// by using websockets via btcd, use of notifications and an rpc
|
||||
// call to getblockcount.
|
||||
//
|
||||
// Install and run btcd:
|
||||
// $ go get github.com/conformal/btcd/...
|
||||
// $ btcd -u rpcuser -P rpcpass
|
||||
//
|
||||
// Install btcrpcclient:
|
||||
// $ go get github.com/conformal/btcrpcclient
|
||||
//
|
||||
// Run this example:
|
||||
// $ go run websocket-example.go
|
||||
//
|
||||
func main() {
|
||||
// Only override the handlers for notifications you care about.
|
||||
// Also note most of these handlers will only be called if you register
|
||||
// for notifications. See the documentation of the btcrpcclient
|
||||
// NotificationHandlers type for more details about each handler.
|
||||
ntfnHandlers := btcrpcclient.NotificationHandlers{
|
||||
OnBlockConnected: func(hash *btcwire.ShaHash, height int32) {
|
||||
log.Printf("Block connected: %v (%d)", hash, height)
|
||||
},
|
||||
OnBlockDisconnected: func(hash *btcwire.ShaHash, height int32) {
|
||||
log.Printf("Block disconnected: %v (%d)", hash, height)
|
||||
},
|
||||
}
|
||||
|
||||
// Connect to local btcd RPC server using websockets.
|
||||
btcdHomeDir := btcutil.AppDataDir("btcd", false)
|
||||
certs, err := ioutil.ReadFile(filepath.Join(btcdHomeDir, "rpc.cert"))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
connCfg := &btcrpcclient.ConnConfig{
|
||||
Host: "localhost:8334",
|
||||
Endpoint: "ws",
|
||||
User: "rpcuser",
|
||||
Pass: "rpcpass",
|
||||
Certificates: certs,
|
||||
}
|
||||
client, err := btcrpcclient.New(connCfg, &ntfnHandlers)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Register for block connect and disconnect notifications.
|
||||
if err := client.NotifyBlocks(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Println("NotifyBlocks: Registration Complete")
|
||||
|
||||
// Get the current block count.
|
||||
blockCount, err := client.GetBlockCount()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("Block count: %d", blockCount)
|
||||
|
||||
// For this example gracefully shutdown the client after 10 seconds.
|
||||
// Ordinarily when to shutdown the client is highly application
|
||||
// specific.
|
||||
log.Println("Client shutdown in 10 seconds...")
|
||||
time.AfterFunc(time.Second*10, func() {
|
||||
log.Println("Client shutting down...")
|
||||
client.Shutdown()
|
||||
log.Println("Client shutdown complete.")
|
||||
})
|
||||
|
||||
// Wait until the client either shuts down gracefully (or the user
|
||||
// terminates the process with Ctrl+C).
|
||||
client.WaitForShutdown()
|
||||
}
|
@ -1,3 +1,3 @@
|
||||
<figure data-type="cover">
|
||||
<img src="images/cover.png"/>
|
||||
</figure>
|
||||
</figure>
|
||||
|
@ -1,7 +1,15 @@
|
||||
<section data-type="dedication" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<section data-type="dedication" xmlns="http://www.w3.org/1999/xhtml" >
|
||||
|
||||
<p>Dedicated to my mum, Theresa (1946–2017)</p>
|
||||
<p>She taught me to love books and question authority</p>
|
||||
<p>Thank you, mum</p>
|
||||
<p data-type="attribution">—Andreas</p>
|
||||
<br/><br/><br/><br/><br/>
|
||||
|
||||
<p>For Amanda</p>
|
||||
<p>It wasn't until I met you that I</p>
|
||||
<p>actually began living in paradise</p>
|
||||
|
||||
|
||||
<p data-type="attribution">—Dave</p>
|
||||
</section>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 2.3 MiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 158 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.8 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 73 KiB |
After Width: | Height: | Size: 118 KiB |
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
Before Width: | Height: | Size: 458 KiB After Width: | Height: | Size: 458 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 93 KiB |
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 53 KiB |