IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 区块链 -> Move精髓&动手设计NFT协议(下篇) -> 正文阅读

[区块链]Move精髓&动手设计NFT协议(下篇)

* 本文由Starcoin社区原创 作者:WGB 根据Starcoin & Move直播课《轻松掌握Move精髓》整理,点击查看原文,点击查看上篇

NFT协议的实现

通过Move语言的三大特性和常用的合约module进行配合,可以非常轻松地创建NFT协议,我们可以以渐进式的方式进行NFT协议的编写。

1. NFT协议 V1

在这段代码中实现了NFT的初始化和铸造,在第6行和第8行分别创建自己的NFT和NFT列表用来存放NFT,在第12行初始化NFT的列表以便可以接收和保存NFT,在第16行的铸造NFT函数中先判断是否可以接收NFT,如果不能则通过assert的判断直接退出并返回错误代码,保证NFT不会被不可接收的账户接收。这段代码实现了非常简单的NFT协议,可以通过其他的特性和功能进行完善。

1    address 0x2 {
2        module NFTExample1 {
3            use 0x1::Signer;
4            use 0x1::Vector;
5    
6            struct NFT has key, store { name: vector<u8> }
7    
8            struct UniqIdList has key, store {
9                data: vector<vector<u8>>
10            }
11    
12            public fun initialize(account: &signer) {
13                move_to(account, UniqIdList {data: Vector::empty<vector<u8>>()});
14            }
15    
16            public fun new(account: &signer, name: vector<u8>): NFT acquires UniqIdList {
17                let account_address = Signer::address_of(account);
18                let exist = Vector::contains<vector<u8>>(&borrow_global<UniqIdList>(account_address).data, &name);
19                assert(!exist, 1);
20                let id_list = borrow_global_mut<UniqIdList>(account_address);
21                Vector::push_back<vector<u8>>(&mut id_list.data, copy name);
22                NFT { name }
23            }
24        }
25    }

2. NFT协议 V2

通过Strcut可创建自己的NFT,但是如果需要创建其他类型的NFT就需要重新写代码,所以可以使用泛型编程的思想来重新构建NFT代码,在6行和8行定义带有泛型的NFT和NFT列表,在第12行定义初始化vector<u8>类型的NFT列表,在16行的函数的返回值和内部调用函数时使用的都是带有泛型的struct和函数,现在这个代码可以称作不完全的NFT框架,可以适合小范围测试的多个NFT。

1    address 0x2 {
2        module NFTExample2 {
3            use 0x1::Signer;
4            use 0x1::Vector;
5    
6            struct NFT<T: store> has key, store { name: T }
7    
8            struct UniqIdList<T: store> has key, store {
9                data: vector<T>
10            }
11    
12            public fun initialize(account: &signer) {
13                move_to(account, UniqIdList {data: Vector::empty<vector<u8>>()});
14            }
15    
16            public fun new(account: &signer, name: vector<u8>): NFT<vector<u8>> acquires UniqIdList {
17                let account_address = Signer::address_of(account);
18                let exist = Vector::contains<vector<u8>>(&borrow_global<UniqIdList<vector<u8>>> (account_address).data, &name);
19                assert(!exist, 1);
20                let id_list = borrow_global_mut<UniqIdList<vector<u8>>>(account_address);
21                Vector::push_back<vector<u8>>(&mut id_list.data, copy name);
22                NFT { name }
23            }
24        }
25    }

NFT协议V3

在上段代码中的new函数和initialize函数没有使用泛型参数,如果需要完成NFT的框架,就需要对这两个函数进行修改,在以下代码中把new函数和initialize函数也使用泛型进行修饰,使该NFT协议的灵活性大大提升,可以试用于多种不同的NFT测试。

address 0x2 {
    module NFTExample3 {
        use 0x1::Signer;
        use 0x1::Vector;
?
        struct NFT<T: store> has key, store { name: T }
?
        struct UniqIdList<T: store> has key, store {
            data: vector<T>
        }
?
        public fun initialize<T: store>(account: &signer) {
            move_to(account, UniqIdList {data: Vector::empty<T>()});
        }
?
        public fun new<T: store + copy>(account: &signer, name: T): NFT<T> acquires UniqIdList {
            let account_address = Signer::address_of(account);
            let exist = Vector::contains<T>(&borrow_global<UniqIdList<T>>(account_address).data, &name);
            assert(!exist, 1);
            let id_list = borrow_global_mut<UniqIdList<T>>(account_address);
            Vector::push_back<T>(&mut id_list.data, copy name);
            NFT { name }
        }
    }
}

4. NFT协议V4

通过对NFT协议的完善,可以在协议中增加Event,用来增加通知的功能可以在钱包中通知NFT的铸造通知。这段代码可以说是比较完整的简单NFT协议,可以再增加移动、销毁等功能,并增加图片显示等,配合前端应用可以制作出精美的NFT。

address 0x2 {
    module NFTExample4 {
        use 0x1::Vector;
        use 0x1::Event;
?
        struct NFT<T: store> has key, store { name: T }
?
        struct UniqIdList<T: store + drop> has key, store {
            data: vector<T>,
            nft_events: Event::EventHandle<NFTEvent<T>>,
        }
?
        struct NFTEvent<T: store + drop> has drop, store {
            name: T,
        }
?
        public fun initialize<T: store + drop>(account: &signer) {
            move_to(account, UniqIdList {data: Vector::empty<T>(), nft_events: Event::new_event_handle<NFTEvent<T>>(account)});
        }
?
        public fun new<T: store + copy + drop>(_account: &signer, account_address:address, name: T): NFT<T> acquires UniqIdList {
            let exist = Vector::contains<T>(&borrow_global<UniqIdList<T>>(account_address).data, &name);
            assert(!exist, 1);
            let id_list = borrow_global_mut<UniqIdList<T>>(account_address);
            Vector::push_back<T>(&mut id_list.data, copy name);
            let new_name = copy name;
            Event::emit_event(&mut id_list.nft_events, NFTEvent { name:new_name });
            NFT { name }
        }
    }
}

问答环节

在Starcoin的社区中有许多的开发者或关注者也在提出各种各样的问题,对于这些问题也有可靠的回答。

  • 问:投票时候币只有WithdrawEvent但是没有DepositEvent,这和老师刚讲的钱只能move有什么区别呢? 是move到vote合约的意思吗?
  • 答:对,Move的语义就是转移,在投票时所投的Token就是通过Move转移到投票合约中
  • 问:move上有类似ERC20这样的标准吗?
  • 答:有的,但是不是Move中的,是Starcoin的stdlib中定义的类似ERC20的协议。但是在以太坊上的eth和ERC20的协议的Token的权限有所不同,但是Starcoin上的Token都是一样的。
  • 问:Move有自定义异常和异常捕获吗?发现预期的异常得能处理吧
  • 答:可以的,比如交易丢掉或者回返在output中
  • 问:泛型后面ability是要和定义的一样,还是子集就行
  • 答:泛型字段的里的泛型可以和整体的Struct不完全相同,可以大于等于整体

  区块链 最新文章
盘点具备盈利潜力的几大加密板块,以及潜在
阅读笔记|让区块空间成为商品,打造Web3云
区块链1.0-比特币的数据结构
Team Finance被黑分析|黑客自建Token“瞒天
区块链≠绿色?波卡或成 Web3“生态环保”标
期货从入门到高深之手动交易系列D1课
以太坊基础---区块验证
进入以太坊合并的五个数字
经典同态加密算法Paillier解读 - 原理、实现
IPFS/Filecoin学习知识科普(四)
上一篇文章      下一篇文章      查看所有文章
加:2021-09-11 18:51:46  更:2021-09-11 18:52:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 12:29:30-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码