ADR 024 - Coin Metadata (#6253)

* Start draft

* Add context

* Updates

* Fix tabbing

* Fix title

* Update docs/architecture/adr-024-coin-metadata.md

Co-authored-by: billy rennekamp <billy.rennekamp@gmail.com>

* revise aliases

* Add section on total supply and gen state

* Add section on aliases

* Add section on gov

* Update docs/architecture/adr-024-coin-metadata.md

Co-authored-by: Aaron Craelius <aaron@regen.network>

* Add ext

* Remove extensions

* Add special treatment for base and display denomination (#6351)

Co-authored-by: billy rennekamp <billy.rennekamp@gmail.com>
Co-authored-by: Aaron Craelius <aaron@regen.network>
Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com>
This commit is contained in:
Alexander Bezobchuk 2020-06-06 21:05:22 -04:00 committed by GitHub
parent b9b578d6de
commit 8bc645a418
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 144 additions and 5 deletions

View File

@ -49,3 +49,4 @@ Please add a entry below in your Pull Request for an ADR.
- [ADR 021: Protocol Buffer Query Encoding](./adr-021-protobuf-query-encoding.md)
- [ADR 022: Custom baseapp panic handling](./adr-022-custom-panic-handling.md)
- [ADR 023: Protocol Buffer Naming and Versioning](./adr-023-protobuf-naming.md)
- [ADR 024: Coin Metadata](./adr-024-coin-metadata.md)

View File

@ -0,0 +1,138 @@
# ADR 024: Coin Metadata
## Changelog
- 05/19/2020: Initial draft
## Status
Proposed
## Context
Assets in the Cosmos SDK are represented via a `Coins` type that consists of an `amount` and a `denom`,
where the `amount` can be any arbitrarily large or small value. In addition, the Cosmos SDK uses an
account-based model where there are two types of primary accounts -- basic accounts and module accounts.
All account types have a set of balances that are composed of `Coins`. The `x/bank` module keeps
track of all balances for all accounts and also keeps track of the total supply of balances in an
application.
With regards to a balance `amount`, the Cosmos SDK assumes a static and fixed unit of denomination,
regardless of the denomination itself. In other words, clients and apps built atop a Cosmos-SDK-based
chain may choose to define and use arbitrary units of denomination to provide a richer UX, however, by
the time a tx or operation reaches the Cosmos SDK state machine, the `amount` is treated as a single
unit. For example, for the Cosmos Hub (Gaia), clients assume 1 ATOM = 10^6 uatom, and so all txs and
operations in the Cosmos SDK work off of units of 10^6.
This clearly provides a poor and limited UX especially as interoperability of networks increases and
as a result the total amount of asset types increases. We propose to have `x/bank` additionally keep
track of metadata per `denom` in order to help clients, wallet providers, and explorers improve their
UX and remove the requirement for making any assumptions on the unit of denomination.
## Decision
The `x/bank` module will be updated to store and index metadata by `denom`, specifically the "base" or
smallest unit -- the unit the Cosmos SDK state-machine works with.
Metadata may also include a non-zero length list of denominations. Each entry containts the name of
the denomination `denom`, the exponent to the base and a list of aliases. An entry is to be
interpreted as `1 denom = 10^exponent base_denom` (e.g. `1 ETH = 10^18 wei` and `1 uatom = 10^0 uatom`).
There are two denominations that are of high importance for clients: the `base`, which is the smallest
possible unit and the `display`, which is the unit that is commonly referred to in human communication
and on exchanges. The values in those fields link to an entry in the list of denominations.
The list in `denom_units` and the `display` entry may be changed via governance.
As a result, we can define the type as follows:
```protobuf
message DenomUnit {
string denom = 1;
uint32 exponent = 2;
repeated string aliases = 3;
}
message Metadata {
string description = 1;
repeated DenomUnit denom_units = 2;
string base = 3;
string display = 4;
}
```
As an example, the ATOM's metadata can be defined as follows:
```json
{
"description": "The native staking token of the Cosmos Hub.",
"denom_units": [
{
"denom": "uatom",
"exponent": 0,
"aliases": [
"microatom"
],
},
{
"denom": "matom",
"exponent": 3,
"aliases": [
"milliatom"
]
},
{
"denom": "atom",
"exponent": 6,
}
],
"base": "uatom",
"display": "atom",
}
```
Given the above metadata, a client may infer the following things:
- 4.3atom = 4.3 * (10^6) = 4,300,000uatom
- The string "atom" can be used as a display name in a list of tokens.
- The balance 4300000 can be displayed as 4,300,000uatom or 4,300matom or 4.3atom.
The `display` denomination 4.3atom is a good default if the authors of the client don't make
an explicit decision to choose a different representation.
A client should be able to query for metadata by denom both via the CLI and REST interfaces. In
addition, we will add handlers to these interfaces to convert from any unit to another given unit,
as the base framework for this already exists in the Cosmos SDK.
Finally, we need to ensure metadata exists in the `GenesisState` of the `x/bank` module which is also
indexed by the base `denom`.
```go
type GenesisState struct {
SendEnabled bool `json:"send_enabled" yaml:"send_enabled"`
Balances []Balance `json:"balances" yaml:"balances"`
Supply sdk.Coins `json:"supply" yaml:"supply"`
DenomMetadata []Metadata `json:"denom_metadata" yaml:"denom_metadata"`
}
```
## Future Work
In order for clients to avoid having to convert assets to the base denomination -- either manually or
via an endpoint, we may consider supporting automatic conversion of a given unit input.
## Consequences
### Positive
- Provides clients, wallet providers and block explorers with additional data on
asset denomination to improve UX and remove any need to make assumptions on
denomination units.
### Negative
- A small amount of required additional storage in the `x/bank` module. The amount
of additional storage should be minimal as the amount of total assets should not
be large.
### Neutral
## References

View File

@ -4,6 +4,11 @@
- {date}: {changelog}
## Status
> A decision may be "proposed" if the project stakeholders haven't agreed with it yet, or "accepted" once it is agreed. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement.
> {Deprecated|Proposed|Accepted}
## Context
> This section describes the forces at play, including technological, political, social, and project local. These forces are probably in tension, and should be called out as such. The language in this section is value-neutral. It is simply describing facts.
@ -14,11 +19,6 @@
> This section describes our response to these forces. It is stated in full sentences, with active voice. "We will ..."
> {decision body}
## Status
> A decision may be "proposed" if the project stakeholders haven't agreed with it yet, or "accepted" once it is agreed. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement.
> {Deprecated|Proposed|Accepted}
## Consequences
> This section describes the resulting context, after applying the decision. All consequences should be listed here, not just the "positive" ones. A particular decision may have positive, negative, and neutral consequences, but all of them affect the team and project in the future.