BIP321: use a valid base58 example address, warn against paying it - #2230
BIP321: use a valid base58 example address, warn against paying it#2230fametrano wants to merge 1 commit into
Conversation
|
For completeness: there is a smaller variant of this same approach that #119 did not consider. Instead of swapping in a different address, just repair the checksum of the one already there. It is a one-character change: How I derived it: base58check-decode the existing string to its 25 bytes, keep version byte + hash160, recompute the checksum, re-encode.
Only the final character changes, and it is the unique fix: brute-forcing all 58 base58 characters in the last position yields exactly one valid address, Why I did not do it this way. Repairing the checksum restores the original address, which per that same comment was the one on the Wikipedia Bitcoin page at the time — i.e. a real address belonging to someone else, plausibly still monitored. On the accidental-payment axis that is strictly worse than #119's choice: funds sent to a mangled address bounce off the wallet's own validation, funds sent to a resurrected third-party address are simply gone. It also leaves So the one-character fix is the smaller diff but the larger hazard, and #119's My overall preference remains #2229 — no spendable address anywhere in the document. But if maintainers prefer this route and want the minimal diff, say so and I will reduce this PR to the single character. |
Revives bitcoin#119, closed in 2015 for lack of author consensus. 175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W has a deliberately broken checksum -- the address from the Wikipedia Bitcoin page of the time with its final character replaced -- while every other address in the document, the bech32 and bech32m examples added after the fork from BIP 21, has a valid checksum. That inconsistency has a documented cost: users have filed URI-parsing bugs against wallets after copying URIs straight out of the document (schildbach in bitcoin#119), and the examples cannot be used as test vectors as they stand (evoskuil in bitcoin#119, who opened it for exactly this reason). Use 1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L, the replacement bitcoin#119 proposed. It is BIP 20's example address, where it is already paired with the same label=Luke-Jr used here, so the labels in the examples stay coherent -- luke-jr's objection in bitcoin#119. Every address in the document is now valid and parseable, so the examples work as test vectors, and a note states that they are illustrative and must not be paid. That addresses laanwj's objection in bitcoin#119 -- that valid example addresses are spendable ones -- by warning the reader rather than by breaking the encoding. Alternatives: bitcoin#2228 and bitcoin#2229, which keep the addresses unspendable instead. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
459565f to
932d3f0
Compare
|
Force-pushed: the PR now also adds a note, which it previously argued was unnecessary.
Rationale for the change of mind: making every address valid fixes the parsing complaints in #119, but on its own it leaves @laanwj's objection from that thread unanswered — a valid address is a spendable one. Warning the reader answers it without breaking the encoding, so the examples stay usable as test vectors. Note that this wording makes no claim about checksum validity, unlike BIP 21's note, so it remains true whichever addresses the document ends up carrying. The title and description are updated accordingly. My preference is still #2229. |
|
I'd suggest closing this one in favor of #2229. |
This revives #119, which @laanwj closed in 2015 for lack of author consensus. One of three mutually exclusive options for the same problem — see the table at the bottom. My preference is #2229, not this PR; this one is here so the option is stated explicitly rather than assumed dead.
The inconsistency
BIP 321's base58 example address has a deliberately broken checksum, but the bech32/bech32m examples added after the fork from BIP 21 do not follow that convention:
175tWpb8K1S7NmH4Zx6rewF9WQrcZv245Wbc1qufgy354j3kmvuch987xe4s40836x3h0lg8f5n2bc1p5swkugezn97763tl0yty6556856uug0q6jflljvep9m4p7339x5qzyrh4gtb1qghfhmd4zh7ncpmxl3qzhmq566jk8ckq4gafnmgThree of the four are already valid, so the document is inconsistent either way. #2228 and #2229 resolve it downward (document, or extend, the invalidity). This PR resolves it upward.
This PR
Two changes:
1NS17iag9jJgTHD1VXjvLCEnZuQ3rJED9L, the replacement proposed in Replace invalid example address with bip20 address #119, at all 16 occurrences. Every address in the document then has a valid checksum, so all the example URIs parse and can be used as test vectors as they stand.The note is the part that answers @laanwj's objection in #119 — that a valid example address is a spendable one — by warning the reader instead of breaking the encoding. Unlike BIP 21's note, it makes no claim about validity, so it stays true regardless of which addresses the document carries.
Why that specific address: it is BIP 20's example address, and BIP 20 already pairs it with the same
label=Luke-Jrthese examples use, so the labels stay coherent — the objection @luke-jr raised in #119 ("maybe change the label to something else too, if it isn't going to be my address"). Verified as a valid P2PKH mainnet address.The case for it, from the #119 thread
The case against, which closed #119
A note is a weaker guarantee than an unspendable string: it protects the reader who reads it, not the one who copies a URI out of a code block. The RFC analogy @laanwj drew (documentation IP ranges) argues for keeping example addresses structurally unusable, and this PR would take the document from two spendable mainnet addresses to four. That is why I still prefer #2229.
@laanwj also suggested a middle path in that thread: use testnet addresses throughout, so the examples are valid and parseable but accidental payments are harmless. That would be a fourth option, and a larger change than any of these three; happy to prepare it if that is the direction maintainers prefer.
There is also a smaller variant of this PR's approach — repairing the existing address's checksum in place, one character — which I worked out in a comment below. It has the smallest diff of anything discussed here and the largest hazard, because it resurrects a real third-party address.
The three options
Only one should be merged; I'll close the other two.
My preference is #2229. It is the only one of the three that leaves no spendable address anywhere in the document, it makes BIP 21's existing wording literally true here so the two documents stay in sync, and the whole cost is four characters. #2228 is the minimal-diff fallback if maintainers would rather not touch strings that downstream implementations may already be using as test vectors. This PR is the one I would close first.