summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKalle Rosenbaum <kalle@rosenbaum.se>2015-09-25 14:30:36 +0200
committerKalle Rosenbaum <kalle@rosenbaum.se>2015-09-25 14:30:36 +0200
commit2c56c21af12a53d9a2b4c1bc5aa467134a72ddb0 (patch)
tree9119f0f6309a7478f6dc4d6c5746880a2c15686d
parent10173c76ccef3a8766538d9029edfab12b620797 (diff)
parente413cd49dec89e2881dd4a91e2f34e7e29382502 (diff)
downloadbips-2c56c21af12a53d9a2b4c1bc5aa467134a72ddb0.tar.xz
Merge remote-tracking branch 'upstream/master'
-rw-r--r--README.mediawiki12
-rw-r--r--bip-0047.mediawiki29
-rw-r--r--bip-0068.mediawiki130
-rw-r--r--bip-0069.mediawiki169
-rw-r--r--bip-0069/bip-0069_examples.py112
-rw-r--r--bip-0070/paymentrequest.proto2
-rw-r--r--bip-0105.mediawiki12
-rw-r--r--bip-0112.mediawiki246
8 files changed, 644 insertions, 68 deletions
diff --git a/README.mediawiki b/README.mediawiki
index 1404eb6..089d9b5 100644
--- a/README.mediawiki
+++ b/README.mediawiki
@@ -266,6 +266,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
@@ -314,6 +320,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-0047.mediawiki b/bip-0047.mediawiki
index d49b0ea..c8397a7 100644
--- a/bip-0047.mediawiki
+++ b/bip-0047.mediawiki
@@ -1,3 +1,9 @@
+RECENT CHANGES:
+
+* (21 Sep 2015) Correct base58check version byte
+
+* (18 Sep 2015) Clarify decoding of notification transactions
+
<pre>
BIP: 47
Title: Reusable Payment Codes for Hierarchical Deterministic Wallets
@@ -60,7 +66,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
@@ -68,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===
@@ -90,17 +96,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: <pre>a</pre>
+## Alice selects the private key corresponding to the first exposed public key, of the first pubkey-exposing input, of the transaction: <pre>a</pre>
## Alice selects the public key associated with Bob's notification address: <pre>B, where B = bG</pre>
## Alice calculates a secret point: <pre>S = aB</pre>
## Alice expresses the secret point in compressed DER format, then calculates a scalar shared secret: <pre>s = SHA256(S)</pre>
# 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: <pre>s XOR (x value)</pre>
-## Replace the chain code with: <pre>sha256(s) XOR (chain code)</pre>
+## Replace the x value with x': <pre>x' = s XOR (x value)</pre>
+## Replace the chain code with c': <pre>c' = sha256(s) XOR (chain code)</pre>
# Alice adds an OP_RETURN output to her transaction which consists of P.
<img src="bip-0047/reusable_payment_codes-01.png" />
+# 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: <pre>A, where A = aG</pre>
+## Bob selects the private key associated with his notification address: <pre>b</pre>
+## Bob calculates a secret point: <pre>S = bA</pre>
+## Bob expresses the secret point in compressed DER format, then calculates a scalar shared secret: <pre>s = SHA256(S)</pre>
+## Bob interprets the 80 byte payload as a payment code, except:
+### Replace the x value with x': <pre>x' = s XOR (x value)</pre>
+### Replace the chain code with c': <pre>c' = sha256(s) XOR (chain code)</pre>
+## 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 2<sup>32</sup> payments) to Bob.
Alice will never again need to send a notification transaction to Bob.
diff --git a/bip-0068.mediawiki b/bip-0068.mediawiki
index 8da92b8..e336765 100644
--- a/bip-0068.mediawiki
+++ b/bip-0068.mediawiki
@@ -1,6 +1,6 @@
<pre>
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 <mark@friedenbach.org>
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:
<pre>
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:
<pre>
- // 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;
-</pre>
-
-In languages which do not support bit inversion, the calculation can be accomplished with integer arithmetic instead:
-
-<pre>
- 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;
</pre>
==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
+
+[https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki BIP 65]: OP_CHECKLOCKTIMEVERIFY
+
+[https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki BIP 66]: Strict DER signatures
-BIP 65: OP_CHECKLOCKTIMEVERIFY, https://github.com/bitcoin/bips/blob/master/bip-0065.mediawiki
+[https://github.com/bitcoin/bips/blob/master/bip-0112.mediawiki BIP 112]: CHECKSEQUENCEVERIFY
-BIP 66: Strict DER signatures, https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
+[https://github.com/bitcoin/bips/blob/master/bip-0113.mediawiki BIP 113]: Median time-past as endpoint for lock-time calculations
diff --git a/bip-0069.mediawiki b/bip-0069.mediawiki
new file mode 100644
index 0000000..e23ff04
--- /dev/null
+++ b/bip-0069.mediawiki
@@ -0,0 +1,169 @@
+<pre>
+ BIP: BIP: 69
+ Title: Lexicographical Indexing of Transaction Inputs and Outputs
+ Authors: Kristov Atlas <kristov@openbitcoinprivacyproject.org>
+ Editors: Daniel Cousens <bips@dcousens.com>
+ Status: Draft
+ Type: Informational
+ Created: 2015-06-12
+</pre>
+
+==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.
+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 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.
+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 Ordering===
+
+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.
+
+Common implementations include:
+
+* `std::lexicographical_compare` in C++ [5]
+* `cmp` in Python 2.7
+* `memcmp` in C [6]
+* `Buffer.compare` in Node.js [7]
+
+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===
+
+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.
+
+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.
+
+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 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 (as a byte-array) will be compared lexicographically, in ascending order.
+If the scriptPubKeys match, the outputs are considered equal.
+
+===Examples===
+
+Transaction 0a6a357e2f7796444e02638749d9611c008b253fb55f5dc88b739b230ed0c4c3:
+
+Inputs:
+
+ <nowiki>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]</nowiki>
+
+Outputs:
+
+ <nowiki>0: 400057456 76a9144a5fba237213a062f6f57978f796390bdcf8d01588ac
+ 1: 40000000000 76a9145be32612930b8323add2212a4ec03c1562084f8488ac</nowiki>
+
+Transaction 28204cad1d7fc1d199e8ef4fa22f182de6258a3eaafe1bbe56ebdcacd3069a5f
+
+Inputs:
+
+ <nowiki>0: 35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055[0]
+ 1: 35288d269cee1941eaebb2ea85e32b42cdb2b04284a56d8b14dcc3f5c65d6055[1]</nowiki>
+
+Outputs:
+
+ <nowiki>0: 100000000 41046a0765b5865641ce08dd39690aade26dfbf5511430ca428a3089261361cef170e3929a68aee3d8d4848b0c5111b0a37b82b86ad559fd2a745b44d8e8d9dfdc0cac
+ 1: 2400000000 41044a656f065871a353f216ca26cef8dde2f03e8c16202d2e8ad769f02032cb86a5eb5e56842e92e19141d60a01928f8dd2c875a390f67c1f6c94cfc617c0ea45afac</nowiki>
+
+==Discussion==
+
+* [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008484.html|<nowiki>[Bitcoin-development]</nowiki> Lexicographical Indexing of Transaction Inputs and Outputs]]
+* [[https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2015-June/008487.html|<nowiki>[Bitcoin-development] [RFC]</nowiki> Canonical input and output ordering in transactions]]
+
+==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]]
+* [[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==
+
+* [[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 &lt;danno@numisight.com&gt;, Sergio Demian Lerner &lt;sergiolerner@certimix.com&gt;, Justus Ranvier &lt;justus@openbitcoinprivacyproject.org&gt;, and Peter Todd &lt;pete@petertodd.org&gt; contributed to the design and motivations for this BIP.
+A similar proposal was submitted to the Bitcoin-dev mailing list independently by Rusty Russell &lt;rusty@rustcorp.com.au&gt;
diff --git a/bip-0069/bip-0069_examples.py b/bip-0069/bip-0069_examples.py
new file mode 100644
index 0000000..e2f52ed
--- /dev/null
+++ b/bip-0069/bip-0069_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()
diff --git a/bip-0070/paymentrequest.proto b/bip-0070/paymentrequest.proto
index 6680810..717946e 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;
diff --git a/bip-0105.mediawiki b/bip-0105.mediawiki
index 7aaef04..cbd309d 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.
diff --git a/bip-0112.mediawiki b/bip-0112.mediawiki
new file mode 100644
index 0000000..c06caf5
--- /dev/null
+++ b/bip-0112.mediawiki
@@ -0,0 +1,246 @@
+<pre>
+ BIP: 112
+ Title: CHECKSEQUENCEVERIFY
+ Authors: BtcDrak <btcdrak@gmail.com>
+ Mark Friedenbach <mark@friedenbach.org>
+ Status: Draft
+ Type: Standards Track
+ Created: 2015-08-10
+</pre>
+
+==Abstract==
+
+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 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.
+
+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 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
+script execution pathway including the CHECKSEQUENCEVERIFY will fail
+to validate, causing the transaction not to be selected for inclusion
+in a block.
+
+
+==Motivation==
+
+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==
+
+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)) {
+ // 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& nInvSequence) const
+ {
+ 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 < 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;
+
+ // 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 lock-time being tested is the same as
+ // the lock-time in the transaction input.
+ if (!(
+ (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 (nInvSequence > txToInvSequence)
+ return false;
+
+ return true;
+ }
+
+https://github.com/maaku/bitcoin/commit/33be476a60fcc2afbe6be0ca7b93a84209173eb2
+
+
+==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 <Alice's pubkey> <Bob's pubkey> <Escrow's pubkey> 3 CHECKMULTISIGVERIFY
+ ELSE
+ <LOCKTIME_THRESHOLD + 30*24*60*60> CHECKSEQUENCEVERIFY DROP
+ <Alice's pubkey> 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 = 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 = 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:
+
+[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-0113.mediawiki BIP 113]:
+Median-Past-Time-Lock.
+
+==Credits==
+
+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 authored 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 65: OP_CHECKLOCKTIMEVERIFY
+https://github.com/bitcoin/bips/blob/master/bip-0065.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==
+
+This document is placed in the public domain.