什么是Metadata
Metadata通常直译为“元数据”,本质上是NFT内容的描述数据。
通常一份Metadata长这样:
// 从Amadeus工具中导出的Metadata { "name":"test #0", "description":"Your NFT collection!", "image":"/0.png", "attributes":[ { "trait_type":"eye", "value":"blue" }, { "trait_type":"body", "value":"thin" }, { "trait_type":"arm", "value":"long" } ] }
注: 上面所展示的Metadata实际上是Opensea所支持的格式,是Opensea所制定的规范。如果你的项目想要在Opensea上进行展示,就一定要以这样的格式出现。 一份Metadata中包含几个关键部分:
- name:NFT的名称
- description:NFT的描述语句
- image:指向NFT最终展示Image的链接
- attributes:NFT所包含的特征
以上几个关键部分与Opensea上内容的对应关系如下图所示:
也就是说,NFT的Metadata存储着用户在Opensea上所看到的内容。
为什么需要Metadata
我们都知道非同质化是NFT最重要的属性,就像那句“世界上没有两片相同的树叶”,而NFT的非同质化如何体现呢?仅仅是NFT的Token ID不同吗?
绝大多数NFT系列是由符合ERC-721标准或ERC-1155标准的合约所创建的,ERC-721和ERC-1155提供了Metadata的拓展选项,能让合约拥有者去诠释这份NFT资产的名称和数据内容。
而NFT的非同质化也更多的被Metadata中迥然不同的数据形式和内容所体现。
如何为NFT绑定Metadata
当我们在Opensea上查看自己最喜爱的NFT时,页面上通常展示出丰富的metadata。Opensea是如何获取这些信息的呢?
如果你曾经了解过ERC721和ERC1155标准,你就会发现,这两项标准中其实并没有对Metadata做出强制的规定。也就是说,如何将NFT与Metadata绑定实际上是一个非常自由的事情。
但显然,完全的自由不是一个逐渐走向统一规范市场的常态。
后续逐渐出现了ERC-721Metadata和ERC-1155Metadata规范,他们定义了NFT与Metadata绑定的标准方式(比如openzeppelin),后续的NFT项目在编写Metadata也有章可循。Opensea这样的Marketplace也无需苦苦思考如何适配市场海量的Metadata格式。
ERC-721Metadata和ERC-1155Metadata规范是对ERC-721和ERC-1155的一个扩展,他们总结了一套标准方法和必要的变量。例如,ERC-721Metadata定义了一个外部方法:tokenURI。该方法的具体功能是:当用户调用这一方法,给他传递要查看的token Id,就可以得到对应的Metadata。
Metadata的表现方式
上一部分中说到Opensea需要读取某个NFT项目背后智能合约的tokenURI方法(ERC-1155标准为uri方法)来获取某个NFT对应的Metadata。那么Opensea能够理解的Metadata有哪些呢?
-
链接
Opensea可以解析链接,包括HTTP/HTTPS/IPFS/AR。需要注意的是,首先链接需要通过最基本的GET请求获取内容。也就是说,将这一链接粘贴到HTTP浏览器/IPFS浏览器中可以获取到其中的内容,而不无需额外操作。
-
Json文档
直接返回内容,不需要Opensea做二次内容寻找。
上述两种方式各有优劣:
- 对于链接的方案,优势在于可以减少链上存储的数据量,最直观的表现就是节省了部署时候的gas费用。但由于Metadata的实际内容上是由项目方的服务器所控制的,因此可以随意修改,用户权益依旧没有得到去中心化的保障。折中的解决方案就是使用IPFS链接,由于IPFS的不可修改性从而保证Metadata的不可修改。
- Json文档的方案优势在于所有的Metadata都以明文的形式写在合约中,用户可以直接读取到某个NFT的Metadata而不需要二次跳转。同时由于智能合约代码量的增加,部署价格也会略贵于链接的方案。并且对于以太坊,由于存在着代码部署大小的限制(编译产物单个文件最大不超过24.576KB),太多的明文写在合约中会占用过多空间,导致放不下更多功能。
总之,如果某NFT系列想要在Opensea等dapp正确读取并展示其metadata,需要遵照相应dapp的规范格式,具体细节请查看其官方文档。
Image的表现方式
在Metadata中,name和description是对NFT的介绍信息,attributes更多的承载了检索的功能。而用户最关心的,也是最直观表现NFT的是其中的image,因此在这里特别讲解一些常见的Image表现方式。
在第一部分的Opensea Metadata格式中我们可以看到,image是其中的一个字段。和Metadata一样,也有两大类表现方式:
- 图片链接。同样分为服务器链接和IPFS链接两种。链接所指向的内容应当是图像本身。
- 图像本身:这里就涉及到了一些互联网中图像的绘制方式。可以以svg格式描述图像(Loot采用的方式),也可以用base64编码描述图像。具体的方式大家感兴趣可以自行了解一下~
优劣也与Metadata基本相同,这里就不再赘述。
Metadata的最佳实践
最佳实践的目标是实现一个不需要中心化服务器的NFT项目,因此Image和Metadata都选择IPFS存储。
前期准备:
- NFT集合的图像,文件名由0.png/jpg ~ n.png/jpg
- 未填入image字段的metadata文档, 文件名由0~n
- 已完成部署的智能合约
- 注册好Pinata账户
第一步:将图像上传至IPFS。 进入Pinata,文件上传,将NFT集合的所有图像放置在一个文件夹内,进行上传。上传完毕后,你将可以在Pinata的已上传文件列表中看到刚刚上传的文件夹。将第二列CID中对应的值复制下来,待后续使用。 第二步:为Metadata文档填入image字段。 补全每个Metadata文档。例如对于0号Metadata文档:
{ "name":"test #0", "description":"Your NFT collection!", "image":"ipfs://[CID]/0.png", "attributes":[ { "trait_type":"eye", "value":"blue" }, { "trait_type":"body", "value":"thin" }, { "trait_type":"arm", "value":"long" } ] }
将第一步中得到的CID填入上述文档中[CID]
的位置即可。
第三步:将Metadata文件夹上传至IPFS。
进入Pinata,文件上传,将NFT集合的所有Metadata放置在一个文件夹内,与id一一对应,进行上传。上传完毕后,你将可以在Pinata的已上传文件列表中看到刚刚上传的Metadata文件夹。将第二列CID中对应的值复制下来,待后续使用。
第四步:设置合约baseURI。
在Etherscan上访问已完成部署的合约,调用setBaseURI方法,传入"ipfs://[CID]/"
。将第三步得到的Metadata CID填入前面的[CID]
即可。
至此,Metadata的最佳实践就完成啦,如果想要更换Collection的Metadata,可以再进行一次上述四个步骤。
总结
在我的视角来看,NFT就像是元宇宙中的物体,每一个物体都有自己的特点,都是不可取代的。Metadata则是这个物品的描述信息,记录着这个物品所包含的内容。Image则是物体真实的模样。 目前Opensea所支持的Metadata内容还是有限的,例如无法支持多个图片的组合和叠加等。NFT还有很大的提升与变化空间。