From 61a9711deb1947f8bd3d05987e4c4f1d104849ab Mon Sep 17 00:00:00 2001 From: Kristov Atlas Date: Fri, 12 Jun 2015 17:31:23 -0400 Subject: [PATCH 01/28] Added BIP 79 Lexicographical Indexing of Transaction Inputs and Outputs --- README.mediawiki | 6 ++ bip-0079.mediawiki | 129 ++++++++++++++++++++++++++++++++++ bip-0079/bip-0079_examples.py | 112 +++++++++++++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 bip-0079.mediawiki create mode 100644 bip-0079/bip-0079_examples.py diff --git a/README.mediawiki b/README.mediawiki index 56f15d53..a758f1a8 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -277,6 +277,12 @@ Those proposing changes should consider that ultimately consent may rest with th | Stephen Pair | Standard | Draft +|- +| [[bip-0079.mediawiki|79]] +| Lexicographical Indexing of Transaction Inputs and Outputs +| Kristov Atlas +| Standard +| Draft |} diff --git a/bip-0079.mediawiki b/bip-0079.mediawiki new file mode 100644 index 00000000..65e35e6b --- /dev/null +++ b/bip-0079.mediawiki @@ -0,0 +1,129 @@ +
+  BIP:     BIP: 79
+  Title:   Lexicographical Indexing of Transaction Inputs and Outputs
+  Authors: Kristov Atlas 
+  Status:  Draft
+  Type:    Informational
+  Created: 2015-06-12
+
+ +==Abstract== + +Currently there is no standard for bitcoin wallet clients when ordering transaction inputs and outputs. As a result, wallet clients often have a discernible blockchain fingerprint, and can leak private information about their users. By contrast, a standard for non-deterministic sorting could be difficult to audit. This document proposes deterministic lexicographical sorting, using hashes of previous transactions and output indices to sort transaction inputs, as well as values and scriptPubKeys to sort transaction outputs. + +==Copyright== + +This BIP is in the public domain. + +==Motivation== + +Currently, there is no clear standard for how wallet clients ought to order transaction inputs and outputs. Since wallet clients are left to their own devices to determine this ordering, they often leak information about their users’ finances. For example, a wallet client might naively order inputs based on when addresses were added to a wallet by the user through importing or random generation. Many wallets will place spending outputs first and change outputs second, leaking information about both the sender and receiver’s finances to passive blockchain observers. Such information should remain private not only for the benefit of consumers, but in higher order financial systems must be kept secret to prevent fraud. A researcher recently demonstrated this principle when he detected that Bitstamp leaked information when creating exchange transactions, enabling potential espionage among traders. [1] + +One way to address these privacy weaknesses is by randomly ordering inputs and outputs. [2] After all, the order of inputs and outputs does not impact the function of the transaction they belong to, making random sorting viable. Unfortunately, it can be difficult to prove that this sorting process is genuinely randomly sorted based on code or run-time analysis, especially if the software is closed source. A malicious software developer can abuse the ordering of inputs and outputs as a side channel of leaking information. For example, if an attacker can patch a victim’s HD wallet client to order inputs and outputs based on the bits of a master private key, then the attacker can eventually steal all of the victim’s funds by monitoring the blockchain. Non-deterministic methods of sorting are difficult to audit because they are not repeatable. + +The lack of standardization between wallet clients when ordering inputs and outputs can yield predictable quirks that characterize particular wallet clients or services. Such quirks create unique fingerprints that a privacy attacker can employ through simple passive blockchain observation. + +The solution is to create an algorithm for sorting transaction inputs and outputs that is deterministic. Since it is deterministic, it should also be unambiguous — that is, given a particular transaction, the proper order of inputs and outputs should be obvious. To make this standard as widely applicable as possible, it should rely on information that is downloaded by both full nodes (with or without typical efficiency techniques such as pruning) and SPV nodes. In order to ensure that it does not leak confidential data, it must rely on information that is publicly accessible through the blockchain. The use of public blockchain information also allows a transaction to be sorted even when it is a multi-party transaction, such as in the example of a CoinJoin. + +==Specification== + +===Applicability=== + +This BIP applies to any transaction for which the order of its inputs and outputs does not impact the transaction’s function. Currently, this refers to any transaction that employs the SIGHASH_ALL signature hash type, in which signatures commit to the exact order of inputs and outputs. Transactions that use SIGHASH_ANYONECANPAY and/or SIGHASH_NONE may include inputs and/or outputs that are not signed; however, compliant software should still emit transactions with lexicographically sorted inputs and outputs, even though they may later be modified by others. + +In the event that future protocol upgrades introduce new signature hash types, compliant software should apply the lexicographical ordering principle analogously. + +While out of scope of this BIP, protocols that do require a specified order of inputs/outputs (e.g. due to use of SIGHASH_SINGLE) should consider the goals of this BIP and how best to adapt them to the specific needs of those protocols. + +===Lexicographical Sorting=== + +Ordering of inputs and outputs will rely on the output of sorting functions. These functions can be defined as taking two inputs or two outputs as parameters and returning their appropriate ordering with respect to each other. + +Byte arrays must be sorted with an algorithm that produces the same output as the following comparison algorithm: + + #returns -1 if barr1 is lesser, 1 if barr1 is greater, and 0 if equal + def bytearr_cmp(barr1, barr2): + pos = 0 + while (pos < len(barr1) and pos < len(barr2)): + if (barr1[pos] < barr2[pos]): + return -1; + elif (barr1[pos] > barr2[pos]): + return 1; + pos = pos + 1 + #the shorter array will be ordered first + if (len(barr1) < len(barr2)): + return -1 + elif (len(barr1) > len(barr2)): + return 1 + else: + return 0 + +N.B. These comparisons do not need to operate in constant time since they are not processing secret information. + +===Transaction Inputs=== + +104 Transaction inputs are defined by the hash of a previous transaction, the output index of of a UTXO from that previous transaction, the size of an unlocking script, the unlocking script, and a sequence number. [3] For sorting inputs, the hash of the previous transaction and the output index within that transaction are sufficient for sorting purposes; each transaction hash has an extremely high probability of being unique in the blockchain — this is enforced for coinbase transactions by BIP30 — and output indices within a transaction are unique. For the sake of efficiency, transaction hashes should be compared first before output indices, since output indices from different transactions are often equivalent, while all bytes of the transaction hash are effectively random variables. + +Hashes of previous transactions are considered for the purposes of this BIP in their little-endian, byte array format in order to match the traditional, human-readable string representation of the hashes. They must be sorted in accordance with the output of the bytearr_cmp() function above: the hash with the earliest lesser byte is ordered first, and shorter hashes are ordered before longer ones as a tie-breaker. In the event of two matching transaction hashes, output indices will be compared based on their integer value, with the smaller value ordered first. A further tie is extremely improbable for the aforementioned reasons. + +Because the hash of previous transactions and output indices must be included in a signed transaction, wallet clients capable of signing transactions will necessarily have access to this data. + +Transaction malleability will not negatively impact the correctness of this process. Even if a wallet client follows this process using unconfirmed UTXOs as inputs and an attacker changes modifies the blockchain’s record of the hash of the previous transaction, the wallet client will include the invalidated previous transaction hash in its input data, and will still correctly sort with respect to that invalidated hash. + +===Transaction Outputs=== + +A transaction output is defined by its scriptPubKey and amount. [3] For sorting purposes, we will consider a scriptPubKey in its byte array representation, and a bitcoin amount in terms of their integer number of satoshis (smallest amount ordered first). + +For the sake of efficiency, amounts will be considered first for sorting, since they contain fewer bytes of information (8 bytes) compared to a standard P2PKH scriptPubKey (25 bytes). [4] When the values are tied, the scriptPubKey is then considered. In the event of a tie between scriptPubKeys, sorting is irrelevant since the outputs are exactly equivalent. + +===Examples=== + +Transaction 0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3: + +Inputs: + + 0: 0e53ec5dfb2cb8a71fec32dc9a634a35b7e24799295ddd5278217822e0b31f57[0] + 1: 26aa6e6d8b9e49bb0630aac301db6757c02e3619feb4ee0eea81eb1672947024[1] + 2: 28e0fdd185542f2c6ea19030b0796051e7772b6026dd5ddccd7a2f93b73e6fc2[0] + 3: 381de9b9ae1a94d9c17f6a08ef9d341a5ce29e2e60c36a52d333ff6203e58d5d[1] + 4: 3b8b2f8efceb60ba78ca8bba206a137f14cb5ea4035e761ee204302d46b98de2[0] + 5: 402b2c02411720bf409eff60d05adad684f135838962823f3614cc657dd7bc0a[1] + 6: 54ffff182965ed0957dba1239c27164ace5a73c9b62a660c74b7b7f15ff61e7a[1] + 7: 643e5f4e66373a57251fb173151e838ccd27d279aca882997e005016bb53d5aa[0] + 8: 6c1d56f31b2de4bfc6aaea28396b333102b1f600da9c6d6149e96ca43f1102b1[1] + 9: 7a1de137cbafb5c70405455c49c5104ca3057a1f1243e6563bb9245c9c88c191[0] + 10: 7d037ceb2ee0dc03e82f17be7935d238b35d1deabf953a892a4507bfbeeb3ba4[1] + 11: a5e899dddb28776ea9ddac0a502316d53a4a3fca607c72f66c470e0412e34086[0] + 12: b4112b8f900a7ca0c8b0e7c4dfad35c6be5f6be46b3458974988e1cdb2fa61b8[0] + 13: bafd65e3c7f3f9fdfdc1ddb026131b278c3be1af90a4a6ffa78c4658f9ec0c85[0] + 14: de0411a1e97484a2804ff1dbde260ac19de841bebad1880c782941aca883b4e9[1] + 15: f0a130a84912d03c1d284974f563c5949ac13f8342b8112edff52971599e6a45[0] + 16: f320832a9d2e2452af63154bc687493484a0e7745ebd3aaf9ca19eb80834ad60[0] + +Outputs: + + 0: 400057456 76a9144a5fba237213a062f6f57978f796390bdcf8d01588ac + 1: 40000000000 76a9145be32612930b8323add2212a4ec03c1562084f8488ac + +Transaction 28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f + +Inputs: + + 0: 35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055[0] + 1: 35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055[1] + +Outputs: + + 0: 100000000 41046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac + 1: 2400000000 41044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac + +==References== + +* [[https://bitcoinmagazine.com/20273/bitstamp-exchange-activity-trackable-due-multisig-wallet-implementation/|1: Bitstamp Info Leak]] +* [[https://github.com/OpenBitcoinPrivacyProject/wallet-ratings/blob/master/2015-1/criteria.md|2: OBPP Random Indexing as Countermeasure]] +* [[https://github.com/aantonop/bitcoinbook/blob/develop/ch05.asciidoc|3: Mastering Bitcoin]] +* [[https://en.bitcoin.it/wiki/Script|4: Bitcoin Wiki on Script]] + +==Acknowledgements== + +Danno Ferrin <danno@numisight.com>, Sergio Demian Lerner <sergiolerner@certimix.com>, Justus Ranvier <justus@openbitcoinprivacyproject.org>, and Peter Todd <pete@petertodd.org> contributed to the design and motivations for this BIP. \ No newline at end of file diff --git a/bip-0079/bip-0079_examples.py b/bip-0079/bip-0079_examples.py new file mode 100644 index 00000000..7622cfe9 --- /dev/null +++ b/bip-0079/bip-0079_examples.py @@ -0,0 +1,112 @@ +import binascii + +#returns -1 if barr1 is less, 1 if barr1 is greater, and 0 if equal +def bytearr_cmp(barr1, barr2): + pos = 0 + while (pos < len(barr1) and pos < len(barr2)): + if (barr1[pos] < barr2[pos]): + return -1; + elif (barr1[pos] > barr2[pos]): + return 1; + pos = pos + 1 + #the shorter array will be ordered first + if (len(barr1) < len(barr2)): + return -1 + elif (len(barr1) > len(barr2)): + return 1 + else: + return 0 + +#tuples: (prev_tx_hash_byte_arr_little_endian, prev_tx_output_index) +def input_cmp(input_tuple1, input_tuple2): + #test prev_tx_hash_byte_arr_little_endian first + prev_tx_hash_cmp = bytearr_cmp(input_tuple1[0], input_tuple2[0]) + if (prev_tx_hash_cmp != 0): + return prev_tx_hash_cmp + #tie-breaker: prev_tx_output_index + if (input_tuple1[1] < input_tuple2[1]): + return -1 + elif (input_tuple1[1] > input_tuple2[1]): + return 1 + else: + raise ValueError('Matching previous transaction hash and previous transaction output index for two disinct inputs. Invalid!') + +def sort_inputs(input_tuples): + return sorted(input_tuples, cmp=input_cmp) + +def print_inputs(ordered_input_tuples): + index = 0 + for prev_tx_hash_byte_arr_little_endian, prev_tx_output_index in ordered_input_tuples: + prev_tx_hash_hex = binascii.hexlify(bytearray(prev_tx_hash_byte_arr_little_endian)) + print("%d: %s[%d]" % (index, prev_tx_hash_hex, prev_tx_output_index)) + index = index + 1 + +#tuples: (amount, scriptPubKey_byte_arr) +def output_cmp(output_tuple1, output_tuple2): + #test amount first + if (output_tuple1[0] < output_tuple2[0]): + return -1 + elif (output_tuple1[0] > output_tuple2[0]): + return 1 + #tie-breaker: scriptPubKey_byte_arr + return bytearray_cmp(output_tuple1[1], output_tuple2[1]) + +def sort_outputs(output_tuples): + return sorted(output_tuples, cmp=output_cmp) + +def print_outputs(ordered_output_tuples): + index = 0 + for amount, scriptPubKey_byte_arr in ordered_output_tuples: + scriptPubKey_hex = binascii.hexlify(bytearray(scriptPubKey_byte_arr)) + print("%d:\t%d\t%s" % (index, amount, scriptPubKey_hex)) + index = index + 1 + +def main(): + #reference data: https://blockchain.info/rawtx/0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3 + tx_0a6a_input_tuples = [ + # (prev_tx_hash_byte_arr_little_endian, prev_tx_output_index) + ([0x64, 0x3e, 0x5f, 0x4e, 0x66, 0x37, 0x3a, 0x57, 0x25, 0x1f, 0xb1, 0x73, 0x15, 0x1e, 0x83, 0x8c, 0xcd, 0x27, 0xd2, 0x79, 0xac, 0xa8, 0x82, 0x99, 0x7e, 0x00, 0x50, 0x16, 0xbb, 0x53, 0xd5, 0xaa], 0), + ([0x28, 0xe0, 0xfd, 0xd1, 0x85, 0x54, 0x2f, 0x2c, 0x6e, 0xa1, 0x90, 0x30, 0xb0, 0x79, 0x60, 0x51, 0xe7, 0x77, 0x2b, 0x60, 0x26, 0xdd, 0x5d, 0xdc, 0xcd, 0x7a, 0x2f, 0x93, 0xb7, 0x3e, 0x6f, 0xc2], 0), + ([0xf0, 0xa1, 0x30, 0xa8, 0x49, 0x12, 0xd0, 0x3c, 0x1d, 0x28, 0x49, 0x74, 0xf5, 0x63, 0xc5, 0x94, 0x9a, 0xc1, 0x3f, 0x83, 0x42, 0xb8, 0x11, 0x2e, 0xdf, 0xf5, 0x29, 0x71, 0x59, 0x9e, 0x6a, 0x45], 0), + ([0x0e, 0x53, 0xec, 0x5d, 0xfb, 0x2c, 0xb8, 0xa7, 0x1f, 0xec, 0x32, 0xdc, 0x9a, 0x63, 0x4a, 0x35, 0xb7, 0xe2, 0x47, 0x99, 0x29, 0x5d, 0xdd, 0x52, 0x78, 0x21, 0x78, 0x22, 0xe0, 0xb3, 0x1f, 0x57], 0), + ([0x38, 0x1d, 0xe9, 0xb9, 0xae, 0x1a, 0x94, 0xd9, 0xc1, 0x7f, 0x6a, 0x08, 0xef, 0x9d, 0x34, 0x1a, 0x5c, 0xe2, 0x9e, 0x2e, 0x60, 0xc3, 0x6a, 0x52, 0xd3, 0x33, 0xff, 0x62, 0x03, 0xe5, 0x8d, 0x5d], 1), + ([0xf3, 0x20, 0x83, 0x2a, 0x9d, 0x2e, 0x24, 0x52, 0xaf, 0x63, 0x15, 0x4b, 0xc6, 0x87, 0x49, 0x34, 0x84, 0xa0, 0xe7, 0x74, 0x5e, 0xbd, 0x3a, 0xaf, 0x9c, 0xa1, 0x9e, 0xb8, 0x08, 0x34, 0xad, 0x60], 0), + ([0xde, 0x04, 0x11, 0xa1, 0xe9, 0x74, 0x84, 0xa2, 0x80, 0x4f, 0xf1, 0xdb, 0xde, 0x26, 0x0a, 0xc1, 0x9d, 0xe8, 0x41, 0xbe, 0xba, 0xd1, 0x88, 0x0c, 0x78, 0x29, 0x41, 0xac, 0xa8, 0x83, 0xb4, 0xe9], 1), + ([0x3b, 0x8b, 0x2f, 0x8e, 0xfc, 0xeb, 0x60, 0xba, 0x78, 0xca, 0x8b, 0xba, 0x20, 0x6a, 0x13, 0x7f, 0x14, 0xcb, 0x5e, 0xa4, 0x03, 0x5e, 0x76, 0x1e, 0xe2, 0x04, 0x30, 0x2d, 0x46, 0xb9, 0x8d, 0xe2], 0), + ([0x54, 0xff, 0xff, 0x18, 0x29, 0x65, 0xed, 0x09, 0x57, 0xdb, 0xa1, 0x23, 0x9c, 0x27, 0x16, 0x4a, 0xce, 0x5a, 0x73, 0xc9, 0xb6, 0x2a, 0x66, 0x0c, 0x74, 0xb7, 0xb7, 0xf1, 0x5f, 0xf6, 0x1e, 0x7a], 1), + ([0xba, 0xfd, 0x65, 0xe3, 0xc7, 0xf3, 0xf9, 0xfd, 0xfd, 0xc1, 0xdd, 0xb0, 0x26, 0x13, 0x1b, 0x27, 0x8c, 0x3b, 0xe1, 0xaf, 0x90, 0xa4, 0xa6, 0xff, 0xa7, 0x8c, 0x46, 0x58, 0xf9, 0xec, 0x0c, 0x85], 0), + ([0xa5, 0xe8, 0x99, 0xdd, 0xdb, 0x28, 0x77, 0x6e, 0xa9, 0xdd, 0xac, 0x0a, 0x50, 0x23, 0x16, 0xd5, 0x3a, 0x4a, 0x3f, 0xca, 0x60, 0x7c, 0x72, 0xf6, 0x6c, 0x47, 0x0e, 0x04, 0x12, 0xe3, 0x40, 0x86], 0), + ([0x7a, 0x1d, 0xe1, 0x37, 0xcb, 0xaf, 0xb5, 0xc7, 0x04, 0x05, 0x45, 0x5c, 0x49, 0xc5, 0x10, 0x4c, 0xa3, 0x05, 0x7a, 0x1f, 0x12, 0x43, 0xe6, 0x56, 0x3b, 0xb9, 0x24, 0x5c, 0x9c, 0x88, 0xc1, 0x91], 0), + ([0x26, 0xaa, 0x6e, 0x6d, 0x8b, 0x9e, 0x49, 0xbb, 0x06, 0x30, 0xaa, 0xc3, 0x01, 0xdb, 0x67, 0x57, 0xc0, 0x2e, 0x36, 0x19, 0xfe, 0xb4, 0xee, 0x0e, 0xea, 0x81, 0xeb, 0x16, 0x72, 0x94, 0x70, 0x24], 1), + ([0x40, 0x2b, 0x2c, 0x02, 0x41, 0x17, 0x20, 0xbf, 0x40, 0x9e, 0xff, 0x60, 0xd0, 0x5a, 0xda, 0xd6, 0x84, 0xf1, 0x35, 0x83, 0x89, 0x62, 0x82, 0x3f, 0x36, 0x14, 0xcc, 0x65, 0x7d, 0xd7, 0xbc, 0x0a], 1), + ([0x7d, 0x03, 0x7c, 0xeb, 0x2e, 0xe0, 0xdc, 0x03, 0xe8, 0x2f, 0x17, 0xbe, 0x79, 0x35, 0xd2, 0x38, 0xb3, 0x5d, 0x1d, 0xea, 0xbf, 0x95, 0x3a, 0x89, 0x2a, 0x45, 0x07, 0xbf, 0xbe, 0xeb, 0x3b, 0xa4], 1), + ([0x6c, 0x1d, 0x56, 0xf3, 0x1b, 0x2d, 0xe4, 0xbf, 0xc6, 0xaa, 0xea, 0x28, 0x39, 0x6b, 0x33, 0x31, 0x02, 0xb1, 0xf6, 0x00, 0xda, 0x9c, 0x6d, 0x61, 0x49, 0xe9, 0x6c, 0xa4, 0x3f, 0x11, 0x02, 0xb1], 1), + ([0xb4, 0x11, 0x2b, 0x8f, 0x90, 0x0a, 0x7c, 0xa0, 0xc8, 0xb0, 0xe7, 0xc4, 0xdf, 0xad, 0x35, 0xc6, 0xbe, 0x5f, 0x6b, 0xe4, 0x6b, 0x34, 0x58, 0x97, 0x49, 0x88, 0xe1, 0xcd, 0xb2, 0xfa, 0x61, 0xb8], 0)] + tx_0a6a_sorted_input_tuples = sort_inputs(tx_0a6a_input_tuples) + print_inputs(tx_0a6a_sorted_input_tuples) + + tx_0a6a_output_tuples = [ + # (amount, scriptPubKey_byte_arr) + (400057456, [0x76, 0xa9, 0x14, 0x4a, 0x5f, 0xba, 0x23, 0x72, 0x13, 0xa0, 0x62, 0xf6, 0xf5, 0x79, 0x78, 0xf7, 0x96, 0x39, 0x0b, 0xdc, 0xf8, 0xd0, 0x15, 0x88, 0xac]), + (40000000000, [0x76, 0xa9, 0x14, 0x5b, 0xe3, 0x26, 0x12, 0x93, 0x0b, 0x83, 0x23, 0xad, 0xd2, 0x21, 0x2a, 0x4e, 0xc0, 0x3c, 0x15, 0x62, 0x08, 0x4f, 0x84, 0x88, 0xac])] + tx_0a6a_sorted_output_tuples = sort_outputs(tx_0a6a_output_tuples) + print_outputs(tx_0a6a_sorted_output_tuples) + + #reference data: https://blockchain.info/rawtx/28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f thanks @quantabytes! + tx_2820_input_tuples = [ + # (prev_tx_hash, prev_tx_output_index) + ("35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", 0), + ("35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055", 1)] #duplicate prev_tx_hash + + tx_2820_sorted_input_tuples = sort_inputs(tx_2820_input_tuples) + print_inputs(tx_2820_sorted_input_tuples) + + tx_2820_output_tuples = [ + # (amount, scriptPubKey_byte_arr) + (100000000, [0x41, 0x04, 0x6a, 0x07, 0x65, 0xb5, 0x86, 0x56, 0x41, 0xce, 0x08, 0xdd, 0x39, 0x69, 0x0a, 0xad, 0xe2, 0x6d, 0xfb, 0xf5, 0x51, 0x14, 0x30, 0xca, 0x42, 0x8a, 0x30, 0x89, 0x26, 0x13, 0x61, 0xce, 0xf1, 0x70, 0xe3, 0x92, 0x9a, 0x68, 0xae, 0xe3, 0xd8, 0xd4, 0x84, 0x8b, 0x0c, 0x51, 0x11, 0xb0, 0xa3, 0x7b, 0x82, 0xb8, 0x6a, 0xd5, 0x59, 0xfd, 0x2a, 0x74, 0x5b, 0x44, 0xd8, 0xe8, 0xd9, 0xdf, 0xdc, 0x0c, 0xac]), + (2400000000, [0x41, 0x04, 0x4a, 0x65, 0x6f, 0x06, 0x58, 0x71, 0xa3, 0x53, 0xf2, 0x16, 0xca, 0x26, 0xce, 0xf8, 0xdd, 0xe2, 0xf0, 0x3e, 0x8c, 0x16, 0x20, 0x2d, 0x2e, 0x8a, 0xd7, 0x69, 0xf0, 0x20, 0x32, 0xcb, 0x86, 0xa5, 0xeb, 0x5e, 0x56, 0x84, 0x2e, 0x92, 0xe1, 0x91, 0x41, 0xd6, 0x0a, 0x01, 0x92, 0x8f, 0x8d, 0xd2, 0xc8, 0x75, 0xa3, 0x90, 0xf6, 0x7c, 0x1f, 0x6c, 0x94, 0xcf, 0xc6, 0x17, 0xc0, 0xea, 0x45, 0xaf, 0xac])] + tx_2820_sorted_output_tuples = sort_outputs(tx_2820_output_tuples) + print_outputs(tx_2820_output_tuples) + +if __name__ == "__main__": + main() \ No newline at end of file From 469e7e7f12b1e1da05f91e2f9c485a8be3a28fd3 Mon Sep 17 00:00:00 2001 From: Kristov Atlas Date: Wed, 24 Jun 2015 17:02:43 -0400 Subject: [PATCH 02/28] BIP #69 assigned by gmaxwell --- README.mediawiki | 12 ++++++------ bip-0079.mediawiki => bip-0069.mediawiki | 0 {bip-0079 => bip-0069}/bip-0079_examples.py | 0 3 files changed, 6 insertions(+), 6 deletions(-) rename bip-0079.mediawiki => bip-0069.mediawiki (100%) rename {bip-0079 => bip-0069}/bip-0079_examples.py (100%) diff --git a/README.mediawiki b/README.mediawiki index a758f1a8..56c8bd1e 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -254,6 +254,12 @@ Those proposing changes should consider that ultimately consent may rest with th | Standard | Draft |- +| [[bip-0069.mediawiki|69]] +| Lexicographical Indexing of Transaction Inputs and Outputs +| Kristov Atlas +| Standard +| Draft +|- | [[bip-0070.mediawiki|70]] | Payment protocol | Gavin Andresen @@ -277,12 +283,6 @@ Those proposing changes should consider that ultimately consent may rest with th | Stephen Pair | Standard | Draft -|- -| [[bip-0079.mediawiki|79]] -| Lexicographical Indexing of Transaction Inputs and Outputs -| Kristov Atlas -| Standard -| Draft |} diff --git a/bip-0079.mediawiki b/bip-0069.mediawiki similarity index 100% rename from bip-0079.mediawiki rename to bip-0069.mediawiki diff --git a/bip-0079/bip-0079_examples.py b/bip-0069/bip-0079_examples.py similarity index 100% rename from bip-0079/bip-0079_examples.py rename to bip-0069/bip-0079_examples.py From f5b652d6ba8b4c939380630e8e738e91e6c26d67 Mon Sep 17 00:00:00 2001 From: Kristov Atlas Date: Wed, 24 Jun 2015 17:04:36 -0400 Subject: [PATCH 03/28] BIP 69 not 79 --- bip-0069.mediawiki | 2 +- bip-0069/{bip-0079_examples.py => bip-0069_examples.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename bip-0069/{bip-0079_examples.py => bip-0069_examples.py} (100%) diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki index 65e35e6b..8b665505 100644 --- a/bip-0069.mediawiki +++ b/bip-0069.mediawiki @@ -1,5 +1,5 @@
-  BIP:     BIP: 79
+  BIP:     BIP: 69
   Title:   Lexicographical Indexing of Transaction Inputs and Outputs
   Authors: Kristov Atlas 
   Status:  Draft
diff --git a/bip-0069/bip-0079_examples.py b/bip-0069/bip-0069_examples.py
similarity index 100%
rename from bip-0069/bip-0079_examples.py
rename to bip-0069/bip-0069_examples.py

From 9a0d3bb69e97f6bb3721ff23ee06f0402e2181d0 Mon Sep 17 00:00:00 2001
From: Kristov Atlas 
Date: Wed, 24 Jun 2015 17:12:19 -0400
Subject: [PATCH 04/28] Links to discussion, changed Acknowledgements

Added links to discussion per request from laanwj.
---
 bip-0069.mediawiki | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 8b665505..71234887 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -117,6 +117,11 @@ Outputs:
  0:    100000000    41046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac
  1:    2400000000    41044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac
 
+==Discussion==
+
+* [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008484.html|[Bitcoin-development] Lexicographical Indexing of Transaction Inputs and Outputs]]
+* [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008487.html|[Bitcoin-development] [RFC] Canonical input and output ordering in transactions]]
+
 ==References==
 
 * [[https://bitcoinmagazine.com/20273/bitstamp-exchange-activity-trackable-due-multisig-wallet-implementation/|1: Bitstamp Info Leak]]
@@ -126,4 +131,4 @@ Outputs:
 
 ==Acknowledgements==
 
-Danno Ferrin <danno@numisight.com>, Sergio Demian Lerner <sergiolerner@certimix.com>, Justus Ranvier <justus@openbitcoinprivacyproject.org>, and Peter Todd <pete@petertodd.org> contributed to the design and motivations for this BIP.
\ No newline at end of file
+Danno Ferrin <danno@numisight.com>, Sergio Demian Lerner <sergiolerner@certimix.com>, Justus Ranvier <justus@openbitcoinprivacyproject.org>, and Peter Todd <pete@petertodd.org> contributed to the design and motivations for this BIP. A similar proposal was submitted to the Bitcoin-dev mailing list independently by Rusty Russell <rusty@rustcorp.com.au>
\ No newline at end of file

From 5f07cd0d18428b32174f352f9bb525dc9807bacf Mon Sep 17 00:00:00 2001
From: Kristov Atlas 
Date: Tue, 18 Aug 2015 17:43:46 -0400
Subject: [PATCH 05/28] trying to fix git mixup with bip68

---
 README.mediawiki | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/README.mediawiki b/README.mediawiki
index 1f8ef4de..69495128 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -254,15 +254,15 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Standard
 | Draft
 |-
-<<<<<<< HEAD
-| [[bip-0069.mediawiki|69]]
-| Lexicographical Indexing of Transaction Inputs and Outputs
-| Kristov Atlas
-=======
 | [[bip-0068.mediawiki|68]]
 | Consensus-enforced transaction replacement signalled via sequence numbers
 | Mark Friedenbach
->>>>>>> bitcoin/master
+| Standard
+| Draft
+|-
+| [[bip-0069.mediawiki|69]]
+| Lexicographical Indexing of Transaction Inputs and Outputs
+| Kristov Atlas
 | Standard
 | Draft
 |-
@@ -297,4 +297,4 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Draft
 |}
 
-
+
\ No newline at end of file

From 831a003f36652a3465fe0ff4e46090ad12c5a9e8 Mon Sep 17 00:00:00 2001
From: Kristov Atlas 
Date: Tue, 18 Aug 2015 17:50:31 -0400
Subject: [PATCH 06/28] added list of open source implementations

H/T @dcousens
---
 bip-0069.mediawiki | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 71234887..77c1fb91 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -129,6 +129,13 @@ Outputs:
 * [[https://github.com/aantonop/bitcoinbook/blob/develop/ch05.asciidoc|3: Mastering Bitcoin]]
 * [[https://en.bitcoin.it/wiki/Script|4: Bitcoin Wiki on Script]]
 
+==Implementations==
+
+* [[https://github.com/spesmilo/electrum/blob/2af670ea2b92e835919b745d94afcb8b4ec32fda/lib/transaction.py#L648|Electrum]]
+* [[https://github.com/bitcoinjs/bip69/blob/master/index.js|BitcoinJS]]
+* [[https://github.com/bitcoinjs/bip69/blob/master/test/fixtures.json|BitcoinJS Test Fixtures]]
+* [[https://www.npmjs.com/package/bip69|NodeJS]]
+
 ==Acknowledgements==
 
 Danno Ferrin <danno@numisight.com>, Sergio Demian Lerner <sergiolerner@certimix.com>, Justus Ranvier <justus@openbitcoinprivacyproject.org>, and Peter Todd <pete@petertodd.org> contributed to the design and motivations for this BIP. A similar proposal was submitted to the Bitcoin-dev mailing list independently by Rusty Russell <rusty@rustcorp.com.au>
\ No newline at end of file

From d9acdcb6b12cd52424e8fec7cae89eef6bafcad9 Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 08:44:55 +1000
Subject: [PATCH 07/28] split sentences over lines for smaller diffs

---
 bip-0069.mediawiki | 62 ++++++++++++++++++++++++++++++++++++----------
 1 file changed, 49 insertions(+), 13 deletions(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 77c1fb91..d4a9a234 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -9,7 +9,10 @@
 
 ==Abstract==
 
-Currently there is no standard for bitcoin wallet clients when ordering transaction inputs and outputs. As a result, wallet clients often have a discernible blockchain fingerprint, and can leak private information about their users. By contrast, a standard for non-deterministic sorting could be difficult to audit. This document proposes deterministic lexicographical sorting, using hashes of previous transactions and output indices to sort transaction inputs, as well as values and scriptPubKeys to sort transaction outputs.
+Currently there is no standard for bitcoin wallet clients when ordering transaction inputs and outputs.
+As a result, wallet clients often have a discernible blockchain fingerprint, and can leak private information about their users.
+By contrast, a standard for non-deterministic sorting could be difficult to audit.
+This document proposes deterministic lexicographical sorting, using hashes of previous transactions and output indices to sort transaction inputs, as well as values and scriptPubKeys to sort transaction outputs.
 
 ==Copyright==
 
@@ -17,19 +20,41 @@ This BIP is in the public domain.
 
 ==Motivation==
 
-Currently, there is no clear standard for how wallet clients ought to order transaction inputs and outputs. Since wallet clients are left to their own devices to determine this ordering, they often leak information about their users’ finances. For example, a wallet client might naively order inputs based on when addresses were added to a wallet by the user through importing or random generation. Many wallets will place spending outputs first and change outputs second, leaking information about both the sender and receiver’s finances to passive blockchain observers. Such information should remain private not only for the benefit of consumers, but in higher order financial systems must be kept secret to prevent fraud. A researcher recently demonstrated this principle when he detected that Bitstamp leaked information when creating exchange transactions, enabling potential espionage among traders. [1]
+Currently, there is no clear standard for how wallet clients ought to order transaction inputs and outputs.
+Since wallet clients are left to their own devices to determine this ordering, they often leak information about their users’ finances.
+For example, a wallet client might naively order inputs based on when addresses were added to a wallet by the user through importing or random generation.
+Many wallets will place spending outputs first and change outputs second, leaking information about both the sender and receiver’s finances to passive blockchain observers.
+Such information should remain private not only for the benefit of consumers, but in higher order financial systems must be kept secret to prevent fraud.
+Currently, there is no clear standard for how wallet clients ought to order transaction inputs and outputs.
+Since wallet clients are left to their own devices to determine this ordering, they often leak information about their users’ finances.
+For example, a wallet client might naively order inputs based on when addresses were added to a wallet by the user through importing or random generation.
+Many wallets will place spending outputs first and change outputs second, leaking information about both the sender and receiver’s finances to passive blockchain observers.
+Such information should remain private not only for the benefit of consumers, but in higher order financial systems must be kept secret to prevent fraud.
+A researcher recently demonstrated this principle when he detected that Bitstamp leaked information when creating exchange transactions, enabling potential espionage among traders. [1]
 
-One way to address these privacy weaknesses is by randomly ordering inputs and outputs. [2] After all, the order of inputs and outputs does not impact the function of the transaction they belong to, making random sorting viable. Unfortunately, it can be difficult to prove that this sorting process is genuinely randomly sorted based on code or run-time analysis, especially if the software is closed source. A malicious software developer can abuse the ordering of inputs and outputs as a side channel of leaking information. For example, if an attacker can patch a victim’s HD wallet client to order inputs and outputs based on the bits of a master private key, then the attacker can eventually steal all of the victim’s funds by monitoring the blockchain. Non-deterministic methods of sorting are difficult to audit because they are not repeatable.
+One way to address these privacy weaknesses is by randomly ordering inputs and outputs. [2]
+After all, the order of inputs and outputs does not impact the function of the transaction they belong to, making random sorting viable.
+Unfortunately, it can be difficult to prove that this sorting process is genuinely randomly sorted based on code or run-time analysis, especially if the software is closed source.
+A malicious software developer can abuse the ordering of inputs and outputs as a side channel of leaking information.
+For example, if an attacker can patch a victim’s HD wallet client to order inputs and outputs based on the bits of a master private key, then the attacker can eventually steal all of the victim’s funds by monitoring the blockchain.
+Non-deterministic methods of sorting are difficult to audit because they are not repeatable.
 
-The lack of standardization between wallet clients when ordering inputs and outputs can yield predictable quirks that characterize particular wallet clients or services. Such quirks create unique fingerprints that a privacy attacker can employ through simple passive blockchain observation.
+The lack of standardization between wallet clients when ordering inputs and outputs can yield predictable quirks that characterize particular wallet clients or services.
+Such quirks create unique fingerprints that a privacy attacker can employ through simple passive blockchain observation.
 
-The solution is to create an algorithm for sorting transaction inputs and outputs that is deterministic. Since it is deterministic, it should also be unambiguous — that is, given a particular transaction, the proper order of inputs and outputs should be obvious. To make this standard as widely applicable as possible, it should rely on information that is downloaded by both full nodes (with or without typical efficiency techniques such as pruning) and SPV nodes. In order to ensure that it does not leak confidential data, it must rely on information that is publicly accessible through the blockchain. The use of public blockchain information also allows a transaction to be sorted even when it is a multi-party transaction, such as in the example of a CoinJoin.
+The solution is to create an algorithm for sorting transaction inputs and outputs that is deterministic.
+Since it is deterministic, it should also be unambiguous — that is, given a particular transaction, the proper order of inputs and outputs should be obvious.
+To make this standard as widely applicable as possible, it should rely on information that is downloaded by both full nodes (with or without typical efficiency techniques such as pruning) and SPV nodes.
+In order to ensure that it does not leak confidential data, it must rely on information that is publicly accessible through the blockchain.
+The use of public blockchain information also allows a transaction to be sorted even when it is a multi-party transaction, such as in the example of a CoinJoin.
 
 ==Specification==
 
 ===Applicability===
 
-This BIP applies to any transaction for which the order of its inputs and outputs does not impact the transaction’s function. Currently, this refers to any transaction that employs the SIGHASH_ALL signature hash type, in which signatures commit to the exact order of inputs and outputs. Transactions that use SIGHASH_ANYONECANPAY and/or SIGHASH_NONE may include inputs and/or outputs that are not signed; however, compliant software should still emit transactions with lexicographically sorted inputs and outputs, even though they may later be modified by others.
+This BIP applies to any transaction for which the order of its inputs and outputs does not impact the transaction’s function.
+Currently, this refers to any transaction that employs the SIGHASH_ALL signature hash type, in which signatures commit to the exact order of inputs and outputs.
+Transactions that use SIGHASH_ANYONECANPAY and/or SIGHASH_NONE may include inputs and/or outputs that are not signed; however, compliant software should still emit transactions with lexicographically sorted inputs and outputs, even though they may later be modified by others.
 
 In the event that future protocol upgrades introduce new signature hash types, compliant software should apply the lexicographical ordering principle analogously.
 
@@ -37,7 +62,8 @@ While out of scope of this BIP, protocols that do require a specified order of i
 
 ===Lexicographical Sorting===
 
-Ordering of inputs and outputs will rely on the output of sorting functions. These functions can be defined as taking two inputs or two outputs as parameters and returning their appropriate ordering with respect to each other.
+Ordering of inputs and outputs will rely on the output of sorting functions.
+These functions can be defined as taking two inputs or two outputs as parameters and returning their appropriate ordering with respect to each other.
 
 Byte arrays must be sorted with an algorithm that produces the same output as the following comparison algorithm:
 
@@ -62,19 +88,28 @@ N.B. These comparisons do not need to operate in constant time since they are no
 
 ===Transaction Inputs===
 
-104	Transaction inputs are defined by the hash of a previous transaction, the output index of of a UTXO from that previous transaction, the size of an unlocking script, the unlocking script, and a sequence number. [3] For sorting inputs, the hash of the previous transaction and the output index within that transaction are sufficient for sorting purposes; each transaction hash has an extremely high probability of being unique in the blockchain — this is enforced for coinbase transactions by BIP30 — and output indices within a transaction are unique. For the sake of efficiency, transaction hashes should be compared first before output indices, since output indices from different transactions are often equivalent, while all bytes of the transaction hash are effectively random variables.
+104 Transaction inputs are defined by the hash of a previous transaction, the output index of of a UTXO from that previous transaction, the size of an unlocking script, the unlocking script, and a sequence number. [3]
+For sorting inputs, the hash of the previous transaction and the output index within that transaction are sufficient for sorting purposes; each transaction hash has an extremely high probability of being unique in the blockchain — this is enforced for coinbase transactions by BIP30 — and output indices within a transaction are unique.
+For the sake of efficiency, transaction hashes should be compared first before output indices, since output indices from different transactions are often equivalent, while all bytes of the transaction hash are effectively random variables.
 
-Hashes of previous transactions are considered for the purposes of this BIP in their little-endian, byte array format in order to match the traditional, human-readable string representation of the hashes. They must be sorted in accordance with the output of the bytearr_cmp() function above: the hash with the earliest lesser byte is ordered first, and shorter hashes are ordered before longer ones as a tie-breaker. In the event of two matching transaction hashes, output indices will be compared based on their integer value, with the smaller value ordered first. A further tie is extremely improbable for the aforementioned reasons.
+Hashes of previous transactions are considered for the purposes of this BIP in their little-endian, byte array format in order to match the traditional, human-readable string representation of the hashes.
+They must be sorted in accordance with the output of the bytearr_cmp() function above: the hash with the earliest lesser byte is ordered first, and shorter hashes are ordered before longer ones as a tie-breaker.
+In the event of two matching transaction hashes, output indices will be compared based on their integer value, with the smaller value ordered first.
+A further tie is extremely improbable for the aforementioned reasons.
 
 Because the hash of previous transactions and output indices must be included in a signed transaction, wallet clients capable of signing transactions will necessarily have access to this data.
 
-Transaction malleability will not negatively impact the correctness of this process. Even if a wallet client follows this process using unconfirmed UTXOs as inputs and an attacker changes modifies the blockchain’s record of the hash of the previous transaction, the wallet client will include the invalidated previous transaction hash in its input data, and will still correctly sort with respect to that invalidated hash.
+Transaction malleability will not negatively impact the correctness of this process.
+Even if a wallet client follows this process using unconfirmed UTXOs as inputs and an attacker changes modifies the blockchain’s record of the hash of the previous transaction, the wallet client will include the invalidated previous transaction hash in its input data, and will still correctly sort with respect to that invalidated hash.
 
 ===Transaction Outputs===
 
-A transaction output is defined by its scriptPubKey and amount. [3] For sorting purposes, we will consider a scriptPubKey in its byte array representation, and a bitcoin amount in terms of their integer number of satoshis (smallest amount ordered first).
+A transaction output is defined by its scriptPubKey and amount. [3]
+For sorting purposes, we will consider a scriptPubKey in its byte array representation, and a bitcoin amount in terms of their integer number of satoshis (smallest amount ordered first).
 
-For the sake of efficiency, amounts will be considered first for sorting, since they contain fewer bytes of information (8 bytes) compared to a standard P2PKH scriptPubKey (25 bytes). [4] When the values are tied, the scriptPubKey is then considered. In the event of a tie between scriptPubKeys, sorting is irrelevant since the outputs are exactly equivalent.
+For the sake of efficiency, amounts will be considered first for sorting, since they contain fewer bytes of information (8 bytes) compared to a standard P2PKH scriptPubKey (25 bytes). [4]
+When the values are tied, the scriptPubKey is then considered.
+In the event of a tie between scriptPubKeys, sorting is irrelevant since the outputs are exactly equivalent.
 
 ===Examples===
 
@@ -138,4 +173,5 @@ Outputs:
 
 ==Acknowledgements==
 
-Danno Ferrin <danno@numisight.com>, Sergio Demian Lerner <sergiolerner@certimix.com>, Justus Ranvier <justus@openbitcoinprivacyproject.org>, and Peter Todd <pete@petertodd.org> contributed to the design and motivations for this BIP. A similar proposal was submitted to the Bitcoin-dev mailing list independently by Rusty Russell <rusty@rustcorp.com.au>
\ No newline at end of file
+Danno Ferrin <danno@numisight.com>, Sergio Demian Lerner <sergiolerner@certimix.com>, Justus Ranvier <justus@openbitcoinprivacyproject.org>, and Peter Todd <pete@petertodd.org> contributed to the design and motivations for this BIP.
+A similar proposal was submitted to the Bitcoin-dev mailing list independently by Rusty Russell <rusty@rustcorp.com.au>

From 66cb8346fed16c407b84416923130422bb9c5036 Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 08:47:06 +1000
Subject: [PATCH 08/28] human-readable string representation is big-endian

---
 bip-0069.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index d4a9a234..250787c5 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -92,7 +92,7 @@ N.B. These comparisons do not need to operate in constant time since they are no
 For sorting inputs, the hash of the previous transaction and the output index within that transaction are sufficient for sorting purposes; each transaction hash has an extremely high probability of being unique in the blockchain — this is enforced for coinbase transactions by BIP30 — and output indices within a transaction are unique.
 For the sake of efficiency, transaction hashes should be compared first before output indices, since output indices from different transactions are often equivalent, while all bytes of the transaction hash are effectively random variables.
 
-Hashes of previous transactions are considered for the purposes of this BIP in their little-endian, byte array format in order to match the traditional, human-readable string representation of the hashes.
+Previous transaction hashes are considered for the purposes of this BIP in their big-endian, byte array format in order to match the human-readable string representation of the hashes.
 They must be sorted in accordance with the output of the bytearr_cmp() function above: the hash with the earliest lesser byte is ordered first, and shorter hashes are ordered before longer ones as a tie-breaker.
 In the event of two matching transaction hashes, output indices will be compared based on their integer value, with the smaller value ordered first.
 A further tie is extremely improbable for the aforementioned reasons.

From 8d2a159496b8b1518a66abb29a28a68e70e0209c Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 08:50:11 +1000
Subject: [PATCH 09/28] sort by prevTxHash in little-endian, descending order,
 lexicographically

---
 bip-0069.mediawiki | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 250787c5..85e3fdde 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -92,9 +92,8 @@ N.B. These comparisons do not need to operate in constant time since they are no
 For sorting inputs, the hash of the previous transaction and the output index within that transaction are sufficient for sorting purposes; each transaction hash has an extremely high probability of being unique in the blockchain — this is enforced for coinbase transactions by BIP30 — and output indices within a transaction are unique.
 For the sake of efficiency, transaction hashes should be compared first before output indices, since output indices from different transactions are often equivalent, while all bytes of the transaction hash are effectively random variables.
 
-Previous transaction hashes are considered for the purposes of this BIP in their big-endian, byte array format in order to match the human-readable string representation of the hashes.
-They must be sorted in accordance with the output of the bytearr_cmp() function above: the hash with the earliest lesser byte is ordered first, and shorter hashes are ordered before longer ones as a tie-breaker.
-In the event of two matching transaction hashes, output indices will be compared based on their integer value, with the smaller value ordered first.
+Previous transaction hashes (in their little-endian, byte-array form) are to be sorted in descending order, lexicographically.
+In the event of two matching transaction hashes, the respective output indices will be compared by their integer value, in ascending order.
 A further tie is extremely improbable for the aforementioned reasons.
 
 Because the hash of previous transactions and output indices must be included in a signed transaction, wallet clients capable of signing transactions will necessarily have access to this data.

From 342058602eb7737ceeb098d07eb9237d5e5fc65a Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 08:51:18 +1000
Subject: [PATCH 10/28] remove probability, specify behaviour for matching
 prevOut indices

---
 bip-0069.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 85e3fdde..43d25ee1 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -93,8 +93,8 @@ For sorting inputs, the hash of the previous transaction and the output index wi
 For the sake of efficiency, transaction hashes should be compared first before output indices, since output indices from different transactions are often equivalent, while all bytes of the transaction hash are effectively random variables.
 
 Previous transaction hashes (in their little-endian, byte-array form) are to be sorted in descending order, lexicographically.
-In the event of two matching transaction hashes, the respective output indices will be compared by their integer value, in ascending order.
-A further tie is extremely improbable for the aforementioned reasons.
+In the event of two matching transaction hashes, the respective previous output indices will be compared by their integer value, in ascending order.
+If the previous output indices match, the inputs are considered equal.
 
 Because the hash of previous transactions and output indices must be included in a signed transaction, wallet clients capable of signing transactions will necessarily have access to this data.
 

From c351ae0b9f518709fdd540573c30206696078f0b Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 08:52:18 +1000
Subject: [PATCH 11/28] remove mention of information typically found in
 wallets

---
 bip-0069.mediawiki | 2 --
 1 file changed, 2 deletions(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 43d25ee1..5a203892 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -96,8 +96,6 @@ Previous transaction hashes (in their little-endian, byte-array form) are to be
 In the event of two matching transaction hashes, the respective previous output indices will be compared by their integer value, in ascending order.
 If the previous output indices match, the inputs are considered equal.
 
-Because the hash of previous transactions and output indices must be included in a signed transaction, wallet clients capable of signing transactions will necessarily have access to this data.
-
 Transaction malleability will not negatively impact the correctness of this process.
 Even if a wallet client follows this process using unconfirmed UTXOs as inputs and an attacker changes modifies the blockchain’s record of the hash of the previous transaction, the wallet client will include the invalidated previous transaction hash in its input data, and will still correctly sort with respect to that invalidated hash.
 

From c6ed18d8b27be10b5f0c5f357969e1b0dbf963db Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 08:54:12 +1000
Subject: [PATCH 12/28] remove malleability foot note

---
 bip-0069.mediawiki | 2 --
 1 file changed, 2 deletions(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 5a203892..d6008253 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -96,8 +96,6 @@ Previous transaction hashes (in their little-endian, byte-array form) are to be
 In the event of two matching transaction hashes, the respective previous output indices will be compared by their integer value, in ascending order.
 If the previous output indices match, the inputs are considered equal.
 
-Transaction malleability will not negatively impact the correctness of this process.
-Even if a wallet client follows this process using unconfirmed UTXOs as inputs and an attacker changes modifies the blockchain’s record of the hash of the previous transaction, the wallet client will include the invalidated previous transaction hash in its input data, and will still correctly sort with respect to that invalidated hash.
 
 ===Transaction Outputs===
 

From c60771d2299a08299a7734a697587dde2378d489 Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 09:07:31 +1000
Subject: [PATCH 13/28] reword transaction outputs in-line with transaction
 inputs format

---
 bip-0069.mediawiki | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index d6008253..f3dff42d 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -100,11 +100,11 @@ If the previous output indices match, the inputs are considered equal.
 ===Transaction Outputs===
 
 A transaction output is defined by its scriptPubKey and amount. [3]
-For sorting purposes, we will consider a scriptPubKey in its byte array representation, and a bitcoin amount in terms of their integer number of satoshis (smallest amount ordered first).
+For the sake of efficiency, amounts should be compared first for sorting, since they contain fewer bytes of information (8 bytes) compared to a standard P2PKH scriptPubKey (25 bytes). [4]
 
-For the sake of efficiency, amounts will be considered first for sorting, since they contain fewer bytes of information (8 bytes) compared to a standard P2PKH scriptPubKey (25 bytes). [4]
-When the values are tied, the scriptPubKey is then considered.
-In the event of a tie between scriptPubKeys, sorting is irrelevant since the outputs are exactly equivalent.
+Transaction output amounts (as 64-bit unsigned integers) are to be sorted in ascending order.
+In the event of two matching output amounts, the respective output scriptPubKeys (in their little-endian, byte-array form) will be compared lexicographically, in ascending order.
+If the scriptPubKeys match, the outputs are considered equal.
 
 ===Examples===
 

From 64a44180b87ceb6101f4b62c5dd6c2b4bba33669 Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 09:08:50 +1000
Subject: [PATCH 14/28] remove random 104

---
 bip-0069.mediawiki | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index f3dff42d..e4d273cb 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -88,7 +88,7 @@ N.B. These comparisons do not need to operate in constant time since they are no
 
 ===Transaction Inputs===
 
-104 Transaction inputs are defined by the hash of a previous transaction, the output index of of a UTXO from that previous transaction, the size of an unlocking script, the unlocking script, and a sequence number. [3]
+Transaction inputs are defined by the hash of a previous transaction, the output index of of a UTXO from that previous transaction, the size of an unlocking script, the unlocking script, and a sequence number. [3]
 For sorting inputs, the hash of the previous transaction and the output index within that transaction are sufficient for sorting purposes; each transaction hash has an extremely high probability of being unique in the blockchain — this is enforced for coinbase transactions by BIP30 — and output indices within a transaction are unique.
 For the sake of efficiency, transaction hashes should be compared first before output indices, since output indices from different transactions are often equivalent, while all bytes of the transaction hash are effectively random variables.
 

From 5f75c82dc47423e026461dc228eebed76fde89b0 Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 09:10:49 +1000
Subject: [PATCH 15/28] add editor note

---
 bip-0069.mediawiki | 1 +
 1 file changed, 1 insertion(+)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index e4d273cb..d265aaef 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -2,6 +2,7 @@
   BIP:     BIP: 69
   Title:   Lexicographical Indexing of Transaction Inputs and Outputs
   Authors: Kristov Atlas 
+  Editors: Daniel Cousens 
   Status:  Draft
   Type:    Informational
   Created: 2015-06-12

From 64f321e2c9919ffc2b6bfb7999d5986c1cb7cf34 Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 21 Aug 2015 09:22:50 +1000
Subject: [PATCH 16/28] dont include pseudo-code for lexicographical sorting

---
 bip-0069.mediawiki | 36 +++++++++++++++---------------------
 1 file changed, 15 insertions(+), 21 deletions(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index d265aaef..e01a792f 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -61,31 +61,21 @@ In the event that future protocol upgrades introduce new signature hash types, c
 
 While out of scope of this BIP, protocols that do require a specified order of inputs/outputs (e.g. due to use of SIGHASH_SINGLE) should consider the goals of this BIP and how best to adapt them to the specific needs of those protocols.
 
-===Lexicographical Sorting===
+===Lexicographical Ordering===
 
-Ordering of inputs and outputs will rely on the output of sorting functions.
-These functions can be defined as taking two inputs or two outputs as parameters and returning their appropriate ordering with respect to each other.
+Lexicographical ordering is an algorithm for comparison used to sort two sets based on their cartesian order within their common superset.
+Lexicographic order is also often known as alphabetical order, or dictionary order.
 
-Byte arrays must be sorted with an algorithm that produces the same output as the following comparison algorithm:
+Common implementations include:
 
- #returns -1 if barr1 is lesser, 1 if barr1 is greater, and 0 if equal
- def bytearr_cmp(barr1, barr2):
-    pos = 0
-    while (pos < len(barr1) and pos < len(barr2)):
-        if (barr1[pos] < barr2[pos]):
-            return -1;
-        elif (barr1[pos] > barr2[pos]):
-            return 1;
-        pos = pos + 1
-    #the shorter array will be ordered first
-    if (len(barr1) < len(barr2)):
-        return -1
-    elif (len(barr1) > len(barr2)):
-        return 1
-    else:
-        return 0
+* `std::lexicographical_compare` in C++ [5]
+* `cmp` in Python 2.7
+* `memcmp` in C [6]
+* `Buffer.compare` in Node.js [7]
 
-N.B. These comparisons do not need to operate in constant time since they are not processing secret information.
+For more information, see the wikipedia entry on Lexicographical order. [8]
+
+N.B. All comparisons do not need to operate in constant time since they are not processing secret information.
 
 ===Transaction Inputs===
 
@@ -159,6 +149,10 @@ Outputs:
 * [[https://github.com/OpenBitcoinPrivacyProject/wallet-ratings/blob/master/2015-1/criteria.md|2: OBPP Random Indexing as Countermeasure]]
 * [[https://github.com/aantonop/bitcoinbook/blob/develop/ch05.asciidoc|3: Mastering Bitcoin]]
 * [[https://en.bitcoin.it/wiki/Script|4: Bitcoin Wiki on Script]]
+* [[http://www.cplusplus.com/reference/algorithm/lexicographical_compare|5: std::lexicographical_compare]]
+* [[http://www.cplusplus.com/reference/cstring/memcmp|6: memcmp]]
+* [[https://nodejs.org/api/buffer.html#buffer_class_method_buffer_compare_buf1_buf2|7: Buffer.compare]]
+* [[https://en.wikipedia.org/wiki/Lexicographical_order|8: Lexicographical order]]
 
 ==Implementations==
 

From 1d74463fd97f81d9612214420f44978991cd3ca6 Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Fri, 28 Aug 2015 10:50:23 +1000
Subject: [PATCH 17/28] Revert "remove malleability foot note"

This reverts commit c6ed18d8b27be10b5f0c5f357969e1b0dbf963db.
---
 bip-0069.mediawiki | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index e01a792f..56400cb1 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -87,6 +87,8 @@ Previous transaction hashes (in their little-endian, byte-array form) are to be
 In the event of two matching transaction hashes, the respective previous output indices will be compared by their integer value, in ascending order.
 If the previous output indices match, the inputs are considered equal.
 
+Transaction malleability will not negatively impact the correctness of this process.
+Even if a wallet client follows this process using unconfirmed UTXOs as inputs and an attacker changes modifies the blockchain’s record of the hash of the previous transaction, the wallet client will include the invalidated previous transaction hash in its input data, and will still correctly sort with respect to that invalidated hash.
 
 ===Transaction Outputs===
 

From f749070a23b62fd603c1341c36142b7d1c7f0f94 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E0=B8=BFtcDrak?= 
Date: Sat, 5 Sep 2015 22:48:52 +0100
Subject: [PATCH 18/28] Update to account for BIP34

---
 bip-0105.mediawiki | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/bip-0105.mediawiki b/bip-0105.mediawiki
index 7aaef044..cbd309d5 100644
--- a/bip-0105.mediawiki
+++ b/bip-0105.mediawiki
@@ -62,10 +62,12 @@ Each time a miner creates a block, they may vote to increase or decrease the
 blocksize by a maximum of 10% of the current block size limit. These votes will 
 be used to recalculate the new block size limit every 2016 blocks.
 
-Votes are cast using the block's coinbase field.
+Votes are cast using the block's coinbase transaction scriptSig.
 
-The first 4 bytes of the coinbase field shall be repurposed for voting as an
-unsigned long integer which will be the block size in bytes.
+As per BIP34, the coinbase transaction scriptSig starts with a push of the block
+height. The next push is a little-endian number representing the preferred block
+size in bytes. For example, 0x4c(OP_PUSHDATA1) 0x03(size of constant) 0x80 0x84 0x1e(2MB)
+or 0x4c(OP_PUSHDATA1) 0x04(size of constant) 0x80 0x96 0x98 0x00(10MB).
 
 If a miner votes for an increase, the block hash must meet a difficulty target
 which is proportionally larger than the standard difficulty target based on the
@@ -95,6 +97,10 @@ This proposal is based on ideas and concepts derived from the writings of
 Meni Rosenfeld and Gregory Maxwell.
 
 
+==References==
+
+[[bip-0034.mediawiki|BIP34]]
+
 ==Copyright==
 
 This work is placed in the public domain.

From ae46943f11faf80c1f69542f0976989c09cfa192 Mon Sep 17 00:00:00 2001
From: BtcDrak 
Date: Tue, 11 Aug 2015 00:49:09 +0100
Subject: [PATCH 19/28] BIP for OP_CHECKSEQUENCEVERIFY

---
 README.mediawiki  |   6 ++
 bip-csv.mediawiki | 206 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 212 insertions(+)
 create mode 100644 bip-csv.mediawiki

diff --git a/README.mediawiki b/README.mediawiki
index 1404eb67..d9c8f1bf 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -314,6 +314,12 @@ Those proposing changes should consider that ultimately consent may rest with th
 | Standard
 | Draft
 |-
+| [[bip-0112.mediawiki|112]]
+| CHECKSEQUENCEVERIFY
+| BtcDrak and Mark Friedenbach
+| Standard
+| Draft
+|-
 | [[bip-0113.mediawiki|113]]
 | Median time-past as endpoint for lock-time calculations
 | Thomas Kerin and Mark Friedenbach
diff --git a/bip-csv.mediawiki b/bip-csv.mediawiki
new file mode 100644
index 00000000..130c3c9c
--- /dev/null
+++ b/bip-csv.mediawiki
@@ -0,0 +1,206 @@
+
+  BIP: XX
+  Title: OP_CHECKSEQUENCEVERIFY
+  Authors: BtcDrak 
+           Mark Friedenbach 	
+  Status: Draft
+  Type: Standards Track
+  Created: 2015-08-10
+
+ +==Abstract== + +This BIP describes a new opcode (OP_CHECKSEQUENCEVERIFY) for the Bitcoin +scripting system that allows a transaction output to be made unspendable +until some relative point in the future according to the nSequence field. + + +==Summary== + +CHECKSEQUENCEVERIFY redefines the existing NOP3 opcode. When executed it +compares the top item on the stack to the nSequence field of the transaction +containing the scriptSig. If that top stack item is greater than the +transaction sequence threshold (1 << 31) the script fails immediately, +otherwise script evaluation continues as though a NOP was executed. + +By comparing the argument to CHECKSEQUENCEVERIFY against the nSequence field, +we indirectly verify that the desired block height or block time has been +reached (according to BIP68's redefinition of nSequence); until that block +height or block time has been reached the transaction output remains +unspendable. + + +==Motivation== + +BIP68 repurposes the transaction nSequence field meaning by giving sequence +numbers new consensus-enforced semantics as a relative lock-time. However, +there is no way to build Bitcoin scripts to make decisions based on this +field. + + +==Specification== + +Refer to the reference implementation, reproduced below, for the precise +semantics and detailed rationale for those semantics. + + + case OP_NOP3: + { + if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) { + // not enabled; treat as a NOP3 + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) { + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } + break; + } + + if (stack.size() < 1) + return set_error(serror, SCRIPT_ERR_INVALID_STACK_OPERATION); + + // Note that unlike CHECKLOCKTIMEVERIFY we do not need to + // accept 5-byte bignums since any value greater than or + // equal to SEQUENCE_THRESHOLD (= 1 << 31) will be rejected + // anyway. This limitation just happens to coincide with + // CScriptNum's default 4-byte limit with an explicit sign + // bit. + // + // This means there is a maximum relative lock time of 52 + // years, even though the nSequence field in transactions + // themselves is uint32_t and could allow a relative lock + // time of up to 120 years. + const CScriptNum nInvSequence(stacktop(-1), fRequireMinimal); + + // In the rare event that the argument may be < 0 due to + // some arithmetic being done first, you can always use + // 0 MAX CHECKSEQUENCEVERIFY. + if (nInvSequence < 0) + return set_error(serror, SCRIPT_ERR_NEGATIVE_LOCKTIME); + + // Actually compare the specified inverse sequence number + // with the input. + if (!CheckSequence(nInvSequence)) + return set_error(serror, SCRIPT_ERR_UNSATISFIED_LOCKTIME); + + break; + } + + bool CheckSequence(const CScriptNum& nSequence) const + { + int64_t txToSequence; + + // Fail under all circumstances if the transaction's version + // number is not set high enough to enable enforced sequence + // number rules. + if (txTo->nVersion < 3) + return false; + + txToSequence = (int64_t)~txTo->vin[nIn].nSequence; + if (txToSequence >= SEQUENCE_THRESHOLD) + return false; + + // There are two types of nSequence: lock-by-blockheight + // and lock-by-blocktime, distinguished by whether + // nSequence < LOCKTIME_THRESHOLD. + // + // We want to compare apples to apples, so fail the script + // unless the type of nSequence being tested is the same as + // the nSequence in the transaction. + if (!( + (txToSequence < LOCKTIME_THRESHOLD && nSequence < LOCKTIME_THRESHOLD) || + (txToSequence >= LOCKTIME_THRESHOLD && nSequence >= LOCKTIME_THRESHOLD) + )) + return false; + + // Now that we know we're comparing apples-to-apples, the + // comparison is a simple numeric one. + if (nSequence > txToSequence) + return false; + + return true; + } + +https://github.com/btcdrak/bips/blob/bip-csv/bip-csv/example.cpp + + +==Example: Escrow with Timeout== + +An escrow that times out automatically 30 days after being funded can be +established in the following way. Alice, Bob and Escrow create a 2-of-3 +address with the following redeemscript. + + IF + 2 3 CHECKMULTISIGVERIFY + ELSE + <30 days> CHECKSEQUENCEVERIFY DROP + CHECKSIGVERIFY + ENDIF + +At any time funds can be spent using signatures from any two of Alice, +Bob or the Escrow. + +After 30 days Alice can sign alone. + +The clock does not start ticking until the payment to the escrow address +confirms. + + +==Reference Implementation== + +A reference implementation is provided in the following git repository: + +https://github.com/maaku/bitcoin/tree/checksequenceverify + + +==Deployment== + +We reuse the double-threshold switchover mechanism from BIPs 34 and 66, +with the same thresholds, but for nVersion = 4. The new rules are in +effect for every block (at height H) with nVersion = 4 and at least 750 +out of 1000 blocks preceding it (with heights H-1000..H-1) also have +nVersion = 4. Furthermore, when 950 out of the 1000 blocks preceding a +block do have nVersion = 4, nVersion = 3 blocks become invalid, and all +further blocks enforce the new rules. + +It is recommended that this soft-fork deployment trigger include other +related proposals for improving Bitcoin's lock-time capabilities, including: + +[https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP 65]: +OP_CHECKLOCKTIMEVERIFY, + +[https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP 68]: +Consensus-enforced transaction replacement signalled via sequence numbers, + +and [https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki BIP XX]: +Median-Past-Time-Lock. + + +==Upgrade and Testing Plan== + +TBD + + +==Credits== + +Mark Friedenbach for designing and authoring the actual implementation +for CHECKSEQUENCEVERIFY. + + +==References== + +BIP 68: Consensus-enforced transaction replacement signalled via sequence numbers +https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki + +BIP 65: OP_CHECKLOCKTIMEVERIFY +https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki + +BIP XX: Median-Past-Time-Lock +https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki + +HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and revocation hashes +http://lists.linuxfoundation.org/pipermail/lightning-dev/2015-July/000021.html + + +==Copyright== + +This document is placed in the public domain. + From 6150b3a8574dcb14520936071005a19b81b12d93 Mon Sep 17 00:00:00 2001 From: Mark Friedenbach Date: Wed, 12 Aug 2015 18:14:51 -0700 Subject: [PATCH 20/28] Comprehensive editing to clarify meaning and intent of existing text. --- bip-csv.mediawiki | 133 +++++++++++++++++++++++++++------------------- 1 file changed, 77 insertions(+), 56 deletions(-) diff --git a/bip-csv.mediawiki b/bip-csv.mediawiki index 130c3c9c..ead3edb0 100644 --- a/bip-csv.mediawiki +++ b/bip-csv.mediawiki @@ -1,6 +1,6 @@
   BIP: XX
-  Title: OP_CHECKSEQUENCEVERIFY
+  Title: CHECKSEQUENCEVERIFY
   Authors: BtcDrak 
            Mark Friedenbach 	
   Status: Draft
@@ -10,32 +10,46 @@
 
 ==Abstract==
 
-This BIP describes a new opcode (OP_CHECKSEQUENCEVERIFY) for the Bitcoin 
-scripting system that allows a transaction output to be made unspendable 
-until some relative point in the future according to the nSequence field.
+This BIP describes a new opcode (CHECKSEQUENCEVERIFY) for the Bitcoin
+scripting system that in combination with BIP 68 allows execution
+pathways of a script to be restricted based on the age of the output
+being spent.
 
 
 ==Summary==
 
-CHECKSEQUENCEVERIFY redefines the existing NOP3 opcode. When executed it 
-compares the top item on the stack to the nSequence field of the transaction 
-containing the scriptSig. If that top stack item is greater than the 
-transaction sequence threshold (1 << 31) the script fails immediately, 
-otherwise script evaluation continues as though a NOP was executed.
+CHECKSEQUENCEVERIFY redefines the existing NOP3 opcode. When executed
+it compares the top item on the stack to the inverse of the nSequence
+field of the transaction input containing the scriptSig. If the
+inverse of nSequence is less than the sequence threshold (1 << 31),
+the transaction version is greater than or equal to 2, and the top
+item on the stack is less than or equal to the inverted nSequence,
+script evaluation continues as though a NOP was executed. Otherwise
+the script fails immediately.
 
-By comparing the argument to CHECKSEQUENCEVERIFY against the nSequence field,
-we indirectly verify that the desired block height or block time has been 
-reached (according to BIP68's redefinition of nSequence); until that block
-height or block time has been reached the transaction output remains 
-unspendable.
+BIP 68's redefinition of nSequence prevents a non-final transaction
+from being selected for inclusion in a block until the corresponding
+input has reached the specified age, as measured in block heiht or
+block time. By comparing the argument to CHECKSEQUENCEVERIFY against
+the nSequence field, we indirectly verify a desired minimum age of the
+the output being spent; until that relative age has been reached any
+script execution pathway including the CHECKSEQUENCEVERIFY will fail
+to validate, causing the transaction not to be selected for inclusion
+in a block.
 
 
 ==Motivation==
 
-BIP68 repurposes the transaction nSequence field meaning by giving sequence
-numbers new consensus-enforced semantics as a relative lock-time. However,
-there is no way to build Bitcoin scripts to make decisions based on this 
-field.
+BIP 68 repurposes the transaction nSequence field meaning by giving
+sequence numbers new consensus-enforced semantics as a relative
+lock-time. However, there is no way to build Bitcoin scripts to make
+decisions based on this field.
+
+By making the nSequence field accessible to script, it becomes
+possible to construct code pathways that only become accessible some
+minimum time after proof-of-publication. This enables a wide variety
+of applications in phased protocols such as escrow, payment channels,
+or bidirectional pegs.
 
 
 ==Specification==
@@ -84,42 +98,47 @@ semantics and detailed rationale for those semantics.
         break;
     }
     
-    bool CheckSequence(const CScriptNum& nSequence) const
+    bool CheckSequence(const CScriptNum& nInvSequence) const
     {
-        int64_t txToSequence;
+        int64_t txToInvSequence;
         
         // Fail under all circumstances if the transaction's version
         // number is not set high enough to enable enforced sequence
         // number rules.
-        if (txTo->nVersion < 3)
+        if (txTo->nVersion < 2)
+            return false;
+
+        // Sequence number must be inverted to convert it into a
+        // relative lock-time.
+	txToInvSequence = (int64_t)~txTo->vin[nIn].nSequence;
+        
+        // Sequence numbers under SEQUENCE_THRESHOLD are not consensus
+	// constrained.
+	if (txToInvSequence >= SEQUENCE_THRESHOLD)
             return false;
         
-        txToSequence = (int64_t)~txTo->vin[nIn].nSequence;
-        if (txToSequence >= SEQUENCE_THRESHOLD)
-            return false;
-        
-        // There are two types of nSequence: lock-by-blockheight
-        // and lock-by-blocktime, distinguished by whether
-        // nSequence < LOCKTIME_THRESHOLD.
+        // There are two types of relative lock-time: lock-by-
+        // blockheight and lock-by-blocktime, distinguished by
+	// whether txToInvSequence < LOCKTIME_THRESHOLD.
         //
         // We want to compare apples to apples, so fail the script
-        // unless the type of nSequence being tested is the same as
-        // the nSequence in the transaction.
+        // unless the type of lock-time being tested is the same as
+        // the lock-time in the transaction input.
         if (!(
-            (txToSequence <  LOCKTIME_THRESHOLD && nSequence <  LOCKTIME_THRESHOLD) ||
-            (txToSequence >= LOCKTIME_THRESHOLD && nSequence >= LOCKTIME_THRESHOLD)
+            (txToInvSequence <  LOCKTIME_THRESHOLD && nInvSequence <  LOCKTIME_THRESHOLD) ||
+            (txToInvSequence >= LOCKTIME_THRESHOLD && nInvSequence >= LOCKTIME_THRESHOLD)
         ))
             return false;
         
         // Now that we know we're comparing apples-to-apples, the
         // comparison is a simple numeric one.
-        if (nSequence > txToSequence)
+        if (nInvSequence > txInvToSequence)
             return false;
     
         return true;
     }
 
-https://github.com/btcdrak/bips/blob/bip-csv/bip-csv/example.cpp
+https://github.com/maaku/bitcoin/commit/33be476a60fcc2afbe6be0ca7b93a84209173eb2
 
 
 ==Example: Escrow with Timeout==
@@ -131,7 +150,7 @@ address with the following redeemscript.
     IF
         2    3 CHECKMULTISIGVERIFY
     ELSE
-        <30 days> CHECKSEQUENCEVERIFY DROP
+         CHECKSEQUENCEVERIFY DROP
          CHECKSIGVERIFY
     ENDIF
 
@@ -153,13 +172,13 @@ https://github.com/maaku/bitcoin/tree/checksequenceverify
 
 ==Deployment==
 
-We reuse the double-threshold switchover mechanism from BIPs 34 and 66,
-with the same thresholds, but for nVersion = 4. The new rules are in 
-effect for every block (at height H) with nVersion = 4 and at least 750 
-out of 1000 blocks preceding it (with heights H-1000..H-1) also have 
-nVersion = 4. Furthermore, when 950 out of the 1000 blocks preceding a 
-block do have nVersion = 4, nVersion = 3 blocks become invalid, and all 
-further blocks enforce the new rules.
+We reuse the double-threshold switchover mechanism from BIPs 34 and
+66, with the same thresholds, but for nVersion = 4. The new rules are
+in effect for every block (at height H) with nVersion = 4 and at least
+750 out of 1000 blocks preceding it (with heights H-1000..H-1) also
+have nVersion = 4. Furthermore, when 950 out of the 1000 blocks
+preceding a block do have nVersion = 4, nVersion = 3 blocks become
+invalid, and all further blocks enforce the new rules.
 
 It is recommended that this soft-fork deployment trigger include other 
 related proposals for improving Bitcoin's lock-time capabilities, including:
@@ -174,33 +193,35 @@ and [https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki BIP XX]:
 Median-Past-Time-Lock.
 
 
-==Upgrade and Testing Plan==
-
-TBD
-
-
 ==Credits==
 
-Mark Friedenbach for designing and authoring the actual implementation 
-for CHECKSEQUENCEVERIFY.
+Mark Friedenbach invented the application of sequence numbers to
+achieve relative lock-time, and wrote the reference implementation of
+CHECKSEQUENCEVERIFY.
+
+The reference implementation and this BIP was based heavily on work
+done by Peter Todd for the closely related BIP 65.
+
+BtcDrak edited this BIP document.
 
 
 ==References==
 
-BIP 68: Consensus-enforced transaction replacement signalled via sequence numbers
-https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki 
+BIP 68: Consensus-enforced transaction replacement signalled via
+sequence numbers
+https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
 
 BIP 65: OP_CHECKLOCKTIMEVERIFY
 https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki
 
-BIP XX: Median-Past-Time-Lock 
-https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki 
+BIP XX: Median past block time for time-lock constraints
+https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki
 
-HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and revocation hashes
-http://lists.linuxfoundation.org/pipermail/lightning-dev/2015-July/000021.html 
+HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and
+revocation hashes
+http://lists.linuxfoundation.org/pipermail/lightning-dev/2015-July/000021.html
 
 
 ==Copyright==
 
 This document is placed in the public domain.
-

From 6902f790f174c8af934869dcc5f10f94f816f65d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E0=B8=BFtcDrak?= 
Date: Thu, 13 Aug 2015 08:14:38 +0100
Subject: [PATCH 21/28] Add constant definitions for clarity

Formatting Fix typos

Update with BIP 112 assignment

Update references to BIP113

Update deployment methodology

Add references
---
 bip-csv.mediawiki => bip-0112.mediawiki | 55 +++++++++++++++++--------
 1 file changed, 37 insertions(+), 18 deletions(-)
 rename bip-csv.mediawiki => bip-0112.mediawiki (79%)

diff --git a/bip-csv.mediawiki b/bip-0112.mediawiki
similarity index 79%
rename from bip-csv.mediawiki
rename to bip-0112.mediawiki
index ead3edb0..c06caf50 100644
--- a/bip-csv.mediawiki
+++ b/bip-0112.mediawiki
@@ -1,5 +1,5 @@
 
-  BIP: XX
+  BIP: 112
   Title: CHECKSEQUENCEVERIFY
   Authors: BtcDrak 
            Mark Friedenbach 	
@@ -29,7 +29,7 @@ the script fails immediately.
 
 BIP 68's redefinition of nSequence prevents a non-final transaction
 from being selected for inclusion in a block until the corresponding
-input has reached the specified age, as measured in block heiht or
+input has reached the specified age, as measured in block height or
 block time. By comparing the argument to CHECKSEQUENCEVERIFY against
 the nSequence field, we indirectly verify a desired minimum age of the
 the output being spent; until that relative age has been reached any
@@ -58,6 +58,14 @@ Refer to the reference implementation, reproduced below, for the precise
 semantics and detailed rationale for those semantics.
 
     
+    // Threshold for nLockTime: below this value it is interpreted as block number,
+    // otherwise as UNIX timestamp (already defined in Bitcoin Core).
+    static const unsigned int LOCKTIME_THRESHOLD = 500000000; // Tue Nov  5 00:53:20 1985 UTC
+    
+    // Threshold for inverted nSequence: below this value it is interpreted
+    // as a relative lock-time, otherwise ignored.
+    static const uint32_t SEQUENCE_THRESHOLD = (1 << 31);
+    
     case OP_NOP3:
     {
         if (!(flags & SCRIPT_VERIFY_CHECKSEQUENCEVERIFY)) {
@@ -107,19 +115,19 @@ semantics and detailed rationale for those semantics.
         // number rules.
         if (txTo->nVersion < 2)
             return false;
-
+        
         // Sequence number must be inverted to convert it into a
         // relative lock-time.
-	txToInvSequence = (int64_t)~txTo->vin[nIn].nSequence;
+        txToInvSequence = (int64_t)~txTo->vin[nIn].nSequence;
         
         // Sequence numbers under SEQUENCE_THRESHOLD are not consensus
-	// constrained.
-	if (txToInvSequence >= SEQUENCE_THRESHOLD)
+        // constrained.
+        if (txToInvSequence >= SEQUENCE_THRESHOLD)
             return false;
         
         // There are two types of relative lock-time: lock-by-
         // blockheight and lock-by-blocktime, distinguished by
-	// whether txToInvSequence < LOCKTIME_THRESHOLD.
+        // whether txToInvSequence < LOCKTIME_THRESHOLD.
         //
         // We want to compare apples to apples, so fail the script
         // unless the type of lock-time being tested is the same as
@@ -132,9 +140,9 @@ semantics and detailed rationale for those semantics.
         
         // Now that we know we're comparing apples-to-apples, the
         // comparison is a simple numeric one.
-        if (nInvSequence > txInvToSequence)
+        if (nInvSequence > txToInvSequence)
             return false;
-    
+        
         return true;
     }
 
@@ -173,13 +181,21 @@ https://github.com/maaku/bitcoin/tree/checksequenceverify
 ==Deployment==
 
 We reuse the double-threshold switchover mechanism from BIPs 34 and
-66, with the same thresholds, but for nVersion = 4. The new rules are
-in effect for every block (at height H) with nVersion = 4 and at least
+66, with the same thresholds, but for nVersion = 8. The new rules are
+in effect for every block (at height H) with nVersion = 8 and at least
 750 out of 1000 blocks preceding it (with heights H-1000..H-1) also
-have nVersion = 4. Furthermore, when 950 out of the 1000 blocks
-preceding a block do have nVersion = 4, nVersion = 3 blocks become
+have nVersion = 8. Furthermore, when 950 out of the 1000 blocks
+preceding a block do have nVersion = 8, nVersion = 3 blocks become
 invalid, and all further blocks enforce the new rules.
 
+When assessing the block version as mask of ~0x20000007 must be applied
+to work around the complications caused by
+[http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-August/010396.html BIP101's premature use]
+of the [https://gist.github.com/sipa/bf69659f43e763540550 undecided version bits proposal].
+
+By applying ~0x20000007 with nVersion = 8, the thresholds should be tested
+comparing block nVersion >= 4 as this will save a bit for future use.
+
 It is recommended that this soft-fork deployment trigger include other 
 related proposals for improving Bitcoin's lock-time capabilities, including:
 
@@ -189,10 +205,9 @@ OP_CHECKLOCKTIMEVERIFY,
 [https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki BIP 68]: 
 Consensus-enforced transaction replacement signalled via sequence numbers,
 
-and [https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki BIP XX]: 
+and [https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki BIP 113]: 
 Median-Past-Time-Lock.
 
-
 ==Credits==
 
 Mark Friedenbach invented the application of sequence numbers to
@@ -202,7 +217,7 @@ CHECKSEQUENCEVERIFY.
 The reference implementation and this BIP was based heavily on work
 done by Peter Todd for the closely related BIP 65.
 
-BtcDrak edited this BIP document.
+BtcDrak authored this BIP document.
 
 
 ==References==
@@ -214,13 +229,17 @@ https://github.com/bitcoin/bips/blob/master/bip-0068.mediawiki
 BIP 65: OP_CHECKLOCKTIMEVERIFY
 https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki
 
-BIP XX: Median past block time for time-lock constraints
-https://github.com/bitcoin/bips/blob/master/bip-00XX.mediawiki
+BIP 113: Median past block time for time-lock constraints
+https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki
 
 HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and
 revocation hashes
 http://lists.linuxfoundation.org/pipermail/lightning-dev/2015-July/000021.html
 
+[http://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-August/010396.html Softfork deployment considerations]
+
+[https://gist.github.com/sipa/bf69659f43e763540550 Version bits]
+
 
 ==Copyright==
 

From 8368e7553ca073ff887bf8d22cde21bec545b56d Mon Sep 17 00:00:00 2001
From: Daniel Cousens 
Date: Thu, 10 Sep 2015 07:43:00 +1000
Subject: [PATCH 22/28] endianness not relevant, use byte order

---
 bip-0069.mediawiki | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
index 56400cb1..e868df31 100644
--- a/bip-0069.mediawiki
+++ b/bip-0069.mediawiki
@@ -83,7 +83,7 @@ Transaction inputs are defined by the hash of a previous transaction, the output
 For sorting inputs, the hash of the previous transaction and the output index within that transaction are sufficient for sorting purposes; each transaction hash has an extremely high probability of being unique in the blockchain — this is enforced for coinbase transactions by BIP30 — and output indices within a transaction are unique.
 For the sake of efficiency, transaction hashes should be compared first before output indices, since output indices from different transactions are often equivalent, while all bytes of the transaction hash are effectively random variables.
 
-Previous transaction hashes (in their little-endian, byte-array form) are to be sorted in descending order, lexicographically.
+Previous transaction hashes (in reversed byte-order) are to be sorted in ascending order, lexicographically.
 In the event of two matching transaction hashes, the respective previous output indices will be compared by their integer value, in ascending order.
 If the previous output indices match, the inputs are considered equal.
 
@@ -96,7 +96,7 @@ A transaction output is defined by its scriptPubKey and amount. [3]
 For the sake of efficiency, amounts should be compared first for sorting, since they contain fewer bytes of information (8 bytes) compared to a standard P2PKH scriptPubKey (25 bytes). [4]
 
 Transaction output amounts (as 64-bit unsigned integers) are to be sorted in ascending order.
-In the event of two matching output amounts, the respective output scriptPubKeys (in their little-endian, byte-array form) will be compared lexicographically, in ascending order.
+In the event of two matching output amounts, the respective output scriptPubKeys (as a byte-array) will be compared lexicographically, in ascending order.
 If the scriptPubKeys match, the outputs are considered equal.
 
 ===Examples===

From 796398d3fbaa08ba361f134ea6e288dc71577d8f Mon Sep 17 00:00:00 2001
From: rayrrr 
Date: Sun, 13 Sep 2015 07:15:52 -0400
Subject: [PATCH 23/28] Fix link to BIP 70 extensions registry in comment.

---
 bip-0070/paymentrequest.proto | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bip-0070/paymentrequest.proto b/bip-0070/paymentrequest.proto
index 6680810e..717946ef 100644
--- a/bip-0070/paymentrequest.proto
+++ b/bip-0070/paymentrequest.proto
@@ -3,7 +3,7 @@
 //
 // Use fields 1000+ for extensions;
 // to avoid conflicts, register extensions via pull-req at
-// https://github.com/bitcoin/bips/bip-0070/extensions.mediawiki
+// https://github.com/bitcoin/bips/blob/master/bip-0070/extensions.mediawiki
 //
 
 package payments;

From c375301fa8fa807ae084cfd7abfb2cf915b01ee9 Mon Sep 17 00:00:00 2001
From: Justus Ranvier 
Date: Fri, 18 Sep 2015 13:30:07 -0500
Subject: [PATCH 24/28] BIP-47: Clarify decoding of notification transactions

Specify procedure for extracting payment codes from notification transactions.

Add explicit check that payment code x values are valid for secp256k1
---
 bip-0047.mediawiki | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki
index d49b0ea5..15c5a8b4 100644
--- a/bip-0047.mediawiki
+++ b/bip-0047.mediawiki
@@ -1,3 +1,7 @@
+RECENT CHANGES:
+
+* (18 Sep 2015) Clarify decoding of notification transactions
+
 
   BIP:     47
   Title:   Reusable Payment Codes for Hierarchical Deterministic Wallets
@@ -60,7 +64,7 @@ A payment code contains the following elements:
 ** Bit 0: Bitmessage notification
 ** Bits 1-7: reserved
 * Byte 2: sign. required value: 0x02 or 0x03
-* Bytes 3 - 34: x value
+* Bytes 3 - 34: x value, must be a member of the secp256k1 group
 * Bytes 35 - 66: chain code
 * Bytes 67 - 79: reserved for future expansion, zero-filled unless otherwise noted
 
@@ -90,17 +94,30 @@ Prior to the first time Alice initiates a transaction to Bob, Alice MUST inform
 # Alice constructs a transaction which sends a small quantity of bitcoins to Bob's notification address (notification transaction)
 ## The inputs selected for this transaction MUST NOT be easily associated with Alice's notification address
 # Alice derives a unique shared secret using ECDH:
-## Alice selects the first exposed public key, of the first pubkey-exposing input, of the transaction: 
a
+## Alice selects the private key corresponding to the first exposed public key, of the first pubkey-exposing input, of the transaction:
a
## Alice selects the public key associated with Bob's notification address:
B, where B = bG
## Alice calculates a secret point:
S = aB
## Alice expresses the secret point in compressed DER format, then calculates a scalar shared secret:
s = SHA256(S)
# Alice serializes her payment code in binary form. # Alice renders her payment code (P) unreadable to anyone except Bob by: -## Replace the x value with:
s XOR (x value)
-## Replace the chain code with:
sha256(s) XOR (chain code)
+## Replace the x value with x':
x' = s XOR (x value)
+## Replace the chain code with c':
c' = sha256(s) XOR (chain code)
# Alice adds an OP_RETURN output to her transaction which consists of P. +# Bob watches for any transactions which create an output at his notification address. +# When a transaction is received, the client examines it to determine if it contains a standard OP_RETURN output with an 80 byte payload (notification transactions). +# If the first byte of the payload in a notification transaction is 0x01: +## Bob selects the first exposed public key, of the first pubkey-exposing input, of the transaction:
A, where A = aG
+## Bob selects the private key associated with his notification address:
b
+## Bob calculates a secret point:
S = bA
+## Bob expresses the secret point in compressed DER format, then calculates a scalar shared secret:
s = SHA256(S)
+## Bob interprets the 80 byte payload as a payment code, except: +### Replace the x value with x':
x' = s XOR (x value)
+### Replace the chain code with c':
c' = sha256(s) XOR (chain code)
+## If the updated x value is a member of the secp256k1 group, the payment code is valid. +## If the updated x value is not a member of the secp256k1 group, the payment code is ignored. + Now that Bob's client has received Alice's payment code, it is possible for Alice to send payments (up to 232 payments) to Bob. Alice will never again need to send a notification transaction to Bob. From 42c0650ccb2d6483f44e71c04d8c982a5e9208fe Mon Sep 17 00:00:00 2001 From: Kristov Atlas Date: Sat, 19 Sep 2015 17:22:41 -0400 Subject: [PATCH 25/28] add EOF newlines per @luke-jr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit “README.mediawiki and bip-0069/bip-0069_examples.py are missing EOF newlines. Anything else needed before merging this draft?” — @luke-jr --- README.mediawiki | 2 +- bip-0069/bip-0069_examples.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.mediawiki b/README.mediawiki index 69495128..13e38e8b 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -297,4 +297,4 @@ Those proposing changes should consider that ultimately consent may rest with th | Draft |} - \ No newline at end of file + diff --git a/bip-0069/bip-0069_examples.py b/bip-0069/bip-0069_examples.py index 7622cfe9..e2f52edd 100644 --- a/bip-0069/bip-0069_examples.py +++ b/bip-0069/bip-0069_examples.py @@ -109,4 +109,4 @@ def main(): print_outputs(tx_2820_output_tuples) if __name__ == "__main__": - main() \ No newline at end of file + main() From 2b419aba8874c24bb4d16dfa3728b4f2dcd0f19b Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Sun, 20 Sep 2015 09:27:01 +0200 Subject: [PATCH 26/28] [trivial] expression --- bip-0069.mediawiki | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki index e868df31..e23ff042 100644 --- a/bip-0069.mediawiki +++ b/bip-0069.mediawiki @@ -33,7 +33,7 @@ Many wallets will place spending outputs first and change outputs second, leakin Such information should remain private not only for the benefit of consumers, but in higher order financial systems must be kept secret to prevent fraud. A researcher recently demonstrated this principle when he detected that Bitstamp leaked information when creating exchange transactions, enabling potential espionage among traders. [1] -One way to address these privacy weaknesses is by randomly ordering inputs and outputs. [2] +One way to address these privacy weaknesses is by randomizing the order of inputs and outputs. [2] After all, the order of inputs and outputs does not impact the function of the transaction they belong to, making random sorting viable. Unfortunately, it can be difficult to prove that this sorting process is genuinely randomly sorted based on code or run-time analysis, especially if the software is closed source. A malicious software developer can abuse the ordering of inputs and outputs as a side channel of leaking information. From 873827d7964960d2dbeb11f3d8df7a642cd292d2 Mon Sep 17 00:00:00 2001 From: Justus Ranvier Date: Mon, 21 Sep 2015 17:07:39 -0500 Subject: [PATCH 27/28] BIP-47: correct base58check version byte Previously specified version byte only produced the desired leading character if the check bytes were omitted Thanks to TD from Samourai Wallet for pointing this out --- bip-0047.mediawiki | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bip-0047.mediawiki b/bip-0047.mediawiki index 15c5a8b4..c8397a7d 100644 --- a/bip-0047.mediawiki +++ b/bip-0047.mediawiki @@ -1,5 +1,7 @@ RECENT CHANGES: +* (21 Sep 2015) Correct base58check version byte + * (18 Sep 2015) Clarify decoding of notification transactions
@@ -72,7 +74,7 @@ A payment code contains the following elements:
 
 When a payment code is presented to the user, it SHOULD be presented encoded in Base58Check form.
 
-* The version byte is: 0x23 (produces a "P" as the first character of the serialized form)
+* The version byte is: 0x47 (produces a "P" as the first character of the serialized form)
 * The payload is the binary serialization of the payment code
 
 ===Protocol===

From 95bac1809ac2e640a0465ba8358a6f1516504584 Mon Sep 17 00:00:00 2001
From: Mark Friedenbach 
Date: Wed, 23 Sep 2015 14:23:54 -0700
Subject: [PATCH 28/28] Rewrite BIP to reflect current state of pull request
 #6312, including the removal of bit inversion and the allocation of future
 soft-fork bits.

---
 bip-0068.mediawiki | 130 +++++++++++++++++++++++++--------------------
 1 file changed, 71 insertions(+), 59 deletions(-)

diff --git a/bip-0068.mediawiki b/bip-0068.mediawiki
index 8da92b8f..e336765a 100644
--- a/bip-0068.mediawiki
+++ b/bip-0068.mediawiki
@@ -1,6 +1,6 @@
 
   BIP: 68
-  Title: Consensus-enforced transaction replacement signalled via sequence numbers
+  Title: Consensus-enforced transaction replacement signaled via sequence numbers (relative lock-time)
   Author: Mark Friedenbach 
   Status: Draft
   Type: Standards Track
@@ -9,17 +9,21 @@
 
 ==Abstract==
 
-This BIP describes a modification to the consensus-enforced semantics of the sequence number field to enable a signed transaction input to remain invalid for a defined period of time after confirmation of its corresponding output, for the purpose of supporting consensus-enforced transaction replacement features.
+This BIP describes a modification to the consensus-enforced semantics of the sequence number field to enable a signed transaction input to remain invalid for a defined period of time after confirmation of its corresponding outpoint, for the purpose of supporting consensus-enforced transaction replacement features.
 
 ==Motivation==
 
-Bitcoin has sequence number fields for each input of a transaction. The original idea appears to have been that the highest sequence number should dominate and miners should prefer it over lower sequence numbers. This was never really implemented, and the half-implemented code seemed to be making this assumption that miners would honestly prefer the higher sequence numbers, even if the lower ones were much much more profitable. That turns out to be a dangerous assumption, and so most technical people have assumed that kind of sequence number mediated replacement was useless because there was no way to enforce "honest" behaviour, as even a few rational (profit maximizing) miners would break that completely. The change described by this BIP provides the missing piece that makes sequence numbers do something significant with respect to enforcing transaction replacement without assuming anything other than profit-maximizing behaviour on the part of miners.
+Bitcoin has sequence number fields for each input of a transaction. The original idea appears to have been that the highest sequence number should dominate and miners should prefer it over lower sequence numbers. This was never really implemented, and the half-implemented code seemed to be making this assumption that miners would honestly prefer the higher sequence numbers, even if the lower ones were much much more profitable. That turns out to be a dangerous assumption, and so most technical people have assumed that kind of sequence number mediated replacement was useless because there was no way to enforce "honest" behavior, as even a few rational (profit maximizing) miners would break that completely. The change described by this BIP provides the missing piece that makes sequence numbers do something significant with respect to enforcing transaction replacement without assuming anything other than profit-maximizing behavior on the part of miners.
 
 ==Specification==
 
-The maximum sequence number can be included in any block, like normal. For transactions with an nVersion of 2 or greater, a sequence number of one less than the maximum can only be included in the next block after the input it is spending, rather than it being possible to be included in the same block. A sequence number one less than that can only be included two blocks later, and so on. Alternatively, a sequence number LOCKTIME_THRESHOLD (500,000,000) less than the maximum (0xffffffff - 500,000,000 = 0xe2329aff) can only be included in a block with an nTime timestamp at least one second greater than the median time stamp of the 11 blocks prior to the block containing the coin being spent. A sequence number one less than that can only be included two seconds later, and so on. This behaviour is only enforced if the most significant bit of the sequence number field is set.
+For transactions with an nVersion of 2 or greater, if the most significant bit (1 << 31) of a sequence number is clear, the remaining 31 bits are interpreted as an encoded relative lock-time. A sequence number with the most significant bit set is given no consensus meaning and can be included in any block, like normal, under all circumstances.
 
-This is proposed to be accomplished by replacing IsFinalTx() and CheckFinalTx(), existing consensus code functions that return true if a transaction's lock-time constraints are satisfied and false otherwise, with LockTime() and CheckLockTime(), new functions that return a non-zero value if a transaction's lock-time or sequence number constraints are not satisfied and zero otherwise:
+If the second most significant bit (1 << 30) is clear, the remaining bits reduced by 2^14 are interpreted as a minimum block-heigh constraint over the input's age. A sequence number of zero indicates a relative lock-time of zero blocks (bits 31 and 30 clear) and can be included in any block. A sequence number of 1 << 14 can be included in the next block after the input it is spending, or any block thereafter, rather than it being possible to be included in the same block. A sequence number of 2 << 14 can't be included until two blocks later, and so on.
+
+Alternatively, if the second most significant bit (1 << 30) is set, the remaining bits reduced by 2^5 are interpreted as a minimum block-time constraint over the input's age. A sequence number with just that second most significant bit set (0x40000000) is interpreted as a relative lock-time of 0, measured in seconds, and can be included in the same block as the output being spent. Advancing that sequence number by 2^5 (0x40000020) constrains the transaction to be included in blocks with an nTime timestamp at least one second greater than the median time stamp of the 11 blocks prior to the block containing the coin being spent. Advancing the sequence number by an additional 2^5 (0x40000040) constrains the spend to be two seconds later, and so on.
+
+This is proposed to be accomplished by replacing IsFinalTx() and CheckFinalTx(), existing consensus and non-consensus code functions that return true if a transaction's lock-time constraints are satisfied and false otherwise, with LockTime() and CheckLockTime(), new functions that return a non-zero value if a transaction's lock-time or sequence number constraints are not satisfied and zero otherwise:
 
 
     enum {
@@ -27,14 +31,26 @@ This is proposed to be accomplished by replacing IsFinalTx() and CheckFinalTx(),
         LOCKTIME_VERIFY_SEQUENCE = (1 << 0),
     };
     
-    const uint32_t SEQUENCE_THRESHOLD = (1 << 31);
+    /* Setting nSequence to this value for every input in a transaction
+     * disables nLockTime. */
+    const uint32_t CTxIn::SEQUENCE_FINAL = 0xffffffff;
+    /* Threshold for CTxIn::nSequence: below this value it is interpreted
+     * as arelative lock-time, otherwise ignored. */
+    const uint32_t CTxIn::SEQUENCE_LOCKTIME_THRESHOLD = (1 << 31);
+     /* Threshold for CTxIn::nSequence when interpreted as a relative
+      * lock-time: below this value it has units of blocks, otherwise
+      * seconds. */
+    const uint32_t CTxIn::SEQUENCE_UNITS_THRESHOLD = (1 << 30);
+    /* Number of reserved low-order bits (depending on units used) which
+     * are shifted out prior to relative lock-time constraint checking. */
+    const int CTxIn::SEQUENCE_BLOCKS_OFFSET = 14;
+    const int CTxIn::SEQUENCE_SECONDS_OFFSET = 5;
     
     int64_t LockTime(const CTransaction &tx,
                      int flags, const CCoinsView* pCoinsView,
                      int nBlockHeight, int64_t nBlockTime)
     {
         CCoins coins;
-        uint32_t nLockTime;
     
         bool fEnforceBIP68 = tx.nVersion >= 2
                           && flags & LOCKTIME_VERIFY_SEQUENCE;
@@ -44,56 +60,58 @@ This is proposed to be accomplished by replacing IsFinalTx() and CheckFinalTx(),
         // time constraints given our view of block chain history.
         int nMinHeight = 0;
         int64_t nMinTime = 0;
-        // Will remain equal to true if all inputs are finalized (MAX_INT).
+        // Will remain equal to true if all inputs are finalized
+        // (CTxIn::SEQUENCE_FINAL).
         bool fFinalized = true;
     
         BOOST_FOREACH(const CTxIn& txin, tx.vin) {
-            // The relative lock-time is the inverted sequence number so
-            // as to preserve the semantics MAX_INT means an input is
-            // finalized (0 relative lock-time).
-            nLockTime = ~txin.nSequence;
-    
-            // ~MAX_INT is zero/false, meaning the input is final.
-            if (!nLockTime)
+            // Set a flag if we witness an input that isn't finalized.
+            if (CTxIn::SEQUENCE_FINAL == txin.nSequence)
                 continue;
             else
                 fFinalized = false;
     
-            // Sequence numbers equal to or above the SEQUENCE_THRESHOLD
-            // are not treated as relative lock-times, nor are they given
-            // any consensus-enforced meaning at this point.
-            if (nLockTime >= SEQUENCE_THRESHOLD)
-                continue;
-    
             // Do not enforce sequence numbers as a relative lock time
             // unless we have been instructed to.
             if (!fEnforceBIP68)
                 continue;
     
-            // Skip this input if it is not in the UTXO set. This should
-            // only ever happen in non-consensus code.
+            // Sequence numbers equal to or above the locktime threshold
+            // are not treated as relative lock-times, nor are they given
+            // any consensus-enforced meaning at this point.
+            if (txin.nSequence >= CTxIn::SEQUENCE_LOCKTIME_THRESHOLD)
+                continue;
+    
+            // Skip this input if it is not in the UTXO set. Aside from
+            // the coinbase input, this should only ever happen in non-
+            // consensus code.
             if (!pCoinsView->GetCoins(txin.prevout.hash, coins))
                 continue;
     
-            if (nLockTime < LOCKTIME_THRESHOLD)
-                // We subtract 1 from relative lock-times because of lock
+            if (txin.nSequence < CTxIn::SEQUENCE_UNITS_THRESHOLD)
+                // We subtract 1 from relative lock-times because a lock-
                 // time of 0 has the semantics of "same block," so a lock-
                 // time of 1 should mean "next block," but nLockTime has
                 // the semantics of "last invalid block height."
-                nMinHeight = std::max(nMinHeight, coins.nHeight + (int)nLockTime - 1);
+                nMinHeight = std::max(nMinHeight,
+                      coins.nHeight
+                    + (int)(txin.nSequence >> CTxIn::SEQUENCE_BLOCKS_OFFSET)
+                    - 1);
             else
                 // Time-based relative lock-times are measured from the
                 // smallest allowed timestamp of the block containing the
                 // txout being spent, which is the median time past of the
-                // block prior.
+                // block prior. We subtract one for the same reason as
+                // above.
                 nMinTime = std::max(nMinTime,
                       pindexBestHeader->GetAncestor(coins.nHeight-1)->GetMedianTimePast()
-                    - LOCKTIME_THRESHOLD + (int64_t)nLockTime);
+                    + (int64_t)((txin.nSequence ^ CTxIn::SEQUENCE_UNITS_THRESHOLD) >> CTxIn::SEQUENCE_SECONDS_OFFSET)
+                    - 1);
         }
     
-        // If sequence numbers are MAX_INT / zero relative lock-time, the
-        // transaction is considered final and nLockTime constraints are
-        // not enforced.
+        // If all sequence numbers are CTxIn::SEQUENCE_FINAL, the
+        // transaction is considered final and nLockTime constraints
+        // are not enforced.
         if (fFinalized)
             return 0;
     
@@ -142,7 +160,7 @@ Code conditional on the return value of IsFinalTx() / CheckLockTime() has to be
 
 ==Rationale==
 
-Counting down from the maximum makes sense, since nothing can be higher than the maximum and no transaction can be in a block before its parent transactions. This means that a higher sequence number can always be included earlier than a lower one (even if the time the original coins being spent was unknown when the transaction was authored). Because of this, even rational miners should go along with the scheme: Take the higher sequence number and collect the fees, or skip over it in the hopes that no one else takes a higher number before the next available lower number becomes spendable. And, of course, users are not constrained to make their sequence numbers go down only one at a time. So it's "take the most updated version, now, or gamble that no one in the next dozen blocks takes the most updated and that you manage to include the next to most when it finally becomes mineable." This is similar to how lock-time works. In fact, this scheme is precisely a per-input relative lock-time.
+Using sequence numbers for locking inputs makes sense, since no transaction can be in a block before its parent transactions. This means that a lower sequence number can always be included earlier than a higher one (even if the time the original coins being spent was unknown when the transaction was authored). Because of this, even rational miners should go along with the scheme: Take the lowest sequence number and collect the fees, or skip over it in the hopes that no one else takes a lower number before the next available higher number becomes spendable. And, of course, users are not constrained to make their sequence numbers go up only one at a time. So it's "take the most updated version, now, or gamble that no one in the next dozen blocks takes the most updated and that you manage to include the next to most when it finally becomes mineable." This is similar to how lock-time works. In fact, this scheme is precisely a per-input relative lock-time.
 
 ==Example: Bidirectional payment channel==
 
@@ -152,7 +170,7 @@ Alice desires to send Bob a payment of 0.1btc. She does so by constructing a tra
 
 Bob now desires to send Alice a refund of 0.25btc. He does so by constructing a transaction spending the 1btc output and sending 0.95btc (= 0.7btc + 0.25btc) to Alice and 0.05btc to himself. Since Bob will still have in his logs the transaction giving him 0.7btc 29 days after the creation of the channel, Alice demands that this new transaction have a relative lock-time of 28 days so she has a full day to broadcast it before the next transaction matures.
 
-Alice and Bob continue to make payments to each other, decrementing the relative lock-time by one day each time the channel switches direction, until the present time is reached or either party desires to close out the channel. A close-out is performed by setting the relative lock-time to zero (nSequence = MAX_INT) and both parties signing.
+Alice and Bob continue to make payments to each other, decrementing the relative lock-time by one day each time the channel switches direction, until the present time is reached or either party desires to close out the channel. A close-out is performed by finalizing the input (nSequence = MAX_INT) and both parties signing.
 
 ==Implementation==
 
@@ -160,50 +178,44 @@ A reference implementation is provided in the following git repository:
 
 https://github.com/maaku/bitcoin/tree/sequencenumbers
 
-==Acknowledgements==
+==Acknowledgments==
 
-Credit goes to Gregory Maxwell for providing a succinct and clear description of the behaviour of this change, which became the basis of this BIP text.
+Credit goes to Gregory Maxwell for providing a succinct and clear description of the behavior of this change, which became the basis of this BIP text.
 
 ==Deployment==
 
-We reuse the double-threshold switchover mechanism from BIPs 34 and 66, with the same thresholds, but for nVersion = 4. The new rules are in effect for every block (at height H) with nVersion = 4 and at least 750 out of 1000 blocks preceding it (with heights H-1000..H-1) also have nVersion = 4. Furthermore, when 950 out of the 1000 blocks preceding a block do have nVersion = 4, nVersion = 3 blocks become invalid, and all further blocks enforce the new rules.
+We reuse the double-threshold switch over mechanism from BIPs 34 and 66, with the same thresholds, but for nVersion = 4. The new rules are in effect for every block (at height H) with nVersion = 4 and at least 750 out of 1000 blocks preceding it (with heights H-1000..H-1) also have nVersion = 4. Furthermore, when 950 out of the 1000 blocks preceding a block do have nVersion = 4, nVersion = 3 blocks become invalid, and all further blocks enforce the new rules.
 
-It is recommended that this soft-fork deployment trigger include other related proposals for improving Bitcoin's lock-time capabilities, such as [https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP 65]: OP_CHECKLOCKTIMEVERIFY.
+It is recommended that this soft-fork deployment trigger include other related proposals for improving Bitcoin's lock-time capabilities, including [https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP 65]: OP_CHECKLOCKTIMEVERIFY, [https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP 112]: CHECKSEQUENCEVERIFY, and [https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki BIP 113] Median time-past as endpoint for lock-time calculations.
 
 ==Compatibility==
 
-The only use of sequence numbers by the Bitcoin Core reference client software is to disable checking the nLockTime constraints in a transaction. The semantics of that application are preserved by this BIP without requiring any special-case handling.
+The only use of sequence numbers by the Bitcoin Core reference client software is to disable checking the nLockTime constraints in a transaction. The semantics of that application are preserved by this BIP.
 
-There may be other uses for the sequence number field that are not commonplace or yet to be discoverd. To allow for other uses of the sequence number field, it is only interpreted as a relative lock-time as described in this BIP if the most significant bit is set. This allows up to 31 bits of the sequence number field to be used for other purposes in applicaitons which don't simultaneously need a per-input relative lock-time.
+There may be other uses for the sequence number field that are not commonplace or yet to be discovered. To allow for other uses of the sequence number field, it is only interpreted as a relative lock-time as described in this BIP if the most significant bit is clear. This allows up to 31 bits of the sequence number field to be used for other purposes in applications which don't simultaneously need a per-input relative lock-time. In addition, the unused low-order bits of the relative lock-time encoding are available for use by future soft-fork extensions.
 
-The most efficient way to calculate sequence number from relative lock-time is with bit-inversion:
+The most efficient way to calculate sequence number from relative lock-time is with bit masks and shifts:
 
 
-    // 0 <= nHeight < 500,000,000 blocks
-    nSequence = ~(nHeight);
-    nHeight = ~(nSequence);
+    // 0 <= nHeight < 65,535 blocks (1.25 years)
+    nSequence = nHeight << 14;
+    nHeight = nSequence >> 14;
     
-    // 1 <= nTime < 1,647,483,648 seconds (52.2 years)
-    nSequence = ~(nTime - 1 + LOCKTIME_THRESHOLD);
-    nTime = ~(nSequence) - LOCKTIME_THRESHOLD + 1;
-
- -In languages which do not support bit inversion, the calculation can be accomplished with integer arithmetic instead: - -
-    nSequence = 0xffffffff - nHeight;
-    nHeight = 0xffffffff - nSequence;
-    
-    nSequence = 0xffffffff - nTime + 1 - LOCKTIME_THRESHOLD;
-    nTime = 0xffffffff - nSequence + 1 - LOCKTIME_THRESHOLD;
+    // 0 <= nTime < 33,554,431 seconds (1.06 years)
+    nSequence = 1<<30 | (nTime << 5);
+    nTime = (nSequence ^ 1<<30) >> 5;
 
==References== Bitcoin mailing list discussion: https://www.mail-archive.com/bitcoin-development@lists.sourceforge.net/msg07864.html -BIP 34: Block v2, Height in Coinbase, https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki +[https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki BIP 34]: Block v2, Height in Coinbase -BIP 65: OP_CHECKLOCKTIMEVERIFY, https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki +[https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP 65]: OP_CHECKLOCKTIMEVERIFY -BIP 66: Strict DER signatures, https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki +[https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki BIP 66]: Strict DER signatures + +[https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP 112]: CHECKSEQUENCEVERIFY + +[https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki BIP 113]: Median time-past as endpoint for lock-time calculations