Fungible Token Metadata Standard #148
Replies: 13 comments 33 replies
-
Note: I was thinking about designing a generic Metadata standard, but then I realized that it is not possible to have a non trivila Metadata structure applicable for all smart contracts. Eg: tokens need information for doing correct arithmetic. DID contracts don't need that. |
Beta Was this translation helpful? Give feedback.
-
Decimal sizeFollowing Luccio proposal, I've changed granularity from 18 to 24 to be able to support |
Beta Was this translation helpful? Give feedback.
-
WITHDRAWN: PROPOSAL: Generic Metadata API@evgenykuzyakov is already working on separate generic me - this standard will be focused on FT metadata I did a little POC using the following API (defined in Rust) APIpub trait MetaData {
/// returns None if the contract does not support the requested metadata
fn metadata(uri: String) -> Option<Value>;
/// returns the metadata that this contract exposes
fn metadata_uris() -> Vec<String>;
}
The idea is that the metadata schemas are decoupled from the API. The metadata API simply enables you to query the contract to find out what metadata it exposes. EXAMPLE: contract metadata API implementation supporting FT metadatause crate::interface::metadata::MetaData;
use crate::*;
use near_sdk::{
near_bindgen,
serde::{Deserialize, Serialize},
serde_json::{self, Value},
};
const METADATA_FT: &str = "http://near.org/contract/metadata/fungible-token";
#[near_bindgen]
impl MetaData for StakeTokenContract {
fn metadata(uri: String) -> Option<Value> {
match uri.as_str() {
METADATA_FT => {
let md = TokenMetadata {
name: "OysterPack STAKE Token",
symbol: "STAKE",
ref_url: "https://github.com/oysterpack/oysterpack-near-stake-token",
ref_hash: "base64-ecoded-hash".to_string(),
granularity: 1,
decimals: 24,
};
Some(serde_json::to_value(md).unwrap())
}
_ => None,
}
}
fn metadata_uris() -> Vec<String> {
vec![METADATA_FT.to_string()]
}
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
#[serde(crate = "near_sdk::serde")]
pub struct TokenMetadata {
name: &'static str,
symbol: &'static str,
ref_url: &'static str,
ref_hash: String,
granularity: u8,
decimals: u8,
} I added this to the STAKE contract as a POC:
|
Beta Was this translation helpful? Give feedback.
-
Question: How contract should react if a transfer receives an While I understand the desire to standardize the decimals, it's unclear to me how this benefits tools. Assuming decimals are fixed to Now the contract should operate on numbers of Alternative: Use number of digits after decimal Example:
Does it create some issues either on the contracts or on the front-end? |
Beta Was this translation helpful? Give feedback.
-
The last thing I'm having trouble wrapping my head around is the
First, Eugene has mentioned that we don't have blake2b hashing. Second, I imagine that the |
Beta Was this translation helpful? Give feedback.
-
(EDIT: WITHDRAWN) CHANGE PROPOSAL: Add array of used extension standardsI think it makes sense to have an array of standards used. For instance, if a fungible token wants to use escrows (in addition to the improved transfer functionality) struct Metadata {
name: String,
symbol: String, // token symbol
ref: String,
ref_hash: vec[u8],
decimals: uint8,
extensions: vec[String]
} I think this makes sense to have in storage on-chain, rather than in the |
Beta Was this translation helpful? Give feedback.
-
Change proposal: Rename |
Beta Was this translation helpful? Give feedback.
-
Summary of DiscussionFungible Token Metadata APIOut of Scope
class FungibleTokenMetadata {
name: string,
symbol: string,
decimals: number,
icon_url: string,
icon_hash: string, // base64 encoded hash bytes
url: string,
url_hash: string, // base64 encoded hash bytes
} Functionfunction ft_metadata(): FungibleTokenMetadata; view method Open Questions:
|
Beta Was this translation helpful? Give feedback.
-
@robert-zaremba please rename the discussion to "Fungible Token Metadata Standard" |
Beta Was this translation helpful? Give feedback.
-
I propose to use |
Beta Was this translation helpful? Give feedback.
-
I just realized that FT token metadata discussion was being discussed on the account storage discussion ... linking it here |
Beta Was this translation helpful? Give feedback.
-
I will insist on removing the "decimal" field and force all NEP-141 standard tokens on NEAR to be decimals=24 and u128 Balances. Choosing a fixed decimal=24 is a very good trade-off, and I think that's the reason why 1 NEAR=1e24 Yoctos and Balances are u128 Besides being a good trade-off, removing the field reduces complexity for hundreds of developers that now can forget about it. With decimals=24, your max amount on a u128 is 340_282_366_920_938, that's 340 trillions, and of course you get 24 digit precision, meaning you can divide 1 by 1 trillion w/o rounding and you still have 12 more digits to continue dividing. (1/1e24 =1e-12) Having fixed decimals=24 on the standards will help a lot on DEFI composability. Smart contracts composing on several tokens become way more simpler if all tokens have the same precision. |
Beta Was this translation helpful? Give feedback.
-
CHANGE PROPOSAL: Bring back pub struct FungibleTokenMetadata {
pub version: String,
pub name: String,
pub symbol: String,
pub reference: String,
pub reference_hash: vec<u8>,
pub decimals: u8,
}
I think particularly with the Bridge, we'd like to keep the |
Beta Was this translation helpful? Give feedback.
-
Rationale
Many smart-contracts need to carry extra information data. Notably, token smart contract should provide minimum information to a user about it's usage.
Previous Fungible Token interfaces (NEP-21, NEP-122) miss standard way to describe crucial information to correctly implement user interfaces and wallets. Most importantly, tokens should have name, description (either directly stored in smart contract or available in a remote service), information for correct token arithmetic.
For example, the following applications maintain their incompatible lists just to get a token icon visible in the wallet: MyEtherWallet, TrustWallet, MetaMask, Parity. Then the services maintain their own lists: Uniswap, Loopring, IDEX.
Decision
We propose a Token Metadata standard, inspired by NEP-136 and NEP-110.
Metadata should be as minimal as possible. We propose to store metadata in a separate structure.
Token Metadata
name
: canonical token name.reference
: a URL to addtional resources about the token.reference_hash
: a blake2b hash of the resource pointed byref
. It's used to validation that the reference content didn't change.decimals
: returns the number of decimals the token uses - e.g. 8, means to divide the token amount by 100000000 to get its user representation.Decimal management
For interactions with tools and assure good UX, we need to know the base of token arithmetic.
ERC-20 has an optional
decimals
contract attribute, other Ethereum standards makes this attribute obligatory. We follow the ERC-777 proposal, and fix the decimals once and for all:granularity
concept from ERC-777: the smallest part of the token that’s (denominated in e24) not divisible. The following rules MUST be applied regarding the granularity:For non fungible tokens:
granularit
anddecimals
MUST be 1Functions
Only one function is necessary to assure solid interactions with dapps and other smart contracts: to access metadata. Management functions are optional and user can change them.
metadata
Returns Metadata structure or any extension of it.
Recommended functions:
metadata_update
Arguments:
ref
: new URL to a reference resource.ref_hash
: blake2b hash of the resource atref
URL.Beta Was this translation helpful? Give feedback.
All reactions