前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数字臧品系统开发铸造原理和开发细节分享

数字臧品系统开发铸造原理和开发细节分享

原创
作者头像
v_jie401214
发布2022-07-28 15:16:25
5760
发布2022-07-28 15:16:25
举报
文章被收录于专栏:数字臧品数字臧品

本文将解释如何从头开始铸造NFT并在opensea中销售。

首先,让我们谈谈NFT是什么。NFT是非同质令牌的缩写。同质令牌是BTC、ETH等,即张三手中的BTC和李四手中的BTC是完全等效的,而NFT不是。不能等价地交换张三手中的NFT和李四手中的NFT。最早的NFT是由加密猫制作的。所有加密猫均由同一份合同签发,但每种猫都不同。因此,每个cat都有一个唯一的令牌ID。这是NFT的特征:每个NFT都有一个唯一标识符

然而,应该注意的是,所谓的唯一标识符仅指在同一合同中发布的NFT,它们的令牌ID都是唯一的。在不同合同中发布的NFT可能具有相同的令牌ID。因此,NFT的真正唯一标识符实际上是合同地址+令牌ID

在opensea中,集合(如Cryptopunk)都是由合同发送的NFT。因此,要发布集合,首先创建一个合同,然后所有与此合同一起发布的NFT将自动收集到此集合

NFT有两个标准:eip-721和eip-1155。721标准相对简单。它只需要确保NFT对应于唯一的令牌ID,因为令牌ID只对应于一个NFT,而1155稍微宽松一些。一个NFT可以有多个,例如,有10个化身,最多可以由10个人持有。如果每个NFT只发送一个,那么它与721

没有什么不同,因此我们只需要支持1155,这相当于与721兼容。1155的NFT接口主要包括以下内容:

根据令牌ID返回元数据的URL:URI(uint256 ID)

查询地址拥有的令牌ID数:balanceof(address account,uint256 ID)

授权或取消授权地址传输NFT:setapprovalforall(address operator,boot approved)

传输NFT:safetransferfrom(address from,address to,uint256 ID,uint256 amount, bytes calldata data)可以在openzeppelin上找到369eip-1155定义的接口和实现。我们只需要在erc1155的基础上进行修改。erc1155的核心代码实际上是一个映射,将令牌ID记录到持有地址,然后记录到持有数量:

contract ERC1155 { // Mapping from token ID to account balances mapping(uint256 => mapping(address => uint256)) private _balances; }

我们做的主要修改是增加一个Token ID到URL的映射。因为我们准备将NFT的图片和Metadata数据都放到IPFS上,所以增加一个Token ID到IPFS文件哈希的映射:

contract ERC1155 { mapping(uint256 => string) private _metadataHashes; string private _uriPrefix = “https://ipfs.infura.io/ipfs/”;

// 返回”https://ipfs.infura.io/ipfs/QmasWH…re2Ych?filename=metadata.json” // 如果使用服务器API返回则可以固定uri为”https://api.example.com/metadata/{id}” function uri(uint256 id) public view returns (string memory) { return _concat(_uriPrefix, _metadataHashes[id], “?filename=metadata.json”); } }

第二个修改是增加一个mint()方法来铸造NFT:

function mint(uint256 amount, string memory metadataHash) public returns (uint256) { // 如果只允许合约部署者铸造,加上判断: // require(msg.sender == owner, “Not contract owner”); nextTokenId++; uint256 tokenId = nextTokenId; _metadataHashes[tokenId] = metadataHash; _mint(msg.sender, tokenId, amount, “”); return tokenId; }

最后一步是在isApprovedForAll()中判断下当前转移操作的发起者是不是OpenSea的代理合约:

function isApprovedForAll(address account, address operator) public view returns (bool) { // Whitelist OpenSea proxy contract for easy trading. ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress); if (address(proxyRegistry.proxies(account)) == operator) { return true; } return _operatorApprovals[account][operator]; }

这么做的目的是将来在OpenSea售卖的时候,不需要授权操作,节省了gas费,缺点是无条件信任了OpenSea的代理合约,降低了一点安全性。

NFT铸造流程 理解NFT的铸造流程是非常重要的。首先,一个NFT关联了一个特定的资源,如图片、视频、3D模型、VR等。假定我们的NFT就是一个图片,铸造NFT的第一步是将图片上传并获得一个固定的URL。这里我们选择IPFS,上传成功后返回的URL类似:

https://ipfs.infura.io/ipfs/QmaCR37BEGv6aZzzfJ1ShT8tu52UWosVgN9ookYY94FVVt?filename=file.png

第二步是准备NFT的Metadata,也就是NFT的描述信息。标准的Metadata就是一个JSON文件,内容如下:

{ “name”: “EIP-1155 based NFT”, “description”: “Public Mintable EIP-1155 based NFT”, “external_url”: “https://michaelliao.github.io/simple-nft/”, “image”: “https://ipfs.infura.io/ipfs/QmaCR37BEGv6aZzzfJ1ShT8tu52UWosVgN9ookYY94FVVt?filename=file.png”, “attributes”: [ { “trait_type”: “Type”, “value”: “EIP-1155” }, { “trait_type”: “Author”, “value”: “Crypto Michael” } ] }

attributes就是NFT的属性,有多少个就往里填多少个。JSON文件也需要一个URL,可以用服务器的API返回,也可以直接上传到IPFS拿到一个URL,这个JSON的URL就是NFT的Metadata的URL,也是合约方法uri(uint256 id)返回的URL。

最后一步,我们调用mint()方法并传入NFT的Metadata的IPFS哈希,就完成了一个NFT的铸造!

铸造后默认的持有人是铸造者本人。如果切换到OpenSea并以铸造者身份登录,就可以看到我们刚铸造出的NFT:

NFT数藏系统之铸造原理和技术开发细节插图
NFT数藏系统之铸造原理和技术开发细节插图

那么问题来了:OpenSea是如何知道我们铸造的NFT并且获得了NFT的图片以及相关信息?

因为我们在铸造的时候,mint()方法写入了一条NFT转移日志,该日志记录了NFT的Token ID、数量和所有者,OpenSea读取链上的日志就可以知道该地址拥有了新铸造的NFT以及NFT的ID和数量。

紧接着,OpenSea通过调用合约方法uri(uint256 id)可以获得Metadata的URL,读取该JSON后,通过JSON文件内的”image”:”https://…”可以获取到NFT对应的图片URL,这样,根据一个合约地址和Token ID,可以获得一个NFT的所有信息。

最后,我们还需要编写一个页面,能把上传图片、设置Metadata、上传Metadata、调用合约mint()方法一键完成。可以参考网页https://michaelliao.github.io/simple-nft/:

NFT数藏系统之铸造原理和技术开发细节插图1
NFT数藏系统之铸造原理和技术开发细节插图1

有的同学已经看出来了,一个NFT除了Token ID和数量写在合约里不能变以外,返回的URL虽然链接是固定的,但是完全可以控制该URL以便返回修改后的Metadata,所以Metadata的内容是完全可以修改的,它对应的图片也是完全可以修改的,因此,所谓NFT不可修改,仅仅指Token ID和数量不能修改,NFT背后对应的元数据和资源文件都是可修改的,会不会修改完全看开发者的人品,并且元数据的URL也是有可能失效的。

最后我们总结一下发行NFT的5个步骤:

1.编写并部署一个1155合约; 2.上传资源文件(例如图片); 3.上传Metadata文件; 4.写入合约铸造; 5.在OpenSea售卖。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档