github.com/cosmos/cosmos-sdk@v0.50.10/docs/architecture/adr-024-coin-metadata.md (about)

     1  # ADR 024: Coin Metadata
     2  
     3  ## Changelog
     4  
     5  * 05/19/2020: Initial draft
     6  
     7  ## Status
     8  
     9  Proposed
    10  
    11  ## Context
    12  
    13  Assets in the Cosmos SDK are represented via a `Coins` type that consists of an `amount` and a `denom`,
    14  where the `amount` can be any arbitrarily large or small value. In addition, the Cosmos SDK uses an
    15  account-based model where there are two types of primary accounts -- basic accounts and module accounts.
    16  All account types have a set of balances that are composed of `Coins`. The `x/bank` module keeps
    17  track of all balances for all accounts and also keeps track of the total supply of balances in an
    18  application.
    19  
    20  With regards to a balance `amount`, the Cosmos SDK assumes a static and fixed unit of denomination,
    21  regardless of the denomination itself. In other words, clients and apps built atop a Cosmos-SDK-based
    22  chain may choose to define and use arbitrary units of denomination to provide a richer UX, however, by
    23  the time a tx or operation reaches the Cosmos SDK state machine, the `amount` is treated as a single
    24  unit. For example, for the Cosmos Hub (Gaia), clients assume 1 ATOM = 10^6 uatom, and so all txs and
    25  operations in the Cosmos SDK work off of units of 10^6.
    26  
    27  This clearly provides a poor and limited UX especially as interoperability of networks increases and
    28  as a result the total amount of asset types increases. We propose to have `x/bank` additionally keep
    29  track of metadata per `denom` in order to help clients, wallet providers, and explorers improve their
    30  UX and remove the requirement for making any assumptions on the unit of denomination.
    31  
    32  ## Decision
    33  
    34  The `x/bank` module will be updated to store and index metadata by `denom`, specifically the "base" or
    35  smallest unit -- the unit the Cosmos SDK state-machine works with.
    36  
    37  Metadata may also include a non-zero length list of denominations. Each entry contains the name of
    38  the denomination `denom`, the exponent to the base and a list of aliases. An entry is to be
    39  interpreted as `1 denom = 10^exponent base_denom` (e.g. `1 ETH = 10^18 wei` and `1 uatom = 10^0 uatom`).
    40  
    41  There are two denominations that are of high importance for clients: the `base`, which is the smallest
    42  possible unit and the `display`, which is the unit that is commonly referred to in human communication
    43  and on exchanges. The values in those fields link to an entry in the list of denominations.
    44  
    45  The list in `denom_units` and the `display` entry may be changed via governance.
    46  
    47  As a result, we can define the type as follows:
    48  
    49  ```protobuf
    50  message DenomUnit {
    51    string denom    = 1;
    52    uint32 exponent = 2;  
    53    repeated string aliases = 3;
    54  }
    55  
    56  message Metadata {
    57    string description = 1;
    58    repeated DenomUnit denom_units = 2;
    59    string base = 3;
    60    string display = 4;
    61  }
    62  ```
    63  
    64  As an example, the ATOM's metadata can be defined as follows:
    65  
    66  ```json
    67  {
    68    "name": "atom",
    69    "description": "The native staking token of the Cosmos Hub.",
    70    "denom_units": [
    71      {
    72        "denom": "uatom",
    73        "exponent": 0,
    74        "aliases": [
    75          "microatom"
    76        ],
    77      },
    78      {
    79        "denom": "matom",
    80        "exponent": 3,
    81        "aliases": [
    82          "milliatom"
    83        ]
    84      },
    85      {
    86        "denom": "atom",
    87        "exponent": 6,
    88      }
    89    ],
    90    "base": "uatom",
    91    "display": "atom",
    92  }
    93  ```
    94  
    95  Given the above metadata, a client may infer the following things:
    96  
    97  * 4.3atom = 4.3 * (10^6) = 4,300,000uatom
    98  * The string "atom" can be used as a display name in a list of tokens.
    99  * The balance 4300000 can be displayed as 4,300,000uatom or 4,300matom or 4.3atom.
   100    The `display` denomination 4.3atom is a good default if the authors of the client don't make
   101    an explicit decision to choose a different representation.
   102  
   103  A client should be able to query for metadata by denom both via the CLI and REST interfaces. In
   104  addition, we will add handlers to these interfaces to convert from any unit to another given unit,
   105  as the base framework for this already exists in the Cosmos SDK.
   106  
   107  Finally, we need to ensure metadata exists in the `GenesisState` of the `x/bank` module which is also
   108  indexed by the base `denom`.
   109  
   110  ```go
   111  type GenesisState struct {
   112    SendEnabled   bool        `json:"send_enabled" yaml:"send_enabled"`
   113    Balances      []Balance   `json:"balances" yaml:"balances"`
   114    Supply        sdk.Coins   `json:"supply" yaml:"supply"`
   115    DenomMetadata []Metadata  `json:"denom_metadata" yaml:"denom_metadata"`
   116  }
   117  ```
   118  
   119  ## Future Work
   120  
   121  In order for clients to avoid having to convert assets to the base denomination -- either manually or
   122  via an endpoint, we may consider supporting automatic conversion of a given unit input.
   123  
   124  ## Consequences
   125  
   126  ### Positive
   127  
   128  * Provides clients, wallet providers and block explorers with additional data on
   129    asset denomination to improve UX and remove any need to make assumptions on
   130    denomination units.
   131  
   132  ### Negative
   133  
   134  * A small amount of required additional storage in the `x/bank` module. The amount
   135    of additional storage should be minimal as the amount of total assets should not
   136    be large.
   137  
   138  ### Neutral
   139  
   140  ## References