Skip to content

TEP: 64 - 代币标准

  • TEP: 64
  • 标题: 代币数据标准
  • 状态: 活跃
  • 类型: 合约接口
  • 作者: EmelyanenkoK, Tolya
  • 创建日期: 2022年2月3日
  • 取代: -
  • 被取代: -

摘要

一个用于代币(元)数据的标准接口,特别是 NFTJettons

动机

对于钱包或市场等应用程序来说,能够自动检索信息以进行展示是非常有用的。代币数据标准可以简化这个过程,并在不同应用程序中统一代币展示的方式。

指南

每个代币(以及 NFT 集合)都有自己的元数据。它包含一些关于代币的信息,如标题和相关图片。元数据可以存储在链外(智能合约只包含一个指向 JSON 的链接)或链上(所有数据都存储在智能合约中)。

NFT 集合元数据示例(链外)

部署在主网地址:EQD7Qtnas8qpMvT7-Z634_6G60DGp02owte5NnEjaWq6hb7v (explorer.tonnft.tools)

元数据:

json
{
   "image": "https://s.getgems.io/nft/b/c/62fba50217c3fe3cbaad9e7f/image.png",
   "name": "TON Smart Challenge #2",
   "description": "TON Smart Challenge #2 Winners Trophy",
   "social_links": [],
   "marketplace": "getgems.io"
}

NFT 项目元数据示例(链外)

部署在主网地址:EQA5q4UveXaw6zx359QtgYh1L6c18X0OiAcQPhlkXufwQjOA (explorer.tonnft.tools)

元数据:

json
{
   "name": "TON Smart Challenge #2 Winners Trophy",
   "description": "TON Smart Challenge #2 Winners Trophy 1 place out of 181",
   "image": "https://s.getgems.io/nft/b/c/62fba50217c3fe3cbaad9e7f/images/943e994f91227c3fdbccbc6d8635bfaab256fbb4",
   "content_url": "https://s.getgems.io/nft/b/c/62fba50217c3fe3cbaad9e7f/content/84f7f698b337de3bfd1bc4a8118cdfd8226bbadf",
   "attributes": []
}

Jetton 元数据示例(链外):

部署在主网地址:EQD0vdSA_NedR9uvbgN9EikRX-suesDxGeFg69XQMavfLqIw (ton.cx)

元数据:

json
{
   "name": "Huebel Bolt",
   "description": "Official token of the Huebel Company",
   "symbol": "BOLT",
   "decimals": 9,
   "image_data": ""
}

这个示例告诉我们,可以直接在 JSON 中嵌入图像,而无需额外的链接。

规范

内容表示

可以使用三种选项:

  1. 链外内容布局 第一个字节是 0x01,其余部分是指向包含代币元数据的 JSON 文档的 URI。URI 以 ASCII 编码。 如果 URI 无法放入一个单元格,则使用“蛇形格式”存储数据,如“数据序列化”段落中所述,蛇形格式前缀 0x00 被省略。
  2. 链上内容布局 第一个字节是 0x00,其余部分是键/值字典。 键是字符串的 sha256 哈希值。 值是按照“数据序列化”段落中描述的方式编码的数据。
  3. 半链内容布局 数据按“链上内容布局”中的描述编码。 字典必须有 uri 键,其值包含指向包含代币元数据的 JSON 文档的 URI。 在这种情况下,客户端应合并链上字典和链外 JSON 文档的键。 如果发生冲突(字段同时存在于链外数据和链上数据中),则使用链上值。

数据序列化

不适合一个单元格的数据可以通过两种方式存储:

  1. 蛇形格式,我们将部分数据存储在一个单元格中,其余数据存储在第一个子单元格中(递归进行)。 必须以 0x00 字节为前缀。 TL-B 方案:
    tail#_ {bn:#} b:(bits bn) = SnakeData ~0;
    cons#_ {bn:#} {n:#} b:(bits bn) next:^(SnakeData ~n) = SnakeData ~(n + 1);
  2. 分块格式,我们在字典 chunk_index -> chunk 中存储数据。 必须以 0x01 字节为前缀。 TL-B 方案:
     chunked_data#_ data:(HashMapE 32 ^(SnakeData ~0)) = ChunkedData;

适合一个单元格的数据存储在“蛇形格式”中。

如果前缀不是 0x000x01,则数据可能是通过 TL-B 方案编码的(与特定智能合约相关),例如在 DNS 合约 中。

非正式的 TL-B 方案:

text#_ {n:#} data:(SnakeData ~n) = Text;
snake#00 {n:#} data:(SnakeData ~n) = ContentData;
chunks#01 data:ChunkedData = ContentData;
onchain#00 data:(HashmapE 256 ^ContentData) = FullContent;
offchain#01 uri:Text = FullContent;

注意,虽然 TL-B 方案不限制每个块的比特大小,但预计所有块都包含整字节数。

NFT 元数据属性

  1. uri - 可选。用于“半链内容布局”。ASCII 字符串。指向包含元数据的 JSON 文档的 URI。
  2. name - 可选。UTF8 字符串。标识资产。
  3. description - 可选。UTF8 字符串。描述资产。
  4. image - 可选。ASCII 字符串。指向具有图像 MIME 类型的资源的 URI。
  5. image_data - 可选。链上布局的图像二进制表示或链外布局的 base64 编码。

Jetton 元数据属性

  1. uri - 可选。用于“半链内容布局”。ASCII 字符串。指向包含元数据的 JSON 文档的 URI。
  2. name - 可选。UTF8 字符串。代币的名称 - 例如“Example Coin”。
  3. description - 可选。UTF8 字符串。描述代币 - 例如“这是 TON 网络的示例 jetton”。
  4. image - 可选。ASCII 字符串。指向具有图像 MIME 类型的 jetton 图标的 URI。
  5. image_data - 可选。链上布局的图像二进制表示或链外布局的 base64 编码。
  6. symbol - 可选。UTF8 字符串。代币的符号 - 例如“XMPL”。用于表示“你收到了 99 XMPL”。
  7. decimals - 可选。如果未指定,则默认使用 9。UTF8 编码的字符串,范围从 0 到 255。代币使用的小数位数 - 例如 8,表示将代币数量除以 100000000 以获得其用户表示,而 0 表示代币不可分割:代币数量应与钱包合约存储中的代币数量相对应。 如果指定小数位数,强烈建议在链上指定此参数,并确保智能合约代码确保此参数不可变。
  8. amount_style - 可选。外部应用程序需要了解显示 jetton 数量的格式。
  • "n" - jetton 数量(默认值)。如果用户有 100 个小数位为 0 的代币,则显示用户有 100 个代币。
  • "n-of-total" - 总发行 jetton 数量中的 jetton 数量。例如,总供应 Jetton = 1000。用户在 jetton 钱包中有 100 个 jetton。例如,必须在用户的钱包中显示为 100 of 1000 或以任何其他文本或图形方式展示特定与整体的关系。
  • "%" - 总发行 jetton 数量的百分比。例如,总供应 Jetton = 1000。用户在 jetton 钱包中有 100 个 jetton。例如,应在用户的钱包中显示为 10%。
  1. render_type - 可选。外部应用程序需要了解 jetton 所属的组以及如何显示它。
  • "currency" - 显示为货币(默认值)。
  • "game" - 显示为游戏。应显示为 NFT,但同时显示 jetton 数量,考虑到 amount_style

缺点

理由和替代方案

提议的标准允许开发人员根据需求扩展(元)数据,而不会有冲突的风险。这个方法的替代方案可能是 预定义的数据字段集,从表面上看,这可以节省一些存储和 gas 费用。然而,没有理由不将元数据以某种紧凑的预定义形式存储在合约中,然后按照数据标准建议的方式在 get 方法中呈现(该方法离线工作,因此不会浪费 gas),从而在不牺牲灵活性的情况下降低费用。

虽然链上数据存储是首选,但链外/半链选项允许灵活地将代币适应所需的用例。

先前的工作

  1. EIP-721
  2. OpenSea 元数据指南

未解决的问题

  1. 我们是否应该验证链外数据以防止其更改? (NoelJacob)
  2. 我们是否应该支持半链布局,其中只有一些元数据字段可以存储在链上? (tvorogme)
  3. 我们是否应该标准化属性、特征和非图像内容? (tolya-yanot)

未来的可能性

变更日志

  • 2022年5月14日 - 该标准现在不仅用于 NFT,还用于 TON 中的所有代币。添加了“Jetton 元数据属性”部分。

  • 2022年8月31日 - 在“数据序列化”段落中添加了关于 TL-B 方案编码数据的说明。

  • 2022年10月14日 - 为 Jetton 元数据添加了 render_type 和 amount_style

  • 2023年12月20日 - 添加了关于半链数据的说明:“如果发生冲突(字段同时存在于链外数据和链上数据中),则使用链上值。”