如何在 Sui 链上发布一个 NFT
如果你是初学者,强烈建议看下前几节内容:
入门 Sui Move 开发:2. 常用命令、编写并发布 Hello World 合约
入门 Sui Move 开发:3. Sui Move 语法和设计模式
入门 Sui Move 开发:4. Sui Move 中集合、对象、泛型、动态字段
在 Sui
链上发布一个非同质化代码也就是 NFT
很简单,因为在 Sui
上一切都是对象,每个对象都是独一无二的。
所以在 Sui
上实现 NFT
其实就是给对象添加所需要的字段。
/// 发布一个 NFT 的简单合约
module nft_greyhao::nft_greyhao;
use std::string::{String , utf8};
use sui::url::{Self, Url};
use sui::event;
// NFT 对象,包含所需要的 name、description、url 信息
public struct GreyhaoNFT has key, store {
id: UID,
name: String,
description: String,
url: Url,
}
// ====Evens ====
public struct NFTMinted has copy, drop {
object_id: ID,
creator: address,
name: String,
}
fun init(ctx: &mut TxContext) {
let url = url::new_unsafe_from_bytes(b"https://avatars.githubusercontent.com/u/107107440");
// 创建一个 NFT 对象实例
let nft = GreyhaoNFT {
id: object::new(ctx),
name: utf8(b"GREYHAO"),
description: utf8(b"NFT was created by GreyHao."),
url: url,
}
event::emit(NFTMinted {
object_id: object::id(&nft),
creator: recipient,
name: nft.name,
});
// 将 NFT 发送给当前交易地址
transfer::transfer(nft, tx_context::sender(ctx));
}
// mint NFT
#[allow(lint(self_transfer))]
public fun mint(ctx: &mut TxContext){
let recipient = tx_context::sender(ctx);
let url = url::new_unsafe_from_bytes(b"https://avatars.githubusercontent.com/u/107107440");
// 创建一个 NFT 对象实例
let nft = GreyhaoNFT {
id: object::new(ctx),
name: utf8(b"GREYHAO"),
description: utf8(b"NFT was created by GreyHao."),
url: url,
}
event::emit(NFTMinted {
object_id: object::id(&nft),
creator: recipient,
name: nft.name,
});
transfer::public_transfer(nft, recipient);
}
/// 转移指定 NFT 给指定地址
public fun transfer(nft: GreyhaoNFT, recipient: address, _: &mut TxContext) {
transfer::public_transfer(nft, recipient)
}
/// mint NFT 并发送给指定地址
public fun mint_and_transfer(recipient: address, ctx: &mut TxContext) {
let nft = GreyhaoNFT {
id: object::new(ctx),
name: utf8(b"GREYHAO"),
description: utf8(b"NFT was created by GreyHao."),
url: url,
}
transfer::public_transfer(nft, recipient)
}
/// 删除指定 NFT 对象
public fun burn(nft: GreyhaoNFT, _: &mut TxContext) {
let GreyhaoNFT {id, name: _, description: _, url: _} = nft;
id.delete()
}
发布合约之后,在浏览器搜索创建的类型为 合约地址::nft_greyhao::GreyhaoNFT
,可以看到如下图所展示的内容。
Display
对象,实现在浏览器上自动展示 NFT 信息上图中跟我期望的有一些不同,怎么上图中没有看到NFT
图片。
接下来就要用到 Display
对象。
Display
对象可以实现链上数据更友好可读的一种模版引擎。通过开发者定义如何将特定的结构或对象格式化为用户友好的字符串表示,在前端中更清晰展示。
只需在 init
方法中添加 Display
相关模版内容,就可以实现当我们在浏览器中搜索 NFT
对象(发布合约时创建的类型为 ObjectType
的对象)所对应的 ObjectID
时就可以看到对应的图片及其他信息。
let keys = vector[
b"name".to_string(),
b"link".to_string(),
b"image_url".to_string(),
b"description".to_string(),
b"project_url".to_string(),
b"creator".to_string(),
];
let values = vector[
b"{name}".to_string(),
b"https://sui-heroes.io/hero/{id}".to_string(),
b"{image_url}".to_string(),
b"A true Hero of the Sui ecosystem!".to_string(),
b"https://sui-heroes.io".to_string(),
b"Unknown NFT Fan".to_string(),
];
let publisher = package::claim(otw, ctx);
let mut display = display::new_with_fields<GreyhaoNFT>(&publisher, keys, values, ctx);
display.update_version();
transfer::public_transfer(publisher, ctx.sender());
transfer::public_transfer(display, ctx.sender());
使用 display
的完整代码
/// 发布一个 NFT 的简单合约
module nft_greyhao::nft_greyhao;
use std::string::{String , utf8};
use sui::url::{Self, Url};
use sui::event;
use sui::package;
use sui::display;
// NFT 对象,包含所需要的 name、description、url 信息
public struct GreyhaoNFT has key, store {
id: UID,
name: String,
description: String,
url: Url,
}
// ====Evens ====
public struct NFTMinted has copy, drop {
object_id: ID,
creator: address,
name: String,
}
fun init(ctx: &mut TxContext) {
// 定义 keys,keys 包含的值就是 GreyhaoNFT 对象中除 id 外的字段
let keys = vector[
b"name".to_string(),
b"description".to_string(),
b"url".to_string(),
];
// 定义 key 对应的值
let values = vector[
b"{name}".to_string(),
b"{description}".to_string(),
b"{url}".to_string(),
];
// 使用了 OTW, 通过 package::claim 得到一个 publisher 对象
let publisher = package::claim(otw, ctx);
// 使用要显示的属性创建 display 对象
let mut display = display::new_with_fields<GreyhaoNFT>(&publisher, keys, values, ctx);
// 更新版本
display.update_version();
// 将 publisher 和 display 都发送给当前交易地址
transfer::public_transfer(publisher, ctx.sender());
transfer::public_transfer(display, ctx.sender());
let url = url::new_unsafe_from_bytes(b"https://avatars.githubusercontent.com/u/107107440");
// 创建一个 NFT 对象实例
let nft = GreyhaoNFT {
id: object::new(ctx),
name: utf8(b"GREYHAO"),
description: utf8(b"NFT was created by GreyHao."),
url: url,
}
event::emit(NFTMinted {
object_id: object::id(&nft),
creator: recipient,
name: nft.name,
});
// 将 NFT 发送给当前交易地址
transfer::transfer(nft, tx_context::sender(ctx));
}
// mint NFT
#[allow(lint(self_transfer))]
public fun mint(ctx: &mut TxContext){
let recipient = tx_context::sender(ctx);
let url = url::new_unsafe_from_bytes(b"https://avatars.githubusercontent.com/u/107107440");
// 创建一个 NFT 对象实例
let nft = GreyhaoNFT {
id: object::new(ctx),
name: utf8(b"GREYHAO"),
description: utf8(b"NFT was created by GreyHao."),
url: url,
}
event::emit(NFTMinted {
object_id: object::id(&nft),
creator: recipient,
name: nft.name,
});
transfer::public_transfer(nft, recipient);
}
/// 转移指定 NFT 给指定地址
public fun transfer(nft: GreyhaoNFT, recipient: address, _: &mut TxContext) {
transfer::public_transfer(nft, recipient)
}
/// mint NFT 并发送给指定地址
public fun mint_and_transfer(recipient: address, ctx: &mut TxContext) {
let nft = GreyhaoNFT {
id: object::new(ctx),
name: utf8(b"GREYHAO"),
description: utf8(b"NFT was created by GreyHao."),
url: url,
}
transfer::public_transfer(nft, recipient)
}
/// 删除指定 NFT 对象
public fun burn(nft: GreyhaoNFT, _: &mut TxContext) {
let GreyhaoNFT {id, name: _, description: _, url: _} = nft;
id.delete()
}
以上就是本节的所有内容。
如果觉得本节内容对你有所帮助,可以点赞鼓励下。
如果你对文章中内容有任何疑问可以留言。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!