根据HOH社区教学材料,实现了一个简单的 NFT 发行功能。包含以下主要功能:
本系列文章将深入浅出的全面讲解Move语言。
请用微信关注《HOH水分子》公众号,我们将持续分享和制作变成语言教程,让大家对编程产生化学反应。
根据HOH社区教学材料,实现了一个简单的 NFT 发行功能。包含以下主要功能:
模块主要包括以下四个结构体:
LIZHECOMENFT
: 用于初始化模块,没有存储具体数据。GithubNFT
: NFT 实体结构,包含 NFT 的基本信息。NFTMinted
: 事件结构,用于在 NFT 发行时触发事件。MintRecord
: 记录 NFT 发行情况,防止重复发行。以下是详细的结构体定义:
// 用于初始化模块
public struct LIZHECOMENFT has drop {}
// NFT 实体结构,包含 NFT 的相关信息
public struct GithubNFT has key, store {
id: UID, // 唯一标识符
nft_id: u64, // NFT 编号
name: String, // NFT 名称
image_url: String, // 图片链接
creator: address, // 创作者地址
recipient: address, // 接收者地址
}
// 发行事件结构,用于记录 NFT 发行时的事件
public struct NFTMinted has copy, drop {
object_id: ID, // NFT 对象 ID
creator: address, // 创作者地址
name: String, // NFT 名称
}
// 记录 NFT 发行情况,防止重复发行
public struct MintRecord has key {
id: UID, // 唯一标识符
record: Table<address, u64>, // 发行记录
}
const MAX_SUPPLY: u64 = 10; // 最大发行量为 10
const ENotEnoughSupply: u64 = 0; // 错误码:供应不足
const EDontMintAgain: u64 = 1; // 错误码:不能重复发行
init
函数用于初始化 NFT 发行模块。主要步骤如下:
MintRecord
对象用于记录 NFT 发行信息。display
显示字段。MintRecord
和 display
转移给调用者(ctx.sender()
)。fun init(otw: LIZHECOMENFT, ctx: &mut TxContext) {
let keys = vector[
utf8(b"name"),
utf8(b"description"),
utf8(b"image_url"),
utf8(b"creator"),
];
let values = vector[
utf8(b"{name} #{nft_id}"),
utf8(b"A NFT for your Github avatar"),
utf8(b"{image_url}"),
utf8(b"{creator}"),
];
let mint_record = MintRecord {
id: object::new(ctx),
record: table::new<address, u64>(ctx),
};
let publisher = package::claim(otw, ctx);
let mut display = display::new_with_fields<GithubNFT>(&publisher, keys, values, ctx);
transfer::share_object(mint_record);
display::update_version(&mut display);
transfer::public_transfer(publisher, ctx.sender());
transfer::public_transfer(display, ctx.sender());
}
mint
函数用于发行新的 NFT,并将其转移给接收者。主要逻辑包括:
nft_id
。nft_id
是否超出最大供应量 MAX_SUPPLY
。GithubNFT
实例并触发 NFTMinted
事件。public entry fun mint(
mint_record: &mut MintRecord,
name: String,
image_url: String,
recipient: address,
ctx: &mut TxContext
) {
assert!(!table::contains(&mint_record.record, recipient), EDontMintAgain);
let nft_id: u64 = table::length(&mint_record.record) + 1;
table::add(&mut mint_record.record, recipient, nft_id);
assert!(nft_id <= MAX_SUPPLY, ENotEnoughSupply);
let nft = GithubNFT {
id: object::new(ctx),
nft_id,
name,
image_url,
creator: ctx.sender(),
recipient,
};
event::emit(NFTMinted {
object_id: object::id(&nft),
creator: ctx.sender(),
name: nft.name,
});
transfer::public_transfer(nft, recipient);
}
burn
函数用于销毁已发行的 NFT,并从 MintRecord
中移除相应记录。步骤如下:
MintRecord
的 record
表中移除接收者的记录。GithubNFT
对象。public entry fun burn(mint_record: &mut MintRecord, nft: GithubNFT) {
table::remove(&mut mint_record.record, nft.recipient);
let GithubNFT { id, nft_id: _, name: _, image_url: _, creator: _, recipient: _, } = nft;
object::delete(id);
}
以下是与该合约交互的命令示例,展示了如何在 Sui 区块链上进行初始化、铸造 NFT 和销毁 NFT。
7.1 合约部署
首先,需要在sui上部署合约
sui client publish
7.2 发行 NFT
调用 mint
方法来铸造 NFT,传入 mint_record
对象、NFT 名称、图片 URL、接收者地址。
sui client call \
--function mint \
--module lizhecomenft \
--package <PACKAGE_ID> \
--args <MINT_RECORD_OBJECT_ID> "My First NFT" "https://example.com/nft.png" <RECIPIENT_ADDRESS> \
--gas-budget 1000
<MINT_RECORD_OBJECT_ID>
: MintRecord
对象的 ID。"My First NFT"
: NFT 名称。"https://example.com/nft.png"
: NFT 的图片 URL。<RECIPIENT_ADDRESS>
: 接收者的钱包地址。7.3 销毁 NFT
使用 burn
方法销毁 NFT,移除记录并删除 NFT 对象。
sui client call \
--function burn \
--module lizhecomenft \
--package <PACKAGE_ID> \
--args <MINT_RECORD_OBJECT_ID> <NFT_OBJECT_ID> \
--gas-budget 1000
<NFT_OBJECT_ID>
: 要销毁的 NFT 的对象 ID。通过这段代码,我们就可以在 Sui 区块链上用 Move 语言发行第一个简单的 NFT。整体流程其实很清晰,分为三个主要步骤:
整个合约的设计思路比较简单明了,非常适合入门学习。我们通过几个基础的操作,就实现了 NFT 的发行、管理和销毁。从实际使用来看,交互命令也是很直观的,只需要按步骤执行,就可以完成从初始化到铸造再到销毁的全流程。
对于刚接触 Move 和 Sui 的开发者来说,这个例子是一个很好的入门项目,能帮助大家快速理解链上资产的管理和智能合约的基本结构。随着熟练度的提升,我们可以在这个基础上,进一步扩展更多功能,比如添加更多的元数据、增加 NFT 的转售功能等等。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!