Appearance
TEP: 64 - 代币标准
- TEP: 64
- 标题: 代币数据标准
- 状态: 活跃
- 类型: 合约接口
- 作者: EmelyanenkoK, Tolya
- 创建日期: 2022年2月3日
- 取代: -
- 被取代: -
摘要
一个用于代币(元)数据的标准接口,特别是 NFT 或 Jettons。
动机
对于钱包或市场等应用程序来说,能够自动检索信息以进行展示是非常有用的。代币数据标准可以简化这个过程,并在不同应用程序中统一代币展示的方式。
指南
每个代币(以及 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 中嵌入图像,而无需额外的链接。
规范
内容表示
可以使用三种选项:
- 链外内容布局 第一个字节是
0x01
,其余部分是指向包含代币元数据的 JSON 文档的 URI。URI 以 ASCII 编码。 如果 URI 无法放入一个单元格,则使用“蛇形格式”存储数据,如“数据序列化”段落中所述,蛇形格式前缀0x00
被省略。 - 链上内容布局 第一个字节是
0x00
,其余部分是键/值字典。 键是字符串的 sha256 哈希值。 值是按照“数据序列化”段落中描述的方式编码的数据。 - 半链内容布局 数据按“链上内容布局”中的描述编码。 字典必须有
uri
键,其值包含指向包含代币元数据的 JSON 文档的 URI。 在这种情况下,客户端应合并链上字典和链外 JSON 文档的键。 如果发生冲突(字段同时存在于链外数据和链上数据中),则使用链上值。
数据序列化
不适合一个单元格的数据可以通过两种方式存储:
- 蛇形格式,我们将部分数据存储在一个单元格中,其余数据存储在第一个子单元格中(递归进行)。 必须以
0x00
字节为前缀。 TL-B 方案:tail#_ {bn:#} b:(bits bn) = SnakeData ~0; cons#_ {bn:#} {n:#} b:(bits bn) next:^(SnakeData ~n) = SnakeData ~(n + 1);
- 分块格式,我们在字典
chunk_index
->chunk
中存储数据。 必须以0x01
字节为前缀。 TL-B 方案:chunked_data#_ data:(HashMapE 32 ^(SnakeData ~0)) = ChunkedData;
适合一个单元格的数据存储在“蛇形格式”中。
如果前缀不是 0x00
或 0x01
,则数据可能是通过 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 元数据属性
uri
- 可选。用于“半链内容布局”。ASCII 字符串。指向包含元数据的 JSON 文档的 URI。name
- 可选。UTF8 字符串。标识资产。description
- 可选。UTF8 字符串。描述资产。image
- 可选。ASCII 字符串。指向具有图像 MIME 类型的资源的 URI。image_data
- 可选。链上布局的图像二进制表示或链外布局的 base64 编码。
Jetton 元数据属性
uri
- 可选。用于“半链内容布局”。ASCII 字符串。指向包含元数据的 JSON 文档的 URI。name
- 可选。UTF8 字符串。代币的名称 - 例如“Example Coin”。description
- 可选。UTF8 字符串。描述代币 - 例如“这是 TON 网络的示例 jetton”。image
- 可选。ASCII 字符串。指向具有图像 MIME 类型的 jetton 图标的 URI。image_data
- 可选。链上布局的图像二进制表示或链外布局的 base64 编码。symbol
- 可选。UTF8 字符串。代币的符号 - 例如“XMPL”。用于表示“你收到了 99 XMPL”。decimals
- 可选。如果未指定,则默认使用 9。UTF8 编码的字符串,范围从 0 到 255。代币使用的小数位数 - 例如 8,表示将代币数量除以 100000000 以获得其用户表示,而 0 表示代币不可分割:代币数量应与钱包合约存储中的代币数量相对应。 如果指定小数位数,强烈建议在链上指定此参数,并确保智能合约代码确保此参数不可变。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%。
render_type
- 可选。外部应用程序需要了解 jetton 所属的组以及如何显示它。
- "currency" - 显示为货币(默认值)。
- "game" - 显示为游戏。应显示为 NFT,但同时显示 jetton 数量,考虑到
amount_style
缺点
无
理由和替代方案
提议的标准允许开发人员根据需求扩展(元)数据,而不会有冲突的风险。这个方法的替代方案可能是 预定义的数据字段集,从表面上看,这可以节省一些存储和 gas 费用。然而,没有理由不将元数据以某种紧凑的预定义形式存储在合约中,然后按照数据标准建议的方式在 get 方法中呈现(该方法离线工作,因此不会浪费 gas),从而在不牺牲灵活性的情况下降低费用。
虽然链上数据存储是首选,但链外/半链选项允许灵活地将代币适应所需的用例。
先前的工作
未解决的问题
- 我们是否应该验证链外数据以防止其更改? (NoelJacob)
- 我们是否应该支持半链布局,其中只有一些元数据字段可以存储在链上? (tvorogme)
- 我们是否应该标准化属性、特征和非图像内容? (tolya-yanot)
未来的可能性
无
变更日志
2022年5月14日 - 该标准现在不仅用于 NFT,还用于 TON 中的所有代币。添加了“Jetton 元数据属性”部分。
2022年8月31日 - 在“数据序列化”段落中添加了关于 TL-B 方案编码数据的说明。
2022年10月14日 - 为 Jetton 元数据添加了 render_type 和 amount_style
2023年12月20日 - 添加了关于半链数据的说明:“如果发生冲突(字段同时存在于链外数据和链上数据中),则使用链上值。”