1

首届Starcoin & Move黑客松源码分析——P(A)

 2 years ago
source link: https://learnblockchain.cn/article/2965
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

P(A)是首届Move黑客松NFT赛道的一个项目,由MemeX团队设计的。本届黑客松有多个NFT项目,从功能完整性、项目完成度、创意性、展示度等多个方面综合考虑,P(A)是一个不错的NFT项目。NFT是目前非常热门的一个赛道,而Move在NFT领域有很大的优势。P(A)使用Move实现,可以说很好地结合了Move的特性。

这里我们通过对合约源码进行分析,来学习一下如何使用Move实现一个简单的NFT。我们先来看 一 下P(A)项目的整体设计图:

从上面的图中可以看出一些重要的信息:

  1. 核心的数据结构:
  • NFT_Info
  • Market
  1. 核心函数:
  • init_market

从逻辑上来说,简单直接,合约Owner通过init_market初始化一个Market,普通用户可以mint来购买NFT。接下来我们深入分析一下源码。

核心数据结构

P(A)包含多个数据结构:Art、NFT、UniqList、NFT_INFO、MARKET,之间的关系如下图所示:

1. Art

struct Art has store, copy, drop {
    prob_a: u8,
    prob_b: u8,
    param_1: vector<u64>,
    param_2: vector<u64>
}

这是NFT渲染需要用到的元数据信息,没有key的ability,意味着能拷贝、能丢弃、能存储。这里建议NFT的元数据不能拷贝和丢弃。

struct NFT has store {
    id: u8,// 唯一标识
    next_nft_id: u8,// 通过链表的形式把NFT标识串起来,方便追踪
    next_nft_owner: address,// 通过链表的形式把address串起来,方便追踪
    data: Art,// NFT元数据
    sell_status: bool,// 状态
    price: u128,// 价格
}

这是NFT具体数据,只有存储的能力,意味着不能拷贝和丢弃。非常方便的发挥了Move的优势,利用虚拟机保障NFT的完整性、唯一性等等。

  1. UniqList
struct UniqList has key {
    data: vector<NFT> // 存储用户拥有的NFT列表
}

UniqList虽然使用了数组,但是这里不用担心大数组的问题,因为每个用户的NFT是存储在自己的账号下的,并不会影响到所有的用户。

  1. NFT_INFO
struct NFT_INFO has store, drop {
    id: u8,// NFT标识
    next_nft_id: u8,
    next_nft_owner: address,
    data: Art,
    price: u128,// 价格
}

这是NFT生成之后的信息,用于展示。有NFT的id了,Art在这里有点冗余。

  1. Market
struct MARKET has key {
    head: address,
    cur_num: u8,// 当前数量
    min_price: u128,// 最小价格
    market_nft_info: vector<NFT_INFO>// 所有的NFT信息
}

这里存放了所有的NFT信息。看上去有大数组的问题,因为P(A)限制了最多只能生成100个NFT,所以这里也不用担心。但是,类似这种列表展示数据,建议通过Event的方式,在链下聚合。

Function定义

  1. init_market函数
public(script) fun init_market(account: signer)

这是合约初始化入口,在合约的Owner账号下初始化一个Market。函数使用了public(script)可见性。

  1. mint函数
public(script) fun mint(account: signer, amount: u128) acquires UniqList, MARKET

这是用户购买NFT的入口,也是public(script) 可见性。acquires表示使用到了当前Module定义的UniqList和MARKET两个数据结构。

思考&总结

P(A)项目从合约实现细节来说,代码相对比较简洁,充分利用了Move在NFT场景的优势,省去了很多不必要的安全检查,比如防止NFT丢失等等。我们来总结一下合约代码实现上的优缺点。

  • NFT是一个热门的方向,也是Move发挥优势的一个典型应用场景
  • 部分Struct在定义的时候巧妙应用了Move的ability来保证安全可靠,例如NFT,不能拷贝和丢弃
  • 函数都是public(script) 可见性,没有暴露多余的入口
  • NFT数据分散存储在用户自己的账号下,NFT本身不会出现大数组的问题
  • 使用了链表的设计,方便追踪
  1. 可以进一步优化:
  • NFT内部数据Art也应该不能拷贝和丢弃,避免产生相同的内容的NFT
  • 关键数据状态变更应该定义Event,方便链下监听
  • Market的数组可以考虑链下存储,避免可能存在的大数组问题
  • 部分细节优化,例如Struct名称大小写风格统一、冗余数据等等
  • 可以增加更丰富的功能,比如NFT的转账等等

总的来说,P(A)巧妙地应用了Move的优势,在NFT的方向上做了很好的尝试,这里查看完整代码。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK