Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalized CashAddr #259

Open
wants to merge 5 commits into
base: master
from

Conversation

Projects
None yet
6 participants
@m4ktub
Copy link
Contributor

commented Jan 16, 2019

The goal of this pull request is to generalize the CashAddr specification so that it can be used with new address types, like stealth/reusable addresses that need more than an hash as payload. The changes can be summed up to:

  • Expand the purpose of the prefix to refer to use case differentiation (e.g.: SLP).
  • Change the interpretation of the 3 least significant bits of the version byte, now renamed type byte, to allow a different meaning for each type.

Although the goal was to preserve backward compatibility, the revision of the size bits mean the test implied by some test vectors (those with type 15) changed, that is, addresses with an unknown type can no longer be length checked from the size bits alone. For that reason those test vectors were segregated to a new section and with new payloads.

@monsterbitar

This comment has been minimized.

Copy link
Contributor

commented Jan 17, 2019

The prefix description states that bitcoincash:, bchtest: and bchreg: are reserved for "main net", "test net" and "reg test".

These are not exclusive applications but merely networks and as such SLP could just as well have been using them. I suggest to either clarify that networks are not a support prefix type, and that the reserved types refer to "payments on " instead.

@markblundeberg

This comment has been minimized.

Copy link
Collaborator

commented Jan 18, 2019

CashAddr is specifically concerned with actual addresses, i.e., it's a human representation of certain standard scriptPubKey forms. My suggestion is that if the prefix is not bitcoincash: / bchtest: / etc., then there should be no restrictions at all, and it is outside the scope of CashAddr so this document does not need any changes.

If people want to come up with an "address" scheme for some other system that is not actual addresses, nothing stops them from using a URI prefix mystealthaddr: with a base32 encoding. What comes after that is up to their specification (they can of course borrow concepts like the checksum, if they want). But just because something is URI prefixed with base32 payload, doesn't mean it's CashAddr.

Besides that it seems strange to preemptively restrict the first bit like this for all protocols. For example, maybe I want my stealth "address" system to look like stealthaddr:s..... The spec forbids this, so why should I follow this spec?

@m4ktub

This comment has been minimized.

Copy link
Contributor Author

commented Jan 18, 2019

CashAddr is specifically concerned with actual addresses, i.e., it's a human representation of certain standard scriptPubKey forms.

I understood that perspective better from my interactions with Deadalnix over Twitter.

My suggestion is that if the prefix is not bitcoincash: / bchtest: / etc., then there should be no restrictions at all,

That was also my suggestion, in the end. Either people agree with this change or the spec should be reviewed to remove the specification of the first byte in the payload. I have doubts about the ability to make a v1.1 in that case but I haven't investigated the implication with more detail yet.

and it is outside the scope of CashAddr so this document does not need any changes.

I disagree. This specification makes simpleledger addresses a perfectly valid CashAddr. Those are even accepted by Copay's library which implements this spec.

If people want to [...]

I believe that having a specification that allows legitimate reuse for several purposes without ambiguity is a plus for adoption and usability. Currently, as I see it, this specification only states its scope through the inability of allowing anything else while creating the expectation of being the "one" format for everything the user perceives as addresses (because a random string of characters, or QR code, is indistinguishable from another to users).

Going back to the first point, I'll try to review the specification again from that perspective. It seems harder to make a backward compatible and coherent specification but I haven't tried yet.

@BigBlockIfTrue

This comment has been minimized.

Copy link

commented Jan 18, 2019

I think it makes a lot of sense to integrate stuff like stealth addresses into the CashAddr spec by defining new address types beyond P2PKH and P2SH:

  • User experience for the address field. While stealth addresses do not appear as such on the blockchain, from an UX point of view, they still function as addresses. It is something a user will have to put in an address field. It should therefore look like an address. The similarity to any other Bitcoin Cash address should be maximal. This can only be achieved if they're defined by the same CashAddr specification in a mutually consistent way.
  • Optionality of the prefix. On the mainnet, the bitcoincash: prefix is optional, avoiding unnecessary verbosity if it's clear from the context that something is a Bitcoin Cash address. Having a mandatory prefix for some address types is unnecessarily confusing. Just imagine P2PKH and P2SH would have different prefixes and P2SH's would be mandatory; it would probably be rather weird the first time you use P2SH, non-technical users who didn't use the optional prefix before might even think bitcoincash-p2sh: were some kind of hacking code. I am not aware of any traditional payment system where account numbers have a mandatory prefix like this either.
  • Clean URI scheme handler association. If every address type requires a separate handler registration mapping the URI scheme to the wallet software, wallet software will need to register every one of them separately, which is both error-prone. It is furthermore collision-prone with other IANA registrations or other software, and the likelihood of such collisions can only be reduced by making the prefixes long, which in turn damages usability. Unlike SLP, the different address formats are intended to spend the same Bitcoin Cash, so it makes sense to use it as a single URI scheme. If the associated wallet software does not support the address type, it can simply notify the user.
@deadalnix

This comment has been minimized.

Copy link
Contributor

commented Jan 25, 2019

Ok, First thing first, what is actually needed to encode a stealth address ?

@markblundeberg

This comment has been minimized.

Copy link
Collaborator

commented Jan 25, 2019

@deadalnix At minimum a stealth payment code system could be easily done with encoding a single pubkey (33 bytes) -- everything could be based on / derived from that. BIP47 payment codes are however 80 bytes long because BIP47 likes to make things overcomplicated.

@m4ktub

This comment has been minimized.

Copy link
Contributor Author

commented Jan 25, 2019

There's no formalized specification. Looking at Copay's PR#1893, which uses Peter Todds' proposal, we can see that the payload's data would contain:

  • Options (1 byte)
  • Scan Public Key (33 bytes)
  • Number of Spend Public Keys [Nk] (1 byte)
  • Nk x Spend Public Keys (33 bytes)
  • Number of Required Signatures (1 byte)
  • Prefix Length In Bits [Pb] (1 byte)
  • Prefix Data (Pb / 8 bytes)

This format is intended to allow P2PKH, multi-sig P2SH, and SPV filtering through an output prefix. The minimum payload size, for this format, is around 71 bytes. There's a size above which it's impractical to encode the stealth address. I think @matiu suggested considering uses cases of n-of-m up to m = 3.

m4ktub added some commits Jan 16, 2019

Avoid assumptions about size in version byte
Reviewed specification to clear terminology and generalize the address format in relation to the size bits.

@m4ktub m4ktub force-pushed the m4ktub:spec-cashaddr-1 branch from 4b02d5f to 9c0476d Jan 25, 2019

@m4ktub m4ktub referenced this pull request Jan 30, 2019

Open

Open CashAddr #266

@m4ktub

This comment has been minimized.

Copy link
Contributor Author

commented Jan 30, 2019

@deadalnix @markblundeberg With PR #266 there's now the revisions under two different approaches.

This one tries to keep the payload structure, for all prefixes, but redefines the type byte to have the ability to create new types. The one in PR #266 unconstraints the payload structure for prefixes not covered by the specification.

@deadalnix

This comment has been minimized.

Copy link
Contributor

commented Feb 5, 2019

Looking at the spec from @matiu it really does sounds like the first step here is to actually figure out what we want for stealth addresses to begin with. Depending on the result, we can see what kind of addresses is the best. It does look like that what will be sent will very much be some kind of complex datastructure, especially if we want to support multisig and alike. Maybe the best is just to send a JSON over the wire ?

@m4ktub

This comment has been minimized.

Copy link
Contributor Author

commented Feb 5, 2019

Although I've mentioned it as a goal, I would like to separate the revision of the specification from any specific proposal for a new address type. As is, the specification does not allow anything other than a fixed size hash to be encoded. So I see two options:

  • Clarify and reinforce that position. In my opinion, this forces wallets to find another encoding for new address types since any address in the form of <prefix>:<data><checksum> is covered by the specification.
  • Review the position. This promotes consistency between address types and wallets, as it reuses conventions and checksum computation.

I prefer the later and both this PR and #266 go in that direction.

Note: There might be a mismatch in expectations for the CashAddr specification. I, for example, expected CashAddr to be equivalent to Base58Check. Nevertheless the specification defines not only an encoding and checksum scheme but also a specific interpretation of the version byte which limits the reusability of CashAddr.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.