A proposal for user-friendly asset addresses

283 views
Skip to first unread message

Leigh McCulloch

unread,
Jun 11, 2020, 5:00:35 PM6/11/20
to Stellar Developers
Hi all,

I've been finding that reading and typing assets in the form of their asset code and issuer is painful because issuer addresses are long. I think there could be value in defining a common format to define user-friendly asset addresses that resolve to the issuer address. This could be implemented by any client without any new server technology by leveraging existing stellar.toml files.

I've posted a full proposal at stellar/stellar-protocol#639, but in summary we could define a format {asset-code}:{asset-domain} and a process where by a client retrieves the stellar.toml of the asset domain to resolve the asset's issuer address which is stored in the file.

Example:
The asset address USD:example.com could resolve to USD:GA2...VAH if example.com hosts the stellar.toml with the USD code and an issuer defined as GA...VAH.

I'd love to hear if others believe this would be useful, if anyone is already doing anything like this, and how it could be improved.

Cheers,
Leigh

Jem

unread,
Jun 12, 2020, 8:07:59 PM6/12/20
to Stellar Developers
This seems like a good idea. Assets need a more succinct method for addressing.

I note the change in cardinality though. The proposal would not serve a domain with many accounts of which some issue assets with the same code. 

e.g. USD:foo*example.com and USD:bar*example.com could not be differentiated by USD:example.com

I do not know if this is a case we actually see in the wild.

What if the addressing scheme could be extended to include federated addresses instead of domains where differentiation is required, as per the example above? 

Leigh McCulloch

unread,
Jun 15, 2020, 11:22:48 PM6/15/20
to Stellar Developers
That would work for sure, and also has the advantage that it is building on the standard way to resolve an address.

It comes with some costs:

1. It requires running a federation server. Many token issuers already host a stellar.toml, but the effort to adoption is much higher to host another service.

2. It's not clear what valuable information that is relevant to the consumer would live in the federated address username. USD:example.com tells the user that the asset is USD issued by the brand/company example.com, where-as USD:usdcommon*example.com has got more concepts in it, and even if the username is useful to be able to issue the same asset code from multiple issuers, that is probably going to be confusing to a consumer.

As you allude I don't think the multi-issuer per asset code on the same domain capability is frequently used. I ran a query on the public Stellar data set and of the 222 asset codes that had more than one issuer on a single domain only one domain had a stellar.toml containing an asset code more than once, tokenz.store.

This was the query I ran on the crypto-stellar dataset:
SELECT COUNT(*) AS count, assets.asset_code, accounts.home_domain
FROM `crypto-stellar.crypto_stellar.history_assets` AS assets
INNER JOIN `crypto-stellar.crypto_stellar.accounts` AS accounts ON assets.asset_issuer = accounts.account_id
WHERE accounts.home_domain IS NOT NULL AND accounts.home_domain != ''  
AND assets.asset_code != 'REMOVE' AND assets.asset_code != 'PLUG'
GROUP BY 2, 3
HAVING count >= 2
ORDER BY 1 DESC

A limitation of the test I ran was that I assumed the issuer account had a home domain set, so this definitely isn't exhaustive proof.

I think asset addresses should be geared towards consumers and so I think it's worth limiting asset addresses to not work with all cases to keep them simpler. We could opt for both federated and non-federated, but I'm not sure the complexity rise with doing both comes with enough benefits.

Leigh

mister...@cosmic.plus

unread,
Jun 17, 2020, 2:17:25 AM6/17/20
to Jem, Stellar Developers
That's how Cosmic.link does it:


It's also possible to extend federated addresses to resolve to assets by adding an `asset_code` field. We'd have gils*cosmic.plus return:

```
{
 account_id,
 asset_code,
 stellar_adress
}
```

It could be used to address both the destination (e.g: when burning asset) and the asset itself. That change is backward compatible.

Worth noting, addressing assets this way is not as robust as using code/issuer and offers a wider attack surface. (TOML & federated server)

This could be partially mitigated by using DKIF (https://galactictalk.org/d/789-domainkeys-identified-federation-dkif).

MisterTicot

--
You received this message because you are subscribed to the Google Groups "Stellar Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stellar-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/stellar-dev/ba88cf8c-73b6-449c-a702-5e811e224d48o%40googlegroups.com.

Leigh McCulloch

unread,
Jun 22, 2020, 2:01:28 PM6/22/20
to Stellar Developers
Hi MisterTicot,

Thanks for sharing how cosmis.link does resolution. Do you also do reverse resolution or use home domains to verify that the issue approves of the domain being used as a reference or is it one way and no verification?

Using existing federation makes it easier for wallets since they can split on the colon and lookup using existing federation clients, but we can also add a client specifically for asset addresses to SDKs so that benefit is easily absorbed.

Looking at some asset issuers' stellar.toml files I'm not seeing FEDERATION_SERVER fields, so the burden to asset issuers is higher as they'd need to deploy a new service to provide a mapping for likely only 1 address; that seems like a large overhead to me. Have you seen many asset issuers use federation?

Leigh


On Tuesday, June 16, 2020 at 11:17:25 PM UTC-7, miste...@cosmic.plus wrote:
That's how Cosmic.link does it:


It's also possible to extend federated addresses to resolve to assets by adding an `asset_code` field. We'd have gils*cosmic.plus return:

```
{
 account_id,
 asset_code,
 stellar_adress
}
```

It could be used to address both the destination (e.g: when burning asset) and the asset itself. That change is backward compatible.

Worth noting, addressing assets this way is not as robust as using code/issuer and offers a wider attack surface. (TOML & federated server)

This could be partially mitigated by using DKIF (https://galactictalk.org/d/789-domainkeys-identified-federation-dkif).

MisterTicot
Le 13 juin 2020 02:07, Jem <jem....@gmail.com> a écrit :
This seems like a good idea. Assets need a more succinct method for addressing.

I note the change in cardinality though. The proposal would not serve a domain with many accounts of which some issue assets with the same code. 

e.g. USD:foo*example.com and USD:bar*example.com could not be differentiated by USD:example.com

I do not know if this is a case we actually see in the wild.

What if the addressing scheme could be extended to include federated addresses instead of domains where differentiation is required, as per the example above? 



On Friday, 12 June 2020 07:00:35 UTC+10, Leigh McCulloch wrote:
Hi all,

I've been finding that reading and typing assets in the form of their asset code and issuer is painful because issuer addresses are long. I think there could be value in defining a common format to define user-friendly asset addresses that resolve to the issuer address. This could be implemented by any client without any new server technology by leveraging existing stellar.toml files.

I've posted a full proposal at stellar/stellar-protocol#639, but in summary we could define a format {asset-code}:{asset-domain} and a process where by a client retrieves the stellar.toml of the asset domain to resolve the asset's issuer address which is stored in the file.

Example:
The asset address USD:example.com could resolve to USD:GA2...VAH if example.com hosts the stellar.toml with the USD code and an issuer defined as GA...VAH.

I'd love to hear if others believe this would be useful, if anyone is already doing anything like this, and how it could be improved.

Cheers,
Leigh

--
You received this message because you are subscribed to the Google Groups "Stellar Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stell...@googlegroups.com.

mister...@cosmic.plus

unread,
Jun 30, 2020, 7:34:36 AM6/30/20
to Leigh McCulloch, Stellar Developers
Cosmic.link simply fetches the pubkey from the federation server. The library is coded in such a way that any place that takes a pubkey will accept a federated address as well (e.g.: asset, signer). There's no special logic for assets. 

Indeed, asset issuers rarely provide a federated address. Ripplefox used to but closed it recently.

I can't speak for them, but I'd guess that there's a security reason here. Normally, the toml only stores metadata, so as long as you go with the pubkey you avoid introducing a single point of failure. That's something worth considering as the proposal in this thread adds a centralized layer to assets addressing.

There are ways to mitigate that issue (e.g.: stellar DKIF), but that's probably out of the scope of this thread.

In term of overhead, I released a Cloudflare worker-based federation server that is easy to setup and will run for free up to 100.000 requests/day:


MisterTicot

To unsubscribe from this group and stop receiving emails from it, send an email to stellar-dev...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/stellar-dev/875d60fd-38eb-4184-ac62-69b5c0fa5b3fo%40googlegroups.com.

Gleb Pitsevich

unread,
Oct 22, 2020, 7:29:10 PM10/22/20
to Stellar Developers
I support this proposal. The notation makes a lot of sense, and is very intuitive.

Some thoughts:
- A very similar format is already used in StellarTerm and works well: https://stellarterm.com/exchange/NGNT-cowrie.exchange/BTC-apay.io
- I think that USD:example.com is a lot cleaner than USD:foo*example.com. Not sure it's worth to over-complicate things for a rare use-case.
- It looks like in the current SEP draft resolving of USD:example.com requires "example.com" to be set as a home domain for the asset.

It's interesting whether the "USD:example.com" should resolve correctly if the asset has *no home_domain specified*?

There are some points why it might make sense to require the home_domain to be set:
1) Notation "USD:example.com" kind of implies that USD asset is indeed issued by "example.com".
2) When seeing USD:example1.com and USD:example2.com I would expect those to be different assets. If home_domain is not set, that would not be the case.

Best,
Gleb

Leigh McCulloch

unread,
Oct 30, 2020, 1:23:19 AM10/30/20
to Stellar Developers
I think your points about why it might make sense to require the home domain to be set are compelling, specifically the second. If it is not a requirement it will always be easy to confuse users by using other domains and relaying to a legitimate asset.

In the draft at v0.1.0 it is implicit that this case would fail but not explicit, so I'm adding clarification of that in stellar/stellar-protocol#761 v0.1.1.

Cheers,
Leigh

Dan Doney

unread,
Oct 30, 2020, 6:59:28 PM10/30/20
to Stellar Developers
This is a great topic! Security tokens are a case where a single issuer would use multiple tokens with the same symbol (tranches). We use this all the time. for example: IBM:SeriesA*ibm.com,  IBM:SeriesB*ibm.com  OR  IBM:RegD*ibm.com,  IBM:RegS*ibm.com OR BOND1:Mezz1*walmart.com,  BOND1:Mezz2*walmart.com. Tranches or Share classes are very common in the securities world. You could handle this by using different domains - or even different tokens, but this makes for a mess and hides the actual linkage between the classes (different rights, same asset).

As a cross ledger provider, we use a different syntax to cover a range of cases. Here's what we do:

For tokens, [Provider(namespace)]:[symbol].[issuer/domain].[tranche].[instance for NFTs]  

1. An implementation has defaults for Provider and Issuer. Tranche and Instance are not required. Only symbol is required. This makes for easy user friendly name that resolve uniquely while retaining expressivity for complex cases. Each implementation sets its default. So:
USD resolves to USD issued by Securrency distinct from USD.CompanyB issued by a separate company. IBM.DTCC.Preferred resolves to IBM preferred shares issued and custodied bt DTCC. Finally, DTCCPrivate:IBM.DTCC.Preferred represents an internal ledger or Ethereum:IBM.DTCC.Preferred represents the shares if they are transferred to a different ledger.
2. Provider allows differing namespaces, ledgers, and implementations even if parties collide on naming or addresses. This provides a convention that works even if parties are using public and private ledgers - or in the cases (not for Stellar of course!) where there is a fork.It also allows for support of different syntax for pointing to a token like the use of a naming server.
3. I recognize that "." is not a good delimiter for a namespace, if domain names are used for issuer. We'll need to switch this. We ran into something similar for Hashgraph
4. Tranche is SUPER useful in the securities world. You won't make a dent there without it.
5. Instance represents unique identifiers for NFTs (which may also be separated by tranches). More on this some other time.

For wallets, [Provider]:[address].[account(if custodian)]
1. Again, this is super useful for cross ledger operations or conflicting naming. Notice the account extension which is important for custodial work (we carry these details in the memo field)

Sorry for a long response. Securrency cares a great deal about this one...

Leigh McCulloch

unread,
Oct 30, 2020, 11:59:31 PM10/30/20
to Stellar Developers
Hi Dan,

This is really helpful insight into how you're using addresses to reference more complex use cases.

Focusing on the token format:

>An implementation has defaults for...Issuer.

In this SEP I think we need to keep the issuer as a required field because no asset has an assumed issuer on the Stellar network. However, as you say, any implementation or application could choose to match an asset code to a default issuer. I think that's out of scope of this SEP since SEPs primarily focus on interoperability, but as long as nothing in the design of this SEP makes that optimization difficult for applications, an application could do this. I think UX optimizations like this are common and this SEP doesn't percent applications to make that optimization.

>[Provider(namespace)]:[symbol].[issuer/domain].[tranche].[instance for NFTs]
>Provider allows differing namespaces, ledgers, and implementations even if parties collide on naming or addresses.
>DTCCPrivate:IBM.DTCC.Preferred represents an internal ledger or Ethereum:IBM.DTCC.Preferred represents the shares if they are transferred to a different ledger
>Tranche and Instance are not required.

The concepts of provider, tranches, and instances look very helpful to a subset of applications, so I'm wondering if they could be defined in extensions to SEP-32.

For example, it would be trivial to support an arbitrary number of additional namespaces on the tail of an asset address if we specify in SEP-32 that the core address (code and issuer) end at not just a whitespace but also at a second delimiter. This would make it trivial in implementations that only need the basics to extract the code and issuer from an address containing additional elements.

Extending the format with an optional prefixed provider or network looks subtly more complex. It's concerns are slightly different because SEP-32 specifies resolution and verification of assets on a specific type of network and so to combine that in SEP-32 would probably be trying to solve too many problems at once. However, I think cross-network namespaces of assets is something we could pursue as a SEP that is a superset of SEP-32 in a similar way to how HTTP protocols in URLs are out-of-scope of DNS resolution. This superset if pursued could probably be a superset of both SEP-32 and SEP-2. I'd be happy to discuss that further separate from this SEP.

My questions are:
1. Dan, and others, do you think a modification like this to SEP-32 would be beneficial to interoperability, or too application specific, therefore adding unnecessary complexity, and something that apps that need it should define on their own terms?
2. Would there be value in collaborating in the future on a cross-network superset of this that could sit on SEP-32/SEP-2?

Cheers,
Leigh

Dan Doney

unread,
Oct 31, 2020, 4:28:22 PM10/31/20
to Stellar Developers
Thanks Leigh. I appreciate your thoughtful response.

> Dan, and others, do you think a modification like this to SEP-32 would be beneficial to interoperability, or too application specific, therefore adding unnecessary complexity, and something that apps that need it should define on their own terms?

I believe the development of a standard would have utility for the community - especially, because it would provide a baseline for references that cross implementations. Blockchain represents a significant opportunity to extend and decentralize the basic tents of Object Oriented Programming. Namespaces and unique referencing are important enablers. In any case, we need it and are happy to share our approach with others to build community. The good thing about SEP-32 as it has been proposed is that it is additive and non-breaking. If others prefer their own implementation, they can keep it.

>>An implementation has defaults for...Issuer.

> In this SEP I think we need to keep the issuer as a required field because no asset has an assumed issuer on the Stellar network. However, as you say, any implementation or application could choose to match an asset code to a default issuer. I think that's out of scope of this SEP since SEPs primarily focus on interoperability, but as long as nothing in the design of this SEP makes that optimization difficult for applications, an application could do this. I think UX optimizations like this are common and this SEP doesn't percent applications to make that optimization.

You are right. The use of defaults is a choice for any local implementation. It is outside the scope of SEP-32. That said, the way we've designed it, you can do both without collisions - and maintain backward compatibility with basic API data structures. Implementing an approach that can allow extensions while maintaining backward compatibility has some tricks that would inform SEP-32 (eg separate delimiter for namespace).


> The concepts of providertranches, and instances look very helpful to a subset of applications, so I'm wondering if they could be defined in extensions to SEP-32.

Provider(namespace) is key since it allows forward compatibility with any naming convention and allows multiple solutions to the asset naming framework. It is also really useful for cross system integration and allows for mapping from a local system or network to a global convention. But, if defaults are to be used (necessary for backward compatibility), the provider delimiter must be different than the delimiter used to separate components of a naming convention. Here are some samples:

Note: I'm using ~to delimit elements in a naming convention

IBM~GCBFPDKMVPMGWNAPUIBGHRPFMCJ33IGQ4AUFHKC3EIN3WSS7UO4DCSJP    Asset issued by Securrency

IBM~securrency.com  Asset issued by Securrency (friendly name resolving to the asset above)


PayID:IBM~Securrency  Asset issued by Securrency but the parser knows based on the provider to use PayID to resolve issuer address
or
PrivateStellar:IBM~GCBFPDKMVPMGWNAPUIBGHRPFMCJ33IGQ4AUFHKC3EIN3WSS7UO4DCSJP Asset issued by Securrency, but residing on a private Stellar implementation

If the syntax didn't include the namespace in the beginning (or optionally missing), than the last 2 examples couldn't be implemented without the possibility of collisions.



As you say, tranche and instance are specific to a subset of asset types and can easily be added as extensions.

IBM~securrency.com~preferred  Asset issued by Securrency, preferred tranche (distinct but related to the assets above)

 
> Focusing on the token format

Good idea. Just sayin', the same technique works for any object (Asset, Wallet, Entity (owners of wallets), Offerings (we use this to manage token offering across providers), Orders, Transfers, etc) and is an important enabler for us to interoperate with other providers, payment networks, banks without changing basic object structures. We can even avoid ambiguity across classes like this: PrivateStellar~Wallet:GCBFPDKMVPMGWNAPUIBGHRPFMCJ33IGQ4AUFHKC3EIN3WSS7UO4DCSJP   But, these extensions are a bonus if we agree on the basics. 

While we don't care which delimiters are used (the delimiters cannot be used in a name obviously), the use of ":" for anything other than namespace would cause a collision elsewhere. A convention seems to have formed to use this when dealing with forks. For example, Bitcoin and Bitcoin Cash collide on wallet addresses. For example, the Bitcoin community uses 18cBEMRxXHqzWWCxZNtU91F5sbUNKhL5PX to refer to an address on Bitcoin and BCH:18cBEMRxXHqzWWCxZNtU91F5sbUNKhL5PX to refer to the Bitcoin Cash ledger (fork). BCH is the namespace or provider of the network. There is a reason I mention it here. I'm looking to collaborate on SEP-32 and also to put forward a cross ledger SEP. The issue I have is that the proposed SEP-32 spec collides with a basic element of a cross ledger spec - that is, the use of ":" as a delimiter for anything other than a namespace (network/provider).









Leigh McCulloch

unread,
Nov 2, 2020, 12:43:07 PM11/2/20
to Stellar Developers
Hi Dan,

>The issue I have is that the proposed SEP-32 spec collides with a basic element of a cross ledger spec - that is, the use of ":" as a delimiter for anything other than a namespace (network/provider).

Ah, this is a really good point. If I understand correctly from your examples using BCH and PayID, what you're highlighting is that we should consider if asset addresses should exist within URIs. A URI is any resource identifier in the form {scheme}:{scheme-part}, and for an asset address to exist in the scheme-part we need to support the colon being the delimiter between the scheme and the scheme-part.

The reason the colon delimiter was chosen is because it is already commonplace in other Stellar products when referencing an asset-code and asset-issuer. For example, Horizon API, Txrep, and Ticker, use the format {asset-code}:{asset-issuer}. Using the same format builds on familiarity and existing consistency. There are also some problems with using other separators that get used in other products today: The hyphen can exist inside domains. The tilde is difficult to see and type for many folks. The asterisk is used in SEP-2. The at symbol would make them appear like email addresses.

One approach we could consider is to support asset addresses within URIs as they are proposed right now, which is technically possible because colons are allowed to be included in the scheme-part. There might be some confusion in the case where an asset code is also a scheme, for example a Bitcoin asset-code and the Bitcoin scheme are likely to overlap, but this could be overcome by applications consistently using either asset addresses that include a scheme or without.

Questions:
1. Do you, and others, think it is important for scheme-less asset addresses and asset addresses wrapped in a URI need to be 100% distinguishable?
2. Do you think continuing to use colon but supporting a scheme prefix would be sufficient?

Cheers,
Leigh

Orbit Lens

unread,
Nov 2, 2020, 2:12:51 PM11/2/20
to Leigh McCulloch, Stellar Developers
My two cents on this: 

- The proposed format makes no difference between alphanum-4 and alphanum-12 assets. I can create an asset with code BEER that will be alphanum-12 asset while clients will expect that the notation BEER:mydomain.com always refers to the alphanum-4 asset. Most applications built on Stellar use similar parsing algorithm that makes an intelligent guess, but I think it worth mentioning that explicitly in the standard.
- Looks like Horizon server team has already adopted the proposed notation, but I'd prefer hyphen symbol instead of colon in the asset name if possible. We have been using hyphens for years following the de-facto standard adopted by StellarTerm and various wallets a long time ago. Changing the delimiter seems like a negligible change at the first glance, nevertheless, it will require a lot of work on updating all paths in UI and API while supporting the old format as well. Google cache, old blog entries, links in direct messages – we'll have to maintain the backward compatibility for years. I don't see any problem with parsing even if a domain also contains hyphen characters. The asset identifier always consists of two parts, so using a straightforward regex (like /^(\w{1,12})-([\w-.]+)$/) for matching or postprocessing string.split() result will do the trick.

Overall, that's an awesome initiative that definitely enhances interoperability between ecosystem apps.

--
You received this message because you are subscribed to the Google Groups "Stellar Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to stellar-dev...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages