From e53d2b9416f6cb29db1e6f526d6ab4028cd1a548 Mon Sep 17 00:00:00 2001 From: Steven Braeger Date: Sat, 19 May 2018 04:05:24 -0400 Subject: [PATCH] Add a backwards-compatible proposal for future-proofing the type-bits The current CashAddr specification includes a version byte that has a 4-bit field to represent the 'type' of the address. Although 16 possible address types seems like a lot considering we currently only have two, it could become necessary to extend the CashAddr format quickly if we ever start to have more than that number. Considering that BCH is re-enabling future opcodes, we might need more than 15 address types sooner rather than later. In that hypothetical, it would be better to have extended it now, while there are fewer implementers, because the later we extend it, the more CashAddr implementations will exist in the ecosystem and extending it will be harder. Any such extension would need to also be backwards-compatible with the current behavior for all currently supported version bits, in order to not break existing code. Furthermore, it would be better to re-use existing methods that are tested in existing node/wallet code. This proposal means that wallets won't be pressured to upgrade existing code until we start to get close to 16 types. This change is a pull request in the spec implementing a possible way to extend the 'type' space but achieve both goals (backwards compatibility, simplicity of implementation, doesn't break existing wallets). It changes the version 'byte' into a version "VarInt" which incidentally parses exactly the same for existing types 0-15, while allowing an essentially infinite number of types in the future. It also uses code that is likely to already exist and be well tested in any environment where CashAddr is implemented. It is referenced by https://github.com/bitcoincashorg/spec/issues/49, but is not solely useful in that context. If necessary, I can also write test-vectors and a few implementations. --- spec/cashaddr.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/spec/cashaddr.md b/spec/cashaddr.md index 114ee0b25..aa89b644b 100644 --- a/spec/cashaddr.md +++ b/spec/cashaddr.md @@ -39,13 +39,14 @@ The payload is a base32 encoded stream of data. | +24 | c | e | 6 | m | u | a | 7 | l | The payload is composed of 3 elements: -1. A version byte indicating the type of address. +1. A version variable-sized integer [[4]](#varint) 2. A hash. 3. A 40 bits checksum. -#### Version byte +#### Version VarInt +The version varint is between 8 and 72 bits representing a variable-sized integer as defined in [[4]](#varint). -The version byte's most signficant bit is reserved and must be 0. The 4 next bits indicate the type of address and the 3 least significant bits indicate the size of the hash. +The 3 least significant bits of the version varint indicate the size of the hash. | Size bits | Hash size in bits | | --------: | ----------------: | @@ -60,7 +61,9 @@ The version byte's most signficant bit is reserved and must be 0. The 4 next bit Encoding the size of the hash in the version field ensure that it is possible to check that the length of the address is correct. -| Type bits | Meaning | Version byte value | +The higher bits (bits 3 and above) of the version varint indicate the "type" of the address. The version varint *must* use the minimum possible sized encoding for the integer it represents. (e.g, a version int of 8 must be represented by 1 byte 0x08, and may not be represented by 0xFD0008) + +| Type bits | Meaning | Version varint value | | --------: | :---------------: | -----------------: | | 0 | P2KH | 0 | | 1 | P2SH | 8 | @@ -154,3 +157,5 @@ The following addresses are given in the legacy and new format. [2] https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki [3] http://www.thonky.com/qr-code-tutorial/alphanumeric-mode-encoding + +[4] https://en.bitcoin.it/wiki/Protocol_documentation#Variable_length_integer