Display Sui对象显示标准
Sui 对象显示标准是一个模板引擎,允许对类型的链下表示(显示)进行链上管理。使用它,您可以将对象的数据替换为模板字符串。该标准不限制您可以设置的字段。您可以使用 {property}语法访问所有对象属性,然后将它们作为模板字符串的一部分插入。
使用Publisher您拥有的对象来设置sui::display类型。有关Publisher对象的更多信息,请参阅Sui Move 示例中的发布者主题。
在 Sui Move 中,Display
TSui Full节点通过匹配定义来处理该类型的所有对象,并在使用查询中的设置Display查询对象时返回处理结果。{ showDisplay: true }
显示属性
建议的基本属性集包括:
- name- 对象的名称。当用户查看对象时,会显示该名称。
- description- 对象的描述。当用户查看对象时,会显示描述。
- link- 指向要在应用程序中使用的对象的链接。
- image_url- 包含对象图像的 URL 或 blob。
- thumbnail_url-较小图像的 URL,可在钱包、浏览器和其他产品中用作预览。
- project_url- 指向与对象或创建者相关的网站的链接。
- creator- 指示对象创建者的字符串。
Sui Hero 模块示例
以下代码示例演示了Display示例Hero模块如何根据类型的name、id和属性而变化。以下表示该函数定义的模板:image_urlHeroinit
{
"name": "{name}",
"link": "https://sui-heroes.io/hero/{id}",
"image_url": "ipfs://{img_url}",
"description": "A true Hero of the Sui ecosystem!",
"project_url": "https://sui-heroes.io",
"creator": "Unknown Sui Fan"
}
/// Example of an unlimited "Sui Hero" collection - anyone can
/// mint their Hero. Shows how to initialize the `Publisher` and how
/// to use it to get the `Display<Hero>` object - a way to describe a
/// type for the ecosystem.
module examples::my_hero {
use sui::tx_context::{sender, TxContext};
use std::string::{utf8, String};
use sui::transfer::transfer;
use sui::object::{Self, UID};
// The creator bundle: these two packages often go together.
use sui::package;
use sui::display;
/// The Hero - an outstanding collection of digital art.
public struct Hero has key, store {
id: UID,
name: String,
image_url: String,
}
/// One-Time-Witness for the module.
public struct MY_HERO has drop {}
/// In the module initializer one claims the `Publisher` object
/// to then create a `Display`. The `Display` is initialized with
/// a set of fields (but can be modified later) and published via
/// the `update_version` call.
///
/// Keys and values are set in the initializer but could also be
/// set after publishing if a `Publisher` object was created.
fun init(otw: MY_HERO, ctx: &mut TxContext) {
let keys = vector[
utf8(b"name"),
utf8(b"link"),
utf8(b"image_url"),
utf8(b"description"),
utf8(b"project_url"),
utf8(b"creator"),
];
let values = vector[
// For `name` one can use the `Hero.name` property
utf8(b"{name}"),
// For `link` one can build a URL using an `id` property
utf8(b"https://sui-heroes.io/hero/{id}"),
// For `image_url` use an IPFS template + `image_url` property.
utf8(b"ipfs://{image_url}"),
// Description is static for all `Hero` objects.
utf8(b"A true Hero of the Sui ecosystem!"),
// Project URL is usually static
utf8(b"https://sui-heroes.io"),
// Creator field can be any
utf8(b"Unknown Sui Fan")
];
// Claim the `Publisher` for the package!
let publisher = package::claim(otw, ctx);
// Get a new `Display` object for the `Hero` type.
let display = display::new_with_fields<Hero>(
&publisher, keys, values, ctx
);
// Commit first version of `Display` to apply changes.
display::update_version(&mut display);
transfer(publisher, sender(ctx));
transfer(display, sender(ctx));
}
/// Anyone can mint their `Hero`!
public fun mint(name: String, image_url: String, ctx: &mut TxContext): Hero {
let id = object::new(ctx);
Hero { id, name, image_url }
}
}
使用对象显示
该调用在自定义函数或模块初始值设定项中display::new
module sui::display {
/// Get a new Display object for the `T`.
/// Publisher must be the publisher of the T, `from_package`
/// check is performed.
public fun new<T>(pub: &Publisher): Display<T> { /* ... */ }
}
创建后Display,您可以对其进行修改。以下代码示例演示了如何修改Display:
module sui::display {
/// Sets multiple fields at once
public fun add_multiple(
self: &mut Display,
keys: vector<String>,
values: vector<String>
) { /* ... */ }
/// Edit a single field
public fun edit(self: &mut Display, key: String, value: String) { /* ... */ }
/// Remove a key from Display
public fun remove(self: &mut Display, key: String ) { /* ... */ }
}
接下来,update_version调用应用更改并通过发出事件Display来设置 。T完整节点接收事件并使用事件中的数据来检索该类型的模板。
以下代码示例演示了如何使用该update_version调用:
module sui::display {
/// Update the version of Display and emit an event
public fun update_version(self: &mut Display) { /* ... */ }
}
Sui实用对象
在 Sui 中,实用程序对象启用功能授权。几乎所有模块都具有只有具有所需功能才能访问的功能。通用模块允许每个应用程序具有一种功能,例如市场。某些功能标记链上共享对象的所有权,或从另一个帐户访问共享数据。对于功能,提供有意义的对象描述以促进用户界面实现非常重要。这有助于避免当对象相似时意外传输错误的对象。它还为用户看到的项目提供用户友好的描述。
以下示例演示了如何创建 capy 功能:
module capy::utility {
/// A capability which grants Capy Manager permission to add
/// new genes and manage the Capy Market
struct CapyManagerCap has key, store {
id: UID
}
}
具有数据重复的典型对象
游戏内物品的常见情况是有大量相似的对象按某些标准分组。优化它们的大小以及铸造和更新它们的成本非常重要。通常,游戏对每个组或项目标准使用单个源图像或 URL。将源图像存储在每个对象内并不是最佳选择。在某些情况下,当游戏允许或购买游戏内物品时,用户会铸造游戏内物品。为此,必须提前创建并存储一些 IPFS/Arweave 元数据。这需要额外的逻辑,这些逻辑通常与物品的游戏内属性无关。
以下示例演示了如何创建 Capy:
module capy::capy_items {
/// A wearable Capy item. For some items there can be an
/// unlimited supply. And items with the same name are identical.
public struct CapyItem has key, store {
id: UID,
name: String
}
}
具有动态表示的独特对象# Sui Capys 使用动态图像生成。当卡比出生时,其属性决定了卡比的外观,例如颜色或图案。当用户将物品放在 Capy 上时,Capy 的外观会发生变化。当用户将多个物品放在 Capy 上时,物品组合就有机会获得奖励。
为了实现这一点,Capys 游戏 API 服务会刷新图像以响应用户发起的更改。Capy 的 URL 是一个带有capy.id. 但存储完整的 URL——以及 Capy 对象中的其他字段(由于其人口的多样性)——也会导致用户支付过多的存储费用并增加汽油费。
下面的例子演示了如何实现动态图像生成:
module capy::capy {
/// A Capy - very diverse object with different combination
/// of genes. Created dynamically + for images a dynamic SVG
/// generation is used.
public struct Capy has key, store {
id: UID,
genes: vector<u8>
}
}
具有独特静态内容的对象# 这是最简单的场景——一个对象代表一切本身。将元数据标准应用于此类对象非常容易,特别是当该对象永远保持不可变时。但是,如果元数据标准不断发展,并且某些生态系统项目为某些属性添加了新功能,则该对象始终保持其原始形式,并且可能需要向后兼容的更改。
module sui::devnet_nft {
/// A Collectible with a static data. URL, name, description are
/// set only once on a mint event
public struct DevNetNFT has key, store {
id: UID,
name: String,
description: String,
url: Url,
}
}