如此精簡優美的 NFT 協議+NFT 交易市場,僅僅使用 230 行代碼就在 2017 年實現,並且演變為目前世界上最有價值的藍籌 NFT 之一,是值得研究的產品。

作者:十四君

封面:Larva Labs

CryptoPunk 加密朋克不僅是一個頂級藍籌 NFT 項目(地板價為 70ETH 約 15W 刀),更是後續 ERC721 標準協議的靈感來源。

NFT 交易市場,是目前整個區塊鏈行業中除了以太坊本身之外最高收入的賽道,而 OpenSea,x2y2,LooksRare 是目前 Top3 平台,其合計交易量佔 99% 以上。

今天咱們將解讀 CryptoPunk 的區區 230 行源碼,其對訂單模型與交易流程的實現,探索其內置的專用 NFT 交易市場的優勢缺點,也為後續逐步源碼分析 3 大 NFT 交易市場合約模型做基礎鋪墊。

想知道大蛋糕未來鹿死誰手,不妨和我一起源碼入手吧。

CryptoPunk 內置的交易市場

如果細心的同學可以發現,在 OpenSea 上如果想購買 Punk 在其屬性頁面會發現,對其所用標準的描述並非 ERC721 或者 1155,而是絕無僅有的 cryptoPunks,他作為 2017 年推出堪稱史上最早的 NFT 協議(成為後續以太坊基金會推出的 721 標準的靈感來源),不僅實現瞭如今 721 標準的多數功能甚至還在其中內置了一個完全去中心化的交易服務市場,實現 3 種交易拍賣模式!

圖片
<OpenSea 上 Punk 首頁>

拓展閱讀:【源碼解讀】你買的 NFT 到底是什麼?

其實對於 NFT 最底層而言,交易流動是個最最基礎的功能了,無非是要求雙方都使用 tansfer,賣方給買方 NFT,買方給賣方 ETH,一手交錢一手交貨,但是當面交易尚且擔憂對方不給錢呢。因此原子性,是達成信任的必備因素,鏈上成交基於不可更改的特性正是最佳解決方案

1、Punk 優美的訂單模型

回想一下,咱們在現實中是如何買賣商品的,大概有三類

  1. 賣家報價,買家支付→等於超市選購
  2. 買家報價,賣家同意→等於菜市口砍價
  3. 線下議價,鏈上成交→等於線下公證拍賣

無論哪種,最終達成成交則需要執行交換,既要防止賣家不給貨,也要防止買家不給錢。

區塊鏈技術雖然完美的解決了萬一不給錢的問題,但是也帶來了議價困難的痛點,畢竟 “砍一刀價格” 都是要上鍊的,肯定不能用拼多多那樣的砍小數點後 6 位(- 。-)

Punk 的 market 同時支持這 3 大類交易形式,既可以賣家報價,也可以買家報價,也可以議價後由合約幫你成交,全程無任何版稅扣取,且 230 行簡短的代碼也杜絕了後門的可能

他的訂單結構非常簡單分兩種:賣家報價單 Offer 和買家投標單 Bid

1.1、賣家報價單 Offer

與標準 NFT 一樣,每個 Punk 都有一個唯一 ID,因此每個 punk 都有一個獨占的 Offer 訂單簿,這個獨占指的是,如果我重新報價無論是漲價還是降價,都將會替換掉前一個

這里通過 isForSale  標註是否在售,通過 onlySellTo  標註指定買家,則是用於鏈下議價鏈上執行成交功能

struct Offer {
        bool isForSale;  // 此 Punk 是否被卖家设置了报价卖出
        uint punkIndex;  // 此 Punk 的 ID
        address seller;  // 此 Punk 的当前持有者
        uint minValue;          // 卖家设定最小卖价
        address onlySellTo;}    // 是否指定只能由谁购买   

咱們可以顯著感受到,訂單模型非常的簡單,甚至連常見的訂單有效期都沒有,只要掛單賣家不主動取消的話,就總是有可能被買家以此價格購走

特別說明:這點雖然和 opensea 長時間的授權賣單類似,但不會出現異常價成交的情況,因為 Punk 在轉移的時候會取消掉歷史的報價單記錄

1.2、買家投標單 Bid

投標單也非常簡約,基本等於(我,想買,這個,給多少錢)四元組了。

除了賣家標價等待購買的形式,任何人均可以通過提交投標單,來聲明哪個 punk 我願意用 x 的金額購買,這裡同樣提供了 hasBid  變量用於體現當前這個投標單是否有效

買方隨時可以取消之前的投標單,但是如果沒有更高的價格覆蓋的話,則原始的投標價格會保留(雖然已經無效),這是用於輔助其他買家定價出價的信息共享的設計

struct Bid {
        bool hasBid; // 投标是否有效,用于买家不想买取消用
        uint punkIndex; // 指定想投标的 PunkID
        address bidder; // 投标者
        uint value;  } // 投标价

投標時,錢在哪裡??其實已經打到 Punk 合約裡了

買家要提交投標單 Bid  是通過其 Punk 合約的 enterBidForPunk  方法進入的,要傳入 punkID 參數以及當前交易的 Value 值,這就意味著,買家報價的時候,就已經將要購買的資金轉入到 Punk 的合約中

1.3、小結

看懂其核心的訂單簿結構後就是抓住了老鼠尾巴,其實他對應的各種方法,都是在進行對當前交易是否合理合法的審核,確定合法後,再對訂單數據做增刪查改

比如賣家成交後,會執行修改 balanceOf  中記錄的用戶累計持有的 Punk 總量,也會修改最核心 punkIndexToAddress  這個記錄哪個 PunkID 所有者是哪個的信息

對於標準協議的底層數據意義可拓展閱讀

NFT 租賃提案 EIP-5006 步入最後審核!讓海外大型遊戲的鏈改成為可能

總之訂單是為交易模式服務的,而 Punk 內置了 3 種交易方法

2、Punk 支持三種交易模式

2.1、賣家先報價,買家再競標

如果我作為持有 Punk 的尊貴用戶之一,想要賣出 Punk,需 3 步

賣家報價-> 買家提交買單-> 賣家提取收益

展開看看

賣家報價:賣家執行 offerPunkForSale  設置願意以某價格賣掉某 nft,而後訂單簿如下

bool: isForSale true
uint256: punkIndex 3
address: seller 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
uint256: minValue 100
address: onlySellTo 0x0000000000000000000000000000000000000000

買家購買:執行 buyPunk  方法在交易的 value 值傳入超過於賣家的 minValue 即可購買成功。**

賣家需要再次調用 withdraw  提走自己本次收益(即買家 buy 時存入合約的 value)

如果賣家突然不想賣了:則調用 punkNoLongerForSale   來報價單

還有什麼流程能比這更簡單的?

或許只有在買家購買的同時也將收益打入賣家賬戶了吧。而 Punk 系統不這麼設計的原因或許是激勵更高頻的場內交易,等需要外部用再提取走吧

2.2、買家先競標,賣家先確認

如果我並未持有 Punk 但對某個 ID 情有獨鍾,也能先出價分 3 步:

買家報競標單 Bid-> 賣家接受-> 賣家提取收益

展開看看

買家報價:調用 enterBidForPunk,並將 eth 作為 value,此時錢存於 punk 合約內

賣家接受:調用 acceptBidForPunk,要明確按買家報價的價格接受此交易,執行后買方已經得到了此朋克 NFTID

賣方提取收益:需要再次執行 withdraw  提走所有可提額度

如果買家不想買了:則調用 withdrawBidForPunk  取消競標單,同時提走預存金額

2.3、鏈下議價鏈上執行

最後一種更簡單了,就是完全已經談妥了價格,由賣家通過

offerPunkForSaleToAddress  對訂單簿不僅設置價格,還設置一個唯一買家地址 onlySellTo,只有此地址可以來完成這個訂單

這樣一來雖然鏈上依舊是 3 次交易(賣家報,買家買,賣家提取收益)但是可以實現低價交易的應用場景,例如定向質押,防止被人監聽截胡低價單用

如何評價 Punk 的交易市場?

乍一看,是一個很標準的最小 NFT 交易模型,確實可以準確穩定可靠的實現交易的核心環節,但有得有失,他優勢如何,而又少了什麼呢

3.1、GAS 成本低

由於鏈上只存儲了 offer  和 Bid  兩種簡約的訂單簿,且只保留最新最高價的部分(對存儲的新增需要高 gas,但對修改則 gas 低)詳情可見下文文末對以太坊黃皮書中定義 gas 計算的解析:【源碼解讀】你買的 NFT 到底是什麼?

所以 Punk 市場的整體 gas 消耗並不高,筆者核算了下完成買賣提取全環節,大致消耗為 30W 的 gas(含買賣雙方合計支出)

按成交 GAS 排序: Punk < opensea < GEM < Genie < X2Y2 < Looksrare

3.2、無需手續費

目前鏈上可見 Punk 累計有 21W 交易,如果 5 筆交易可成交一單的話,則以及有 4W 次轉移,對於這樣數十億市值的頂級藍籌而言,不收版稅簡直是暴遣天物啊

當然,拿這樣內置交易服務對比專職交易市場來比著實有些不公平,但也正是因為 punk 這樣內置完成交易的功能是遠遠到不了完善的功能體系的,所以才有了各種廣泛市場的可乘之機

而按手續費排序:Punk(0%) < X2Y2(0.5%) < Looksrare(2%) < OS(2.5%)

3.3、對機制的缺點評價

結論 1:買賣機制不利於流動性池

NFT 而言流動性是至關重要的,而每次報價都要上鍊顯然是盆冷水,賣家不缺錢則不樂意動,買家難成交也缺乏動機,所以對報價者即收費且要求鎖定資產到 Punk 此舉雖然不會出現扣款失敗的情況,但是也導致買家資產的時間的價值的損失

這點,後來 Os 等平台均採用簽名的方式,來鏈下撮合購買意願,報價近乎無需 gas 僅成單的時候需要鏈上登記訂單結果來執行轉移

這一擊是中心化與去中心化在效率上的爭奪,顯然現在的市場還是需要效率

結論 2:訂單模型不利於批量操作

Punk 訂單模型的簡約堪稱是交易模型的典範,然而面對批量成交的訴求呢?

  • 賣家:得每個 id 每個報單,確定成交
  • 買家:得每個 id 每個競價,等待成交

雖然收益的資金有可以累計後批量提取的設計,但不是重點

而批量報價成交,是現在 NFT 市場的必爭之地

x2y2 和 Looksrare 都在這點發力作為針對 os 的包圍戰,甚至拉上 Gem 等聚合器打通流量池的局限性,而 os 最新的 SeaPort 協議也實現了捆綁交易的新訂單模型,從而可以任意資產組合對應任意資產組合直接實現市場交易

然而 Punk 的源碼太過於超前,缺乏了代扣授權的功能,再也無緣批量成交

結論 3:單一拍賣流程不利於撮合成交與定價

成交是需要妥協的,而 NFT 當前的價值也需要通過成交來博弈,如何為 NFT 定價一直都是巨大的難題

由此常見有四大拍賣機制:

  1. 英式拍賣。公開競標往上拾價,最高出價者得
  2. 荷式拍賣。價格由高往低降,首個出價者得
  3. 第一價格拍賣。對拍品進行單獨密封報價競品,不知道其他競買人的出價
  4. 第二價格拍賣。與上類似,不同的是最後出價最高者獲勝,但只需按第二高價格支付

而這些拍賣機制(英拍荷拍)是 Opensea 的基礎功能,利於促進成交與定價

英拍:限定時間競拍,即不佔用高價值藍籌的資金成本,也有時間緩衝來擬合各群體的博弈結果

荷拍:更有效的減少過高報價流動性低而無成交的問題,讓價值總要依據市場而變化

圖片

最終

雖然我吐槽了一堆,但是如此精簡優美的 NFT 協議+NFT 交易市場,僅僅使用 230 行代碼就在 2017 年實現,並且演變為目前世界上最有價值的藍籌 NFT 之一,是值得研究的產品

未來未必只有交易市場一頭獨大,更多垂類會在自己 NFT 內也內置交易功能如 StepN、Axie Infinity、NBA Top Shot,而在 Seaport 開源開放後內置市場就未必是功能濃縮版的代言詞了

後續筆者將繼續研究 OpenSea,X2Y2,Looksrare,Gem 等頭部 NFT 市場平台,從合約出發,看其優勢與局限性,有興趣的看官,速速點贊關注,後續跟進吧~

免責聲明:作為區塊鏈信息平台,本站所發布文章僅代表作者及嘉賓個人觀點,與 Web3Caff 立場無關。本文內容僅用於信息分享,均不構成任何投資建議及要約,並請您遵守所在國家或地區的相關法律法規。