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

XLS-5d Standard for Tagged Addresses #6

Closed
nbougalis opened this issue Jun 4, 2019 · 48 comments
Closed

XLS-5d Standard for Tagged Addresses #6

nbougalis opened this issue Jun 4, 2019 · 48 comments

Comments

@nbougalis
Copy link

nbougalis commented Jun 4, 2019

  XRP Ledger Proposed Standard #5

  Title:        Tagged Addresses
  Author:       Nikolaos D. Bougalis 
  Affiliation:  Ripple
  Created:      2019-05-15

Abstract

Destination tags provide a way for exchanges, payment processors, corporates or entities which accept incoming payments, escrows, checks and similar transcations to use a single receiving wallet while being able to disambiguate incoming transactions by instructing the senders to include a destination tag.

This draft introduces the concept of a tagged address: an address that contains both the target wallet as well as a destination tag as a single unit.

Motivation

Although flexible, destination tags suffer from several drawbacks.

Communicating a destination tag to users can be a problem for a number of reasons:

  • In the absence of a standard format to represent an (address, tag) pair, different users of destination tags communicate the information in different ways.
  • Users needs to enter two items, usually in two distinct input fields which may be inconsistently or confusingly named (e.g. one implementation refers to the destination tag as a "PIN").
  • Programmers need to decide on how, when or even if the "Destination Tag" field must be surfaced, complicating panel layouts and increasing the potential for user confusion.
  • The tag is an opaque identifier, generated by and meaningful only to the entity that will be receiving funds. Tags do not natively include any kind of checksum or error checking to prevent against common issues such as a user accidentially omitting or transposing digits or otherwiseincorrectly enter a tag.

This proposal seeks to address this problem by defining a standard format to represent an (address, tag) which:

  • Is expressed as a single string that shares all the desirable properties of existing addresses, including the ability to be selected by double-clicking on them.
  • Eliminates the need for a separate "Destination Tag" field by allowing a single format to represent addresses both with and without tags.
  • Includes a built-in checksum as a form of error-checking to reduce the probability that a typographical error will generate a correct address.

Limitations

We are not looking to change the on-ledger format; that is, the new style addresses can't be used for fields where an AccountID is expected in the binary format. Instead, the packed address will be detected and decoded at higher levels (for example, by the client sofware, ripple-lib or the RPC and WebSocket APIs in rippled), verified and then split into distinct fields (e.g. sfDestination and sfDestinationTag) as appropriate, to assemble the underlying transaction.

Philosophy

“The nature of Bitcoin is such that once version 0.1 was released, the core design was set in stone for the rest of its lifetime.”

— Satoshi Nakamoto

While we can propose a standard, we need to contend with the fact that, by design, the basics of the protocol (and that includes account addresses) were fixed the moment the ledger was instantiated. While not completely inflexible, account addresses are deeply embedded into the protocol and even if they aren't part of the "core design" changing them would involve a huge amount of pain.

Not all is lost, however and there are things we can do. In this case, we can define a new address style which incorporates the destination tag and software can be understand such packed addresses, improving the UX for users, while intelligently unpacking such addresses into their constituent parts for the underlying system.

Options

Although we have options in developing a new format, including what encoding to use, ideally the resulting addresses will be similar to existing addresses to reduce the likelihood of user confusion as much as possible and, ideally, not requiring developers to implement a new codec.

Given this constrain, we need to use the Base58Check encoding, leaving us with two options:

  1. A "tightly packed" format, where the address and tag are encoded using Base58Check as a single unit.
  2. A "loosely packed" format, where the address is encoded using Base58Check and the destination tag is encoded separately and appended to the address.

The advantage of the "loose" format is that a tagged address will precisely match the classic address, up to the tag. The "tight" format results in an address that shares no common prefix with the classic address, except, perhaps, by chance.

The disadvantage of the "loose" format is that a tagged address is more complex to detect, encode and decode.

On balance, we feel that although the "loose" could allow for classic and tagged addresses to co-exist, we believe that the "tight" format is a better choice overall.

Status

This is only a proposal. It is my hope that it will generate discussion between developers, community members and other interested parties, and that we will reach consensus on the way forward.

Comments, criticisms, suggestions and improvements are welcome!

Proposal

Addresses and Destination Tags

For a better introduction to addresses and tags, it may help to reference https://developers.ripple.com/accounts.html.

Existing Format

Currently, an address is generated by base58-encoding (with a checksum) a 21 byte buffer:

[← 1 byte prefix →|← 160 bits of account ID →]

The chosen byte prefix is TokenType::AccountID (value 0)

Proposed format

In the proposed format, the address and destination tag are combined into a single 30 byte buffer which is then encoded using the familiar Base58Check algorithm as a single unit, using a new two-byte prefix:

[← 2 byte prefix →|← 160 bits of account ID →|← 8 bits of flags →|← 64 bits of tag →]

The tag shall always be encoded as a little endian two's complement 64 bit integer.

Prefix

The standard proposes using different prefixes, making addresses encoded for use on the mainnet have a different initial character than addresses encoded for use on the testnet, making it possible for users and tools to differentiate addresses.

Network Prefix Initial Character
mainnet 0x05 0x44 X
testnet 0x04 0x93 T

It is important to note: an address encoded for mainnet use could still be used on the testnet and vice versa; tools that understand the new format are encouraged to implement protections.

Flags

Adding a flags field allow us to make this format slightly more flexible than it would otherwise be. At this time, only 3 flags are specified, one of which is reserved and may not be used in practice.

Name Value Description
NO_TAG 0x00 The address is untagged and treated as if no tag had been specified. The remaining 8 bytes MUST be zero.
TAG_32 0x01 The address contains a 32-bit tag. The tag is encoded in little-endian form in the next 4 bytes. The remaining 4 bytes MUST be zero.
TAG_64 0x02 The address contains a 64-bit tag. The tag is encoded in little-endian form in the next 8 bytes. This flag is reserved in case 64-bit tags ever become supported.

Caution

Exactly one of NO_TAG, TAG_32 and TAG_64 MUST be set; implementations should mask of any other fields when checking which of these flags is set.

All flag values not explicitly defined are reserved for future extensions and MUST be set to 0. Implementations that encounter flag values that are unknown should return an error and treat the address as invalid.

Encoding Example

Below we present how the classic address rGWrZyQqhTp9Xu7G5Pkayo7bXjH4k4QYpf would be encoded under this spec to include various destination tags. The tag, if any, is on the left most column. The raw bytes, prior to encoding are shown in the second column. Lastly, we show the resulting base58 encoded address.

Encoding for Main Net

Tag Address Raw Bytes
XVLhHMPHU98es4dbozjVtdWzVrDjtV5fdx1mHp98tDMoQXb 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A000000000000000000
0 XVLhHMPHU98es4dbozjVtdWzVrDjtV8AqEL4xcZj5whKbmc 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A010000000000000000
1 XVLhHMPHU98es4dbozjVtdWzVrDjtV8xvjGQTYPiAx6gwDC 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A010100000000000000
2 XVLhHMPHU98es4dbozjVtdWzVrDjtV8zpDURx7DzBCkrQE7 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A010200000000000000
32 XVLhHMPHU98es4dbozjVtdWzVrDjtVoYiC9UvKfjKar4LJe 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A012000000000000000
276 XVLhHMPHU98es4dbozjVtdWzVrDjtVoKj3MnFGMXEFMnvJV 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A011401000000000000
65591 XVLhHMPHU98es4dbozjVtdWzVrDjtVozpjdhPQVdt3ghaWw 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A013700010000000000
16781933 XVLhHMPHU98es4dbozjVtdWzVrDjtVqrDUk2vDpkTjPsY73 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A016D12000100000000
4294967294 XVLhHMPHU98es4dbozjVtdWzVrDjtV1kAsixQTdMjbWi39u 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A01FEFFFFFF00000000
4294967295 XVLhHMPHU98es4dbozjVtdWzVrDjtV18pX8yuPT7y4xaEHi 44AA066C988C712815CC37AF71472B7CBBBD4E2A0A01FFFFFFFF00000000

Encoding for Testnet

Tag Address Raw Bytes
none TVE26TYGhfLC7tQDno7G8dGtxSkYQn49b3qD26PK7FcGSKE 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A000000000000000000
0 TVE26TYGhfLC7tQDno7G8dGtxSkYQnSy8RHqGHoGJ59spi2 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A010000000000000000
1 TVE26TYGhfLC7tQDno7G8dGtxSkYQnSz1uDimDdPYXzSpyw 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A010100000000000000
2 TVE26TYGhfLC7tQDno7G8dGtxSkYQnTryP9tG9TW8GeMBmd 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A010200000000000000
32 TVE26TYGhfLC7tQDno7G8dGtxSkYQnT2oqaCDzMEuCDAj1j 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A012000000000000000
276 TVE26TYGhfLC7tQDno7G8dGtxSkYQnTMgJJYfAbsiPsc6Zg 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A011401000000000000
65591 TVE26TYGhfLC7tQDno7G8dGtxSkYQn7ryu2W6njw7mT1jmS 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A013700010000000000
16781933 TVE26TYGhfLC7tQDno7G8dGtxSkYQnVsw45sDtGHhLi27Qa 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A016D12000100000000
4294967294 TVE26TYGhfLC7tQDno7G8dGtxSkYQnX8tDFQ53itLNqs6vU 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A01FEFFFFFF00000000
4294967295 TVE26TYGhfLC7tQDno7G8dGtxSkYQnXoy6kSDh6rZzApc69 93AA066C988C712815CC37AF71472B7CBBBD4E2A0A01FFFFFFFF00000000

Advantages

  • Both the account ID and the destination tag are protected by the 32-bit checksum performed by the Base58Check format.
  • We can determine whether the address is packed by casual visual examination of the address, as well by examining the first byte of the decoded data.
  • Any given pair of tagged addresses referencing the same underlying address but with different destination tags will share a long common prefix when encoded.
  • The address is visually distinct from any addresses already in use.

Disadvantages

The primary disadvantage is the untagged address may appear in several places, including things such as trust lines, responses from the rippled API endpoints and more and that can be confusing for users.

Transaction Example

Consider the following transaction submission:

rippled submit secret '{
    "TransactionType":"Payment",
    "Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
    "Amount":"200000000",
    "Destination":"XVLhHMPHU98es4dbozjVtdWzVrDjtV8zpDURx7DzBCkrQE7"
}'

The server would unpack XVLhHMPHU98es4dbozjVtdWzVrDjtV8zpDURx7DzBCkrQE7 to rGWrZyQqhTp9Xu7G5Pkayo7bXjH4k4QYpf and a destination tag of 2, and process the submission as if it had been:

rippled submit secret '{
    "TransactionType":"Payment",
    "Account":"r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
    "Amount":"200000000",
    "Destination":"rGWrZyQqhTp9Xu7G5Pkayo7bXjH4k4QYpf",
    "DestinationTag":2
}'

Obviously the server cannot do this when presented with a pre-signed transaction, although assembling and signing a transaction using an unexpanded packed address shouldn't be possible, since the binary encoding of an AccountID requires exactly 20 bytes.

Third party tools that accept user input should allow users to enter such addresses and transparently expand them prior to signing and/or submitting.

Questions

Below is a list of questions to be addressed as a result of this requirements document:

Should the format include both a source and a destination tag?

Probably not. It's better to simply state that the new format specifies an "address and tag" and to allow such addresses to be used both as a source and as a destination, and to decide the tag's type (source or destination) based on the field.

Can we tweak the encoding so that a packed address shares a common prefix with the actual address?

Not trivially. The Base58 format is quirky and doesn't behave the same way as "power-of-two" encodings, like Base32 or Base16. We could have retained a common prefix by encoding the address and destination tag separately and fusing the two components, but that significantly complicated the decoding process, which is something we sought to avoid.

There's potential for confusion. Can we help?

Users may not understand the semantics of a packed address sufficiently. This means that errors or confusion are possible as a result. Two exchange users might wonder why their deposit addresses are now different. Or one user may ask a friend what the deposit address is and, unknowingly, deposit funds into their friend's account.
The first is obviously not a problem with existing addresses, and the second is less likely to be an issue than these single addresses. The UX of third parties that choose to use the new format will have to make it clear to users that the address is unique for them.

The server could add information to the metadata associated with a transaction to help tools to map addresses. For example, the server could add the following:

"TaggedAddresses": [
    { 
        "XVLhHMPHU98es4dbozjVtdWzVrDjtV8zpDURx7DzBCkrQE7": {
            "Address": "rGWrZyQqhTp9Xu7G5Pkayo7bXjH4k4QYpf",
            "Tag": 2
        }
    }
]

Why not BECH32?

The BECH32 format is great and has several advantages over Base58, including speed. We are defining a new address encoding here, so why not just go for that? It's an option, but we decided to be conservative and not require new code to be written or incorporated into servers, clients and libraries.

What happens if someone specifies one of these addresses in the binary format?

The short answer is that they can't. The serialization field only allows exactly 20 bytes, so only the account itself can fit in. This format is only for base58 encoded addresses and is purely a convenience for users.

Should we integrate this natively into the protocol?

No. It would be a huge change and, potentially, breaking one and there aren't any advantages that I can see. There are many risks. Allowing APIs to understand the new format sufficiently to decompose it into its two constituent fields should be sufficient.

@nbougalis
Copy link
Author

Although this is still a spec / proposal, I'd like to tag some people that are involved with promiment wallets, to ensure visibility and to give them a chance to participate in refining this spec.

Edge Wallet: @paullinator
Ledger: @gre, @EricLarch
Toast Wallet: @codetsunami
XRPTipBot: @WietseWind

Please add others, as necessary.

@WietseWind
Copy link
Member

@nbougalis Thank you! I'm happy to implement this in the projects + libs I'm working on + spread the word (explain it to devs/exchanges/users) once this is implemented. This will definitely help fight user error.

@ihomp
Copy link

ihomp commented Jun 8, 2019

Agreed with "This will definitely help fight user error." +1 to implement it too.

@zquestz
Copy link

zquestz commented Jun 11, 2019

So while I like the proposal. Seems it should also be compared to just having a standard URI format that also allows the destination tag to be included.

<address>?tag=<tag>

This has some advantages:

  1. Address is super clear to the user. This doesn't change.
  2. The URI can clearly show that it is including a destination tag and not require an API call to find the actual destination tag used.
  3. Many wallets are already using the old spec that was similar to this.
  4. Allows extensions that could include amount and other metadata.
  5. Allows for a single QR code, so exchange integration is super simple and doesn't require 2 pieces of data, just one.

Was there a reason this approach wasn't considered? Perhaps I am missing something.

@nbougalis
Copy link
Author

Thanks for the comments @zquestz. I appreciate the question. We did consider this and no, you aren't really missing anything. I simply didn't lay out our rationale for not adopting the URI-style format.

The problem with the URI format is that:

  • you can't select it with a double-click the way you can a Base58-encoded address (one of the primary benefits of the Base58 encoding according to Satoshi);
  • the destination tag doesn't include any kind of checksum. If the string is ?dt=12345 and the user accidentally doesn't copy the 5 there's no automated way to detect it;
  • communicating effectively about destination tags to users can be a challenge.

The URI syntax is (mostly) not subject to these issues primarily because the tools we use to display content where I'd expect to find such URIs embedded will, typically, detect URLs and make them clickable, reducing the possibility of end-user error.

If there's support for this new format, then we should also augment the proposed URI spec to ensure that it includes support for packed addresses and define the expected behavior if a packed address is specified along with a ?tag=.

@WietseWind
Copy link
Member

WietseWind commented Jun 15, 2019

I just published a node/javascript lib. to encode/decode based on the proposal by @nbougalis. The samples and test folder show how it's working.

https://github.com/XRPL-Labs/ripple-tagged-address-codec

https://www.npmjs.com/package/ripple-tagged-address-codec

@junderw
Copy link

junderw commented Jun 17, 2019

  1. On the withdrawal side, to switch over to a new address type, there would need to be a grace period where either the old way or new way is allowed. This requires UX work to not confuse the user even further. Not to mention that this also means our PDCA cycle is then controlled by our competitors (we can't deprecate until our competitors switch, and in the meanwhile we have increased support volume due to confusion) so the first one to support gets the short end of the stick. Every time.
  2. On the deposit side, offering up two addresses confuses users, they paste the new address in a competitor's old address box, and while they are contacting one of either of our support desks, their money is not getting to our exchange, meaning they are not trading on our exchange, meaning... why would we do this?

There needs to be some sort of incentive to switch over, otherwise we're all playing a game where the best course of action for all is to wait for the competitors to bear the cost of educating users and fielding support requests.

Switching to Segwit addresses on BTC etc. has an incentive. Lower fees.

Switching to this new format might decrease destTag mismatch errors, but it will increase confusion and other types of support tickets.

I would much rather a standard for destination tag checksums be created.

ie. increase the size of destTag to 64 bit, take the number you want to use, do some checksum math to get a number from 0-9999. Add that 4 digit checksum to the number multiplied by 10000 etc.

That way:

  1. All exchanges already support it.
  2. We can validate if a destination tag is valid. Offer a button on the error screen saying "I know what I'm doing, ignore the checksum error, the receiving end doesn't support yet." and we're done.
  3. Maybe add a new account param similar to rejectNoDestTag, but rejectInvalidChecksumDestTag. etc.

tl;dr This address proposal will have a hard time with adoption unless someone goes around offering money to exchanges to support it. It would be much better to create a checksum feature to tag on to DestinationTag.

@WietseWind
Copy link
Member

@junderw I think there's incentive at exchanges etc. already, since it will save them a lot of support questions and manual corrections in the long term, users making mistakes with the tags, sending with tag zero, etc.

Of course it would take a (relatively long) period where users can use both formats, but that's relatively easy to explain. I may even put up a small website with a address+tag converter & explanation so all platforms can link to that info.

I agree @ the confusing part, but with a few lines and both options and a decent UI it should work. If we want to improve the destination tag user experience (so: not a separate tag but one checksummed packed address you can easily copy-paste at once) now is the time to do it, since there aren't that many users in the grand scheme of things.

@junderw
Copy link

junderw commented Jun 17, 2019

Of course it would take a (relatively long) period where users can use both formats, but that's relatively easy to explain. I may even put up a small website with a address+tag converter & explanation so all platforms can link to that info.

99% of people using exchanges are not the type to go on twitter to find a guy who made a converter, or even people that would even regularly check any of Ripple Labs' official channels to read about the change.

Most users get 100% of their info from the exchanges they use, and the support teams of those same exchanges.

Obviously having a conversion site would be a great resource our support team could link to, but it will still require a significant load on Customer Support.

it will save them a lot of support questions and manual corrections in the long term, users making mistakes with the tags, sending with tag zero, etc.

These problems are just as easily fixed with an officially supported destination tag checksum. Even a 2 digit base-10 checksum will catch 99% of mis-entries. And if our account has the noInvalidDestTag active, tag 0 will be rejected by the network, since tag 0 would actually be whatever the checksum for 0 is. With a 2 digit checksum let's say it would be 42. then 1 would be 185 then 2 would be 291 etc etc. In which case, the only possible valid-checksum tag below the checksum threshold would be 42.

But with the currently proposed new-address system, this problem is only solved under the assumption that our competitors support withdrawals using the new address. AND assuming that we offer both encodings and the competitor does not dynamically detect the addresses during withdraw (ie. they make the user flip a switch) it could be possible that they get stuck trying to send to us, and they lose valuable trading time that could have been performed on our platform instead of our competitor's while they wait for support to answer their question.

I agree that the destination tag being a separate entity was a bad idea to start with.

But right now, we have to weigh the decision "will supporting this new format end up being a plus or minus for us?" and I am not fully convinced it will be a plus. So it won't be implemented it until exchanges see it as a plus.

I personally am not convinced.

@intelliot
Copy link
Collaborator

The "two's complement" mention in this proposal doesn't make sense to me since tags are unsigned integers

@RichardAH
Copy link
Collaborator

Good point. Unless there’s a reason we would want negative dest tags under the 64bit standard that just serves to confuse

@ximinez
Copy link
Collaborator

ximinez commented Jun 18, 2019

These problems are just as easily fixed with an officially supported destination tag checksum.

Hi @junderw . Could you clarify what you mean here by "officially supported"?

@junderw
Copy link

junderw commented Jun 18, 2019

ie. similar to asfRequireDest, a new flag called asfRequireDestChecksum could tell the network to reject deposits that have a dest tag with invalid checksum.

with 32 bits being so low, a 2 digit (base 10) checksum is all we could spare... but it helps.

However, if the network actually rejected transactions for us it would help.

Not to mention if there was a standard we could add withdrawal validation.

Thanks.

@nbougalis
Copy link
Author

@junderw, thanks for your comments. I like the idea of a destination tag checksum and it could address one of the problems this proposal aims to solve, but as you point out there is an issue with the number of available bits to spare for a checksum, which would have to be fixed for this to be, as you wrote, "officially supported" (i.e. well defined and part of the protocol, so that rippled could verify the checksum).

Even if implemented, the checksum addresses only one problem though. In my experience a separate address and destination tag pose a challenge for users, exchanges and wallets and the tagged addresses could help improve the UX for users.

In a perfect world, using a well-defined URI (see issue #3) would be enough, but we don't live in a perfect world.

I will grant you that the tagged address system isn't perfect. But, imo, it's better than the existing alternative.

@junderw
Copy link

junderw commented Jun 18, 2019

perhaps a feature request for a dtag checksum should be separate thing.

As far as this address proposal is concerned, "needs a much larger incentive then currently exists", and "early adopter exchanges have a high cost for zero benefit (99% of deposit/withdraw are to other exchanges, so it won't get used at all until other exchanges use it)

"If only this were implemented from the beginning" is the sentiment.

@junderw
Copy link

junderw commented Jun 18, 2019

An extreme example of a "chicken and egg" problem.

Ripple Labs should get behind this and offer incentives / dev resources to integrate.

That's the only way I see this getting adoption.

@ihomp
Copy link

ihomp commented Jun 20, 2019

In my opinion it's possible to get attention of some big exchangers. If they see such implementation is worth the hassle as it dramatically decrease all the xrp tickets with missed/incorrect destination tags, then they will do it. Some exchangers didn't want to support BCH or ETH, but anyway started to support it as they saw a profit in it. Changing old Ripple logo to a new XRP logo didn't bring much profit to exchangers, but they still managed it (probably because of xrp community power).

To minimise confusion the update can be cooperated, and best UI practises for a transition period can be shared. Roll out schedule, and announcement across different platforms also can be synced.
Smaller exchangers will probably follow bigger ones.

@WietseWind
Copy link
Member

@ihomp I completely agree. I'm working on a simple website with option for community translations where with a simple explanation, some samples and an encoder/decoder, so clients and exchanges can link to that site if they want to allow people to read more about it.

@WietseWind
Copy link
Member

WietseWind commented Jun 20, 2019

Added all proposal into one lib that encodes+decodes for node, & info in the Readme:

https://github.com/xrp-community/xrpl-destination

And it's really hard to pick one;

Existing
+ Everybody knows it
- Lots of mistakes

Packed
+ Tech is the best, easiest for all programming languages, no double checksum
- Existing address not recognizable

Appended
+ Easy to spot the existing address at the start
- (Beautiful and creative) Hocus pocus encoding/decoding (harder to build in all programming languages

X-Address
+ Existing address recognizable at the end
+ 😎 Starts with an "X" so easy to communicate to users, "You can use the X format here"
- Hard to spot the existing address, Invalid alphabet with the zero (not in the ripple encoding alphabet)

@sublimator
Copy link

@nbougalis

Doesn't seem to be much progress here?

My "proposal" was mostly just some fun, but I regret even putting it out there, as it's just a spanner in the works. I got another email from some poor soul that lost money. Interesting to note that they didn't realize the destination tag changed per transaction at the particular gateway.

This is still a real problem.

@intelliot
Copy link
Collaborator

That's odd. Does the gateway actually lose funds after the first transaction to a particular destination tag?

If you haven't already, review the following proposal: https://github.com/intelliot/x-address-proposal

Gateways can encode an optional expiration timestamp into the address, which would ensure that the address would become invalid after e.g. 24 hours. Of course, this requires support from the client wallet, but I'm optimistic that we can get that to happen, especially since we will provide implementations in JavaScript and C++.

@sublimator
Copy link

sublimator commented Jul 15, 2019 via email

@RichardAH
Copy link
Collaborator

I'm in support of changing the prefix in xls5d to x or similar. It's too confusing to users otherwise

@WietseWind
Copy link
Member

@sublimator @codetsunami Agree. I'm opting for the proposal by @nbougalis (since it's a really clean solution) but changing the prefix to map to an x instead of an r for end user recognisability (+1 for @intelliot for this idea!)

I'll be coding a TS implementation this week 👍

@sublimator
Copy link

sublimator commented Jul 15, 2019 via email

@RichardAH
Copy link
Collaborator

@sublimator just to be clear no one will lose their money for lack of providing a dest tag. It is the exchange/counterparty not doing the right thing (i.e. returning un-tagged payments) which is the issue there. Obviously making an address format where the tag can't be accidentally excluded helps but the fault for lost funds remains with the exchange/counterparty. It's not as though the XRP is burnt by the network if the dest tag is excluded.

@intelliot
Copy link
Collaborator

If the issue is that the user sent to an old "used" destination tag, then I'm not sure how a new format would help them.

If the gateway reuses destination tags after a period of time (e.g. 24 hours or 7 days or whatever) then having an expiry encoded in the address would help.

@RichardAH
Copy link
Collaborator

Building hundreds of bells and whistles into the address format can't actually reduce irreducible complexity. It can improve UX, that's about it. If the exchange has transient endpoints the user needs to be aware of this no matter what.

Imho making expirable address formats will cause at least as much confusion as it solves. Imagine sending someone an endpoint you know is correct only to have the payment rejected because the endpoint expired. Bad UX.

@intelliot
Copy link
Collaborator

Correct: improving UX is the goal here, and it is pretty important. What do you mean by "endpoint"?

Having the payment rejected with 'invalid address' is a much better UX than losing funds.

@RichardAH
Copy link
Collaborator

An endpoint is a location to pay to

@sublimator
Copy link

sublimator commented Jul 17, 2019 via email

@nbougalis
Copy link
Author

nbougalis commented Jul 24, 2019

Expiring addresses face another problem: if I look at an account’s history on an explorer like bithomp, I’ll be unable to see expiring addresses even for transactions where I used them, since the necessary information (expiration time) isn’t available, although workarounds could be developed (e.g. waste could store the expiring addresses as a memo).

Knowing I sent to Xsomsthingsometgung but seeing the transaction sent funds to rWhateverHere is bad UX and liable to cause some heartburn. The whole point of this spec is to be transparent to users and it seems to me that the expiring address format would actually require that users learn more—above and beyond what they already know.

With this spec, both the classic and the tagged address can be displayed since all the infrormation displayed, which alleviates this issue I think.

@sublimator
Copy link

sublimator commented Jul 25, 2019 via email

@RichardAH
Copy link
Collaborator

Knowing I sent to Xsomsthingsometgung but seeing the transaction sent funds to rWhateverHere is bad UX and liable to cause some heartburn.

I hadn't thought of this but yes chain explorers will struggle to display up to 2^32 'X' addresses for every 1 'r' address. No problem if they enter the 'X' address for the lookup, but if they enter an 'r' address and want to find all 'X' addresses, for an exchange account this will be impossible to display.

@sublimator
Copy link

sublimator commented Jul 25, 2019 via email

@RichardAH
Copy link
Collaborator

RichardAH commented Jul 25, 2019

@sublimator yes I’m saying that looking up a packed address in an explorer is fine, but if you look up a regular address in an explorer there’s a good chance the explorer won’t be able to tell you all the packed addresses that have been used for that regular address. Consider an exchange account with a new dtag for each deposit. There would be hundreds of thousands or more packed addresses to display. May not be a real issue but in terms of user cognition of which addresses are associated with which ledger account there’s a break there.

@WietseWind
Copy link
Member

@codetsunami I guess the explorer will only show them when they apply, on a per tx basis.

@sublimator
Copy link

sublimator commented Jul 25, 2019 via email

@RichardAH
Copy link
Collaborator

@WietseWind it’ll have to be something along those lines yeah. But I can see for new users how this will be even more confusing that dtags were to begin with. In a sense we’ve traded input complexity for cognitive complexity— now users need to understand two types of addresses and how they’re linked. Ultimately probably not a bad trade-off if it prevents people losing their funds. I’m still of the opinion concatenating the base58 encoded dtag onto the end of the original address would have been optimal. That way the user could still clearly see it’s the same address but with a bit of routing info on the end.

@WietseWind
Copy link
Member

@codetsunami But the two addresses (r.... / X...) will only be during a migration. That will take a year or so, but it's temporary. Once most platforms added support the deprecation of showing the r... address can start.

@RichardAH
Copy link
Collaborator

@WietseWind you may be right, time will tell

@nbougalis
Copy link
Author

Like anything, adoption will be key. Consider how BCH migrated to a new address format.

@keefertaylor
Copy link

There are two libraries that do encoding (in JS):

These two libraries have the same implementation, but use different parameters from the test. Ripple's homegrown library favors test while XRPL-Tagged-Address-Codec favors testnet. In turn, this means http://xrpaddress.info disagrees with the library produced by Ripple.

I don't have an opinion on which is better, but I do think it would be great to standardize to reduce user confusion (and selfishly, I'm about to expose this parameter in another library and want to know what to call it).

Elliot mentioned that he thinks testnet is misleading because these addresses can also be used on DevNet or other dev networks. I tend to agree with this rationale.

Do folks have thoughts here? Could we converge these implementations?

@WietseWind
Copy link
Member

WietseWind commented Dec 16, 2019

I agree. I will rename testnet to test tonight/tomorrow :)

@intelliot
Copy link
Collaborator

@WietseWind Here's a PR: xrp-community/xrpl-tagged-address-codec#3 but feel free to ignore it if you have a better way :)

@WietseWind
Copy link
Member

@intelliot Thanks a lot! I already prepared the changes myself (incl. a little more find/replaces changes in the tests) so I just pushed that one, but I really appreciate it.

Updated the site as well.

Thanks everybody!

@WietseWind
Copy link
Member

Note: embedded in Code section:
https://github.com/XRPLF/XRPL-Standards/tree/master/XLS-5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

11 participants