一个数据驱动的动态 NFT 实现方案

news2024/11/19 11:29:05

1 背景

2022 年是 Web3 行业很不如意的一年,DeFi 旧力已去,游戏和社交应用新力未发,放眼望去,似乎只有 NFT 仍然热度不减,各种应用、各种概念也是层出不穷,几乎是独力支撑熊市当中 Web3 的希望。除了围绕 NFT 艺术品层出不穷的新玩法之外,过去一年至少有两项基础创新值得关注:

第一是 Chainlink 提出的 dNFT (动态 NFT),即发布之后还能够响应外部事件而变化的 NFT。

第二是 Solv Protocol 提出的 ERC-3525 半匀质化通证(SFT),不但具有动态变化的能力,而且像 ERC-20 一样可以计算,像账户一样能够接受、存储、发送和编程数字资产,特别适合表达复杂的数字资产,如金融票据、积分卡、真实世界资产等等。

无论是 dNFT 还是  SFT,相比于原始的 NFT,可以动态变化的图像都是一个突出的亮点。我们知道,目前艺术类 NFT 的主要价值就在于其图像外观。而此类 NFT 的图像大都是每 ID 或者每品类固定,在 NFT 创造之初就已经确定,一旦确定就终生不能修改。这种业务逻辑之下,我们并不需要更复杂的机制,简单的静态图像就可以满足需求。而面向复杂应用的 NFT 则不然,如果 NFT 的图像能根据业务流程和外部事件“动起来”,那么无疑将会大大提升 NFT 的应用价值和用户体验。这种可以动态 NFT,我们称之为数据驱动的动态 NFT,或数据驱动的 dNFT,以区别于由时间轴驱动的、简单重复的动画 NFT。

以 Uniswap V3 为例,其交易对 LP NFT 是一种金融 NFT,定义和展现了一个 LP 的作市策略和资金头寸。由于 Uniswap V3 在开发时并没有成熟的 dNFT 解决方案,ERC-3525 更是还需要一年半才会问世,因此其开发团队所实现的 NFT 仍然是静态的、固定的,并不能够动态地显示用户的所有者、当前头寸、当前价格、无常损失等动态数据,可以说是 Uniswap 团队由于 NFT 技术限制而在产品层面进行了的妥协。如果当时存在这样的技术,NFT 的图像可以响应底层数据的变化而发生变化,向 Uniswap 的 LP 提供丰富的实时信息,那么无疑会大大提升 Uniswap V3 LP NFT 的信息透明度和用户体验。这就是典型的数据驱动的 dNFT。请注意,这里的动态图像并不是简单的时间轴动画,而是数据驱动的、可响应外部事件而变化的图像。

本文介绍了一种实现数据驱动的 dNFT 的方案,我们在实践中已经部署了这个方案,经验证非常有效,且能够与主流 NFT 平台对接。

2. 方案

我相信,大家对 NFT 已经非常熟悉了,其核心属性也耳熟能详。token id、token URI、owner,其中token URI 描述 NFT 的扩展属性,正是其构建复杂应用的核心字段。该字段也被当前主流的 NFT 交易平台 Opensea 所扩展,并被各方广泛认可。我们的生成动态NFT图像的方案也正是围绕该字段构建。

试想一下,有如下需求:在 Uniswap V3 交易对NFT上展示owner及头寸(position)信息。

我们会面临哪些问题?有什么样的解决方案呢?

41257f85516a172456a74b77245fdebf.png

在Uniswap V3 交易对 NFT 图像中,我们面临的问题就是如何生成动态 NFT 图像。LP 易主或者头寸产生变动时,都会驱动图像的刷新。

怎么开发这样的 NFT 呢?基本思路是,按需动态渲染生成 NFT 图像,在访问时实时渲染生成图像。

展开来描述。目前Uniswap V3 交易对 NFT 图像只展示静态数据,我们的目标是增加 Owner (所有者)和 Position (头寸)的 LP NFT 图像,我们可以把图像和数据分解开来:

  • 底图 —— NFT 图像的整体架构

  • 数据 —— NFT 图像上的可变数据

因此,我们生成动态NFT图像的方式是:以一个固定的底图为模板,在用户访问时基于数据实时生成图像的动态部分。

2.1 底图

  • 底图配置(索引)

其中,可以根据合约地址配置,一个合约发出的所有 dNFT 共用同一个底图。也可以基于某一个属性动态选择底图,比如,在 Uniswap V3 中可以根据动态收益率来选择不同的底图,收益率越高,底图越喜庆。

contract address → background image A

contract address + 0.5% → background image 1

contract address + 1% → background image 2
  • 底图格式

底图格式决定图像生成的技术,我们的最佳实践是 SVG 格式。SVG 格式底图模板示例如下:

<?xml version="1.0" encoding="UTF-8"?>
    <svg width="600px" height="400px" viewBox="0 0 600 400" version="1.1" xmlns="<http://www.w3.org/2000/svg>" xmlns:xlink="<http://www.w3.org/1999/xlink>">
        <style>
            .text {
                pointer-events: none;
                -webkit-user-select: none;
                -moz-user-select: none;
                -ms-user-select: none;
                user-select: none;   
                font-variant-numeric: tabular-nums lining-nums;                 
            }
        </style>
        <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
            <g>
                <rect fill="#FFFFFF" opacity="0" x="0" y="0" width="600" height="400"></rect>
                <text font-family="Arial" font-size="36" font-weight="bold" fill="#FFFFFF" class="text">
                    <tspan x="48" y="48">Owner: {{OwnerPlaceholder}}</tspan>
										<tspan x="48" y="80">USDC: {{USDCPlaceholder}}</tspan>
										<tspan x="48" y="116">WETH: {{WETHlaceholder}}</tspan>
                </text>
            </g>
        </g>
    </svg>

基于 SVG 底图模板,获取NFT相关数据之后,只需用字符串模板工具替换相应 Placeholder 即可生成图像。

2.2 业务数据

获取业务数据的方式取决于 NFT 应用的实现方式。一个常用的模式是调用合约 tokenURI 接口,将返回结果基于业务解析即可获取业务数据。下面介绍这种模式的具体做法。

以下是 ERC-721 的元数据接口:

interface ERC721Metadata /* is ERC721 */ {
    /// @notice A descriptive name for a collection of NFTs in this contract
    function name() external view returns (string _name);

    /// @notice An abbreviated name for NFTs in this contract
    function symbol() external view returns (string _symbol);

    /// @notice A distinct Uniform Resource Identifier (URI) for a given asset.
    /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC
    ///  3986. The URI may point to a JSON file that conforms to the "ERC721
    ///  Metadata JSON Schema".
    function tokenURI(uint256 _tokenId) external view returns (string);
}

这个接口中的 tokenURI() 函数可以返回一个 URI,指向该 NFT 对应的元数据资源在网络上的位置。对于一个实现了 ERC721Metadata 接口的 NFT,我们可以调用 tokenURI() 接口,获得该 NFT 的元数据。

ERC-721 标准对于元数据结构进行了以下建议:

{
    "title": "Asset Metadata",
    "type": "object",
    "properties": {
        "name": {
            "type": "string",
            "description": "Identifies the asset to which this NFT represents"
        },
        "description": {
            "type": "string",
            "description": "Describes the asset to which this NFT represents"
        },
        "image": {
            "type": "string",
            "description": "A URI pointing to a resource with mime type image/* representing the asset to which this NFT represents. Consider making any images at a width between 320 and 1080 pixels and aspect ratio between 1.91:1 and 4:5 inclusive."
        }
    }
}

很显然,关于这个 NFT 的动态数据,应该放在元数据中,以便被读取。

不过 NFT 的元数据结构并非一定,标准所规定的的格式也未必是最合理。开发者完全可以基于应用的具体情况来定义自己的元数据结构。

例如,OpenSea 就建议了另一个元数据的结构,以下是一个例子,具体建议请参见:https://docs.opensea.io/docs/metadata-standards

{
  "description": "Friendly OpenSea Creature that enjoys long swims in the ocean.", 
  "external_url": "<https://openseacreatures.io/3>", 
  "image": "<https://storage.googleapis.com/opensea-prod.appspot.com/puffs/3.png>", 
  "name": "Dave Starbelly",
  "attributes": [ ... ]
}

不管用哪种元数据结构,开发者都必须清楚地定义这种结构,并且将数据放在这个结构中,供 DAPP 调用。DAPP 读取元数据后,通过解析获得

2.3 实现方案

在当前技术条件下,底图结合动态数据驱动实时渲染生成动态 NFT 图像,还需要部署一个中心化服务来配合 DAPP 才能实现。前两节已经介绍了底图的定义方式和 NFT 应用业务数据的获取模式。这个方案的大致处理流程如下:

f6ca9dfd24edc23eb198ec4da69e3de5.png

  • 首先,DAPP(或其他Client) 向 Image Handler 发送一个 image URI 请求获得对应的图像;

  • Image Handler 是一个动态图像服务,收到 image调用后,向 RPC Node 发起请求,调用相应 NFT 合约的 tokenURI 函数获得 NFT metadata;同时,Image Handler 到指定位置获得底图模板代码;

  • 获取 metadata 后,根据相关 NFT 底图模板和 metadata 中的数据,替换底图 NFT 模板中的 Placeholders,从而实时生成 SFT 图像,这一过程也称为“渲染”:

{
  "name": "Image Handler Example",
  "description": "This is an image handler example.", 
  "image": "image URI", 
}

其中 image 字段即为特定 image URI,其路由形式可以灵活设计,例如:

<https://image-handler/meta/images/0xsdfh...sdf/1>
<https://image-handler/image?contractaddress=0xsddf..sdf&tokenid=1>

这个解决方案的重点是,Image Handler 必须能够根据这个 URI 顺利地同时找到所需的底图和数据资源,然后将两者结合起来实时渲染 SVG 图像,从而展示出来。

3 小结

随着复杂 NFT 应用的不断涌现,生成数据驱动的动态 NFT 的需求将会越来越多,以上只是可行方案之一,希望能够抛砖引玉。值得一提的是,ERC-3525 标准对于数据驱动的动态 SFT 提供了更高水平的支持,以后我们将介绍基于 ERC-3525 的数据驱动、实时渲染的动态 SFT 生成方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/183632.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MFC】MFC应用程序流程(11)

在WIN32应用程序中使用MFC于MFC框架创建的应用程序流程基本上一致的&#xff0c;不同之处是对MFC框架的使用。 MFC应用程序流程 应用程序类继承CWinAppEx&#xff08;类似CWinApp&#xff09;&#xff0c;编译时注入的WinMain函数利用多态机制实现应用程序初始化&#xff1a;…

LaoCat带你认识容器与镜像(番外一【Harbor】)

祝大家开工大吉呀&#xff0c;新的一年要有新的收获呀 ~ 本章内容 搭建Docker镜像私仓Harbor&#xff0c;并配置Docker私仓。 本文实操全部基于Ubuntu 20.04 宿主机 > linux服务器本身 Harbor > 2.5.3 Docker系列文章之仓库篇就介绍了Docker有俩种类型的镜像仓库&#x…

AppShark:一款针对Android应用程序的静态分析与漏洞扫描框架

关于AppShark AppShark是一款针对Android应用程序的安全测试框架&#xff0c;该工具本质上是一个静态污点分析平台&#xff0c;可以用于扫描Android应用程序中的漏洞。 AppShark除了实现行业普遍应用的数据流分析&#xff0c;还将指针分析与数据流分析融合&#xff0c;因而漏…

【项目精选】基于SpringBoot+Vue实现的仿掘金论坛系统(包含完整源码以及部署教程)

项目简介 本论坛基于SpringBootVue框架实现前后端分离&#xff0c;自适应手机端和电脑端&#xff0c;界面简洁美观&#xff0c;功能完善&#xff0c;性能高效。分为用户系统和管理系统两部分。 大厂微服务架构设计&#xff1b;代码简洁、高效无冗余&#xff1b;注释详细易阅读…

LabVIEW 在NI Linux实时设备上访问Shell

LabVIEW 在NI Linux实时设备上访问Shell有一台运行NI Linux实时操作系统的设备&#xff0c;想访问设备上的shell或终端。要使用以下任一方法与设备通信&#xff0c;必须在计算机上安装终端客户端。使用SSH连接&#xff1a;1. 打开电源并将设备连接到网络或直接连接到计算机。2.…

已解决:Linux安装Docker完整过程

① 目的 接口自动化接口需要持续集成&#xff0c;最终选择Jenkins来实现。通过docker来实现安装部署Jenkins ② 环境 Linux ③Docker的自动化安装 Docker官方和国内daocloud都提供了一键安装的脚本&#xff0c;使得Docker的安装更加便捷。 官方的一键安装方式&#xff1a; curl…

C#,索尼偏光相机(Polarization Camera)传感器IMX250和专用SDK简介

以下文字用百度翻译&#xff0c;效果一般&#xff0c;凑合看吧。2018年12月开始上市的索尼偏光相机和偏光相机专用SDK实现了高功能、高画质、高速处理。其要点在于&#xff0c;开发为不在需要专业知识的偏振信号处理的安装中花费工时&#xff0c;能够以最小限度的成本利用的SDK…

逆战成钢!大势智慧2023新春年会暨表彰大典圆满举行

2023年1月14日&#xff0c;大势智慧2023新春年会暨表彰大典如期举行。暂别了疫情的阻隔&#xff0c;大势智慧武汉总部与各分公司成员时隔两年再次迎来“面对面拥抱”。三百多名大势成员群贺新春&#xff0c;共同度过了一次难忘的年会盛典。 逆战成钢 用奋战实现业绩、规模高增…

Flutter 2023 Roadmap 解析

随着 Flutter Forward 大会召开&#xff0c; Flutter 官方在 3.7 版本 之余为我们展示了如 3D 渲染支持、add-to-web 等未来可能出现的 Feature&#xff0c;但是这些都还只是处于开发中&#xff0c;未来可能还会有其他变动&#xff0c;而在大会结束后&#xff0c;官方也公布了更…

【GD32F427开发板试用】基于蓝牙模块的远程点灯演示

本篇文章来自极术社区与兆易创新组织的GD32F427开发板评测活动&#xff0c;更多开发板试用活动请关注极术社区网站。作者&#xff1a;寒冰1988 一. 前言 感谢极术社区联合兆易创新组织的本次活动&#xff0c;很荣幸能够中签本次的试用机会&#xff0c;结合手里的外围模块&…

代码随想录算法训练营第31天 回溯算法 93.复原IP地址 78.子集 90.子集II

文章目录LeetCode 93.复原IP地址题目讲解思路LeetCode 78.子集题目讲解思路LeetCode 90.子集II题目讲解难点总结LeetCode 93.复原IP地址 题目讲解 思路 递归参数 startIndex一定是需要的&#xff0c;因为不能重复分割&#xff0c;记录下一层递归分割的起始位置。 本题我们还…

ubuntu1804搭建svo2.0环境并跑euroc数据集

0说明 整个SVO2.0环境搭建过程按照官网的说明进行(链接&#xff1a;https://github.com/uzh-rpg/rpg_svo_pro_open) 开发环境是ubuntu18.04ROS-Melodic 1工具安装 Install catkin tools and vcstools if you haven’t done so before. Depending on your operating system …

使用这个插件,fiddler抓包直接生成httprunner脚本

har2case可以将.har文件转化成yaml格式或者json格式的httprunner的脚本文件&#xff0c;生成.har格式文件可以借助 fiddler 或 Charles 抓包工具 友情提示&#xff1a; 录制脚本&#xff0c;只是一个过渡&#xff0c;从0到1的一个过渡&#xff0c;如果让你直接写脚本&#xff…

微信app hook修改剪刀石头布以及骰子思路

0x01 前言 该方法很简单&#xff0c;本次记录是为了加深对安卓hook技术的学习&#xff0c;以及进一步熟悉frida和objection的使用&#xff0c;如果只是想需要这个功能&#xff0c;推荐手机root后装微x模块 技术仅供分享&#xff0c;请勿用于非法用途 0x02 环境准备 首先需要准…

linux下更新tomcat版本

进入tomcat目录下查看当前版本号./version.sh2.切忌升级之前一定要备份老版本mkdir tomcat-backup3.拷贝老版本到你创建的文件夹中cp -rf apache-tomcat-9.0.45-stunew/ tomcat-backup/4.下载tomcat安装包&#xff0c;随便你下载什么版本&#xff0c;我这里以68为例官网&#x…

ssm二手废旧塑料回收交易系统的设计与实现

内容是设计并且实现一个废旧塑料交易系统的设计与实现。它是在Windows下&#xff0c;以MYSQL为数据库开发平台&#xff0c;Tomcat网络信息服务作为应用服务器。废旧塑料交易系统的设计与实现的功能已基本实现&#xff0c;主要包括用户、回收站、加工厂、预约信息、收购信息、交…

ARP协议与ARP地址欺骗防护

ARP协议 什么是MAC地址 MAC地址是固化在网卡上的网络标识&#xff0c;由Ieee802标准规定。 什么是广播 向同一个网段内的设备&#xff0c;发送数据包&#xff0c;广播IP地址是同网段最后一个IP地址。 认识ARP协议 ARP的全称是地址解析协议&#xff0c;我们通过ARP协议获取…

Webpack 运行时代码分析 - 动态加载

文章内容&#xff1a;用 webpack 打包含有动态加载的模块&#xff0c;分析打包后的代码&#xff0c;也就是 webpack 运行时代码。 先思考如下一些问题&#xff1a; 1.什么叫做动态加载 2.如果不使用 webpack 打包&#xff0c;能做到动态加载吗 3.webpack 是如何实现动态加载的…

安装mysql的保姆级教程

安装mysql的保姆级教程&#xff1a; 1.准备的条件 已下载mysql应用软件 my.ini文件&#xff08;见2&#xff09; 2.设置my.ini文件 &#xff08;1&#xff09;my.ini文件内容&#xff1a; [mysqld] # 设置3306端口 port3306 # 设置mysql的安装目录 ----------是你的文件路径…

TCP/IP网络编程——基于 UDP 的服务端/客户端

完整版文章请参考&#xff1a; TCP/IP网络编程完整版文章 文章目录第 6 章 基于 UDP 的服务端/客户端6.1 理解 UDP6.1.1 UDP 套接字的特点6.1.2 UDP 的工作原理6.1.3 UDP 的高效使用6.2 实现基于 UDP 的服务端/客户端6.2.1 UDP 中的服务端和客户端没有连接6.2.2 UDP 服务器和客…