我們會面臨哪些問題?有什麼樣的解決方案呢?
作者: Clark Wu(ERC-3525 作者之一,Solv Protocol 核心開發者)
NFT 基礎層創新:動態 NFT 和 ERC-3525
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 平台對接。
基於 ERC-3525 的動態 NFT 實現方案
我相信,大家對 NFT 已經非常熟悉了,其核心屬性也耳熟能詳。token id、token URI、owner,其中 token URI 描述 NFT 的擴展屬性,正是其構建複雜應用的核心字段。該字段也被當前主流的 NFT 交易平台 Opensea 所擴展,並被各方廣泛認可。我們的生成動態 NFT 圖像的方案也正是圍繞該字段構建。
試想一下,有如下需求:在 Uniswap V3 交易對 NFT 上展示 owner 及頭寸(position)信息。
我們會面臨哪些問題?有什麼樣的解決方案呢?
Uniswap V3 交易對 NFT 圖像中,我們面臨的問題就是如何生成動態 NFT 圖像。LP 易主或者頭寸產生變動時,都會驅動圖像的刷新。
怎麼開發這樣的 NFT 呢?基本思路是,按需動態渲染生成 NFT 圖像,在訪問時實時渲染生成圖像。
展開來描述。目前 Uniswap V3 交易對 NFT 圖像只展示靜態數據,我們的目標是增加 Owner(所有者)和 Position(頭寸)的 LP NFT 圖像,我們可以把圖像和數據分解開來:
底圖—— NFT 圖像的整體架構
數據—— NFT 圖像上的可變數據
因此,我們生成動態 NFT 圖像的方式是:以一個固定的底圖為模板,在用戶訪問時基於數據實時生成圖像的動態部分。
2.1 底圖
底圖配置(索引)
其中,可以根據合約地址配置,一個合約發出的所有 dNFT 共用同一個底圖。也可以基於某一個屬性動態選擇底圖,比如,在 Uniswap V3 中可以根據動態收益率來選擇不同的底圖,收益率越高,底圖越喜慶。
contractaddress → background image Acontractaddress + 0.5% → background image 1contractaddress + 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>
2.2 業務數據
獲取業務數據的方式取決於 NFT 應用的實現方式。一個常用的模式是調用合約 tokenURI 接口,將返回結果基於業務解析即可獲取業務數據。下面介紹這種模式的具體做法。
以下是 ERC-721 的元數據接口:
interface ERC721Metadata /* is ERC721 */ {/// @notice A descriptive name for a collection of NFTs in this contractfunction name() external view returns (string _name);/// @notice An abbreviated name for NFTs in this contractfunction 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 應用業務數據的獲取模式。這個方案的大致處理流程如下:
首先,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 圖像,從而展示出來。
小結
隨著複雜 NFT 應用的不斷湧現,生成數據驅動的動態 NFT 的需求將會越來越多,以上只是可行方案之一,希望能夠拋磚引玉。值得一提的是,ERC-3525 標準對於數據驅動的動態 SFT 提供了更高水平的支持,以後我們將介紹基於 ERC-3525 的數據驅動、實時渲染的動態 SFT 生成方案。
免責聲明:作為區塊鏈信息平台,本站所發布文章僅代表作者及嘉賓個人觀點,與 Web3Caff 立場無關。文章內的信息僅供參考,均不構成任何投資建議及要約,並請您遵守所在國家或地區的相關法律法規。