作者:霧月,極客Web3
導語:目前的以太坊銘文本質還是Ordinals的新瓶裝舊酒,沒有真正意義的新典範。 ETHS仍有安全風險,雖然它的確比Rollup去中心化,但其提款流程還是依賴第三方公證人/管理者,有被盜風險。顯然ETHS當下還是以金融炒作居多,而不是說它能帶來以太坊Layer2帶不來的革新。
近期BTC生態銘文的火熱,帶動了其他鏈的開發者搭建類似的系統。不同鏈上的銘文系統的實現方式和可實現的功能略有不同,但有一些共同點:
- 銘文都利用了轉帳時附加的文字訊息來表達想要完成的操作,如,在訊息內寫入「向XXX轉1個幣」。請注意,這些資訊是純文字的,不會涉及鏈上的智能合約執行等操作。
- 開發者會設計一系列規範和標準,將所有的文字訊息規範化。
- 開發者提供一套Indexer索引器,用於將鏈上所有銘文的文字資訊歸集後,計算銘文系統的內的狀態。 Indexer是個鏈下的開源元件,任何人都可以運作。
BTC銘文Ordinals在BTC上建立了一套發行NFT、代幣的機制,也引出了對BTC L2的大規模思考,在這個意義上我們可以認為Ordinals具有一定的前沿和探索性質。不過,Ordinals在技術和產品體驗上受到了BTC本身架構的限制,同時也因為粉塵污染和資料佔用等原因,遭到了BTC社群OG的非議。
那麼,在以太坊上復刻銘文,是否有意義呢?畢竟以太坊本身俱有複雜的智慧合約,ERC20、NFT也是以太坊上本身就有的內容;這些銘文項目又會對以太坊生態產生怎樣的影響,會出現在BTC上的爭議和風波嗎?
Ethscriptions的技術實現方式
我們先來看看Ethscriptions的實現方式,它是以太坊上著名的銘文項目,主要利用Calldata來運作。
Calldata是以太坊交易中傳輸的原始輸入資料。一般用於傳輸智慧合約互動時所需的參數,但也可以用於向EOA地址發送文字訊息(留言,銘文刻字,轉帳備註等任何用途)。圖中Input Data即calldata。
如果你想使用Ethscriptions在交易中銘刻”Hello world”,則需要建立一條包含以下calldata的交易:
鏈下的Indexer監聽到這筆交易後,就會更新資料庫並通知用戶:一條新的銘文產生了,銘刻的內容是Hello world。銘文裡也可以放更複雜的內容,如代表圖片資訊的base64等。
Ethscriptions目前通過了6個ESIP(Proposals for improvement to the Ethscriptions protocol),類似EIP的提案,來定義不同場景下銘文的使用。但這些只是比較基礎的銘文規範,例如從EOA發起的銘文交易的格式,合約emit事件等等。
Ethscriptions由於是以太坊上的項目,也可以利用以太坊的智慧合約來實現一定程度上的邏輯。需要注意的是,直接與智能合約互動並不是Ethscriptions推薦的方式。
雖然官方的NFT市場等也是直接用智慧合約實現的。根據官方文件的說法,Ethscriptions想要為用戶提供的是「去中心化且價格合理的運算服務」:將運算剝離至鏈下,將顯著降低以太坊的使用成本。
我們來具體探討一下呼叫智能合約的成本,可以分為三個部分:
- 基本交易成本:任何以太坊交易都需要支付,目前為21000 gas。
- 資料傳輸成本(calldata):calldata一般用於提交與智能合約互動的資料和參數。 EIP-2028調整後,calldata資料每個位元組一般消耗16 gas(若是資料為0的位元組消耗4 gas)。
- 合約執行成本:如果交易呼叫了智慧合約中的函數,那麼根據函數執行的複雜度,就需要支付計算成本。例如,如果涉及狀態更新(例如在ERC-20合約中更新餘額資訊),呼叫SSTORE會消耗高達5000~20000 gas。
我們以一個非常簡單的USDT轉帳的交易為例,該交易總共耗費了63197 gas,calldata為:
我們解析下該calldata,以及它會花費多少gas:
- 以太坊calldata為十六進位格式,也即每兩位為一個位元組(16^2 = 2^8)。開頭的0x代表資料採用16進位。
- 開頭0x後面的a9059cbb是函數選擇子,佔用4個非零位元組。
- 之後的32位元組為位址,前面有12位元組的零(因為以太坊位址是20字節,這裡左補了零到32位元組),以及20位元組的非零位址資料。
- 最後32位元組代表金額,左補了大量的零,末尾有3b9aca00非零數據,4位元組非零。
- 所以,非零字節28個,零字節40 個
因此,calldataGas = 28 * 16 + 40 * 4 = 608 gas。
而總gas為63197,減去calldata成本和固定成本,則執行該交易的智能合約計算成本為41589 gas。在這筆交易裡合約運算成本佔了大頭,而這僅僅是一筆簡單的交易,複雜的交易中合約運算的成本會進一步上升。
將運算過程放至鏈下確實會顯著地降低使用成本:不想在鏈上直接調用智能合約的話,可以向一個約定好的EOA地址
0x00000000000000000000000000000000000face7發送交易數據
在交易的calldata中聲明原本想呼叫哪個合約,以及對應的輸入參數。由於上述地址是一個EOA帳戶,沒有合約程式碼,所以前面所說的操作不會在鏈上觸發計算任務,只是發布了一則訊息而已。
而在鏈下,Indexer監聽到這則訊息後,就會進行解析,弄清楚這則訊息的發起者原本想呼叫ETH鏈上哪個合約,然後Indexer會在鏈下計算出合約呼叫的結果。
那麼線下的Indexer想要進行銘文和智能合約的運算,就必須有一套STF(狀態轉換函數)規則和運行時,複雜點的可以叫虛擬機VM。 Ethscriptions在ESIP-4中推出了自己的VM-Ethscriptions VM,後來改名為Facet VM。
Facet-有點像協處理器
Facet將自身定義為一個便宜好用,安全,去中心化的運算平台。監聽以太坊上Ethscriptions的calldata,拉到VM中運算,最後給使用者返還結果。 Facet包含幾個關鍵的組成部分:
- Facet VM,用ruby寫的一套VM,負責監聽ETHS交易,解析calldata,執行運算。
- Rubidity,Facet中的智慧合約程式語言,與Ruby有一定相似性,又保留了許多solidity的用法和概念,以期開發者能快速上手。
- Dumb Contract,呆笨合約,一種在Facet上運行的合約。這個名字充滿了幽默感。有人稱之為啞合約也是對的,dumb本身是雙關的,啞可以描述這種合約工作的靜默過程。但另一方面根據官方名言”So dumb, they’re smart”,大愚若智,一股濃濃的與smart contract叫板的意味,所以叫呆笨合約也沒問題。
呆笨合約本身不會真正部署在以太坊上,只是其程式碼會以calldata的形式發佈到ETH鏈上。下面是一個Facet對呆笨合約的呼叫案例:
一筆鑄幣交易,向EOA黑洞地址
0x00000000000000000000000000000000000face7提交下圖中的calldata,聲明自己要mint的代幣和數量即可,這其實和Ordinals或BRC-20如出一轍:
我們再來看看Rubidity和Solidity的直覺對比,請看下圖。
雖然官方說Rubidity具有類似Solidity的概念和架構,以便開發者快速上手。但我們知道其實這對開發者側的發展來說是有一定負面影響的。而目前Facet VM僅支援官方白名單中的呆笨合約,這說明官方對這套語言以及VM並沒有很十足的信心。是否重複使用EVM對官方而言,在工程技術上比新開發一個VM和一個新的語言更難,我不得而知。但有一點可以肯定的是:全新的語言、全新的合約、全新的生態、全新的以太坊使用方式,確實有足夠的噱頭。
Facet對智能合約的抨擊
Facet文件中對以太坊和智能合約做出瞭如下的勁爆評論:“Smart Contracts are considered to be the feature above all others that makes Ethereum special, and yet Facet’s thesis is that Smart Contracts are Ethereum’s biggestsign flaw.”
他們認為以太坊的智能合約是最大的設計缺陷,因為合約本身只要給定輸入(calldata),其輸出就是確定的,因此不應該在鏈上進行運算,平白無故浪費錢。再結合Ethscriptions所說的“去中心化且價格合理的運算服務”,顯然Ethscriptions和Facet非常想打造一種市場印象,“我們正在製造全新的以太坊擴容範式和使用方式”,但實際上ETHS自己的一些技術方案不是很可靠。
從產品角度來看,Facet可以在鏈下間接調用智能合約,又有自己的鏈下的呆笨合約體系,確實官方正在實踐其口號。
但從經濟角度講,天下沒有白吃的午餐,儲存和運算當然是要錢的。那請問Indexer該如何解決這部分成本呢?這官方就沒有什麼明確說明了,我們可以想像一下:
- 向用戶收費。例如NFT市場向買家收取的手續費,但我們不能以一個簡易的項目的收費模型看待一個類L2網路的長遠收費方式。
- 靠自身生態炒作關聯致富。這個當然可行,但只是短期的讓專案方一時爽的方案。 Ethscriptions如果想成為一種全新的以太坊範式,Indexer必須有長久的,從網路出發的經濟機制來保障運作。
- 如果是不營利的Public goods,那麼會有哪些機構donate呢?我覺得至少以太坊基金會不會特別積極,因為本身以太幣有非常好的方案——Rollup。
Facet和呆笨合約出現的根本原因
如果我們只是需要以太坊銘文的簡單形式,那麼只需要Ethscriptions一個專案就夠了。那為什麼其ESIP-4提案又催生了Facet呢?
因為銘文體系沒辦法用於複雜的交易邏輯。我們可以檢視下Ethscriptions官方的NFT市場合約的運作邏輯,它使用了掛單機制。
如果要將銘文NFT充值進合約,只需要把calldata寫為銘文的EthscriptionId並呼叫市場合約。由於這種操作故意選擇無效的函數呼叫形式,預設會觸發fallback()。
最後會在以太坊鏈上拋出一個名為PotentialEthscriptionDeposited的事件,Indexer節點在鏈下監聽到這個事件後,便會在本地將NFT的歸屬權劃轉為市場合約。
為了節省gas,ETHS的交易市場沒有把賣家掛單的一些參數,如價格、截止時間等放在ETH合約裡存儲,而是以消息的形式放在了線下,目測應該是存儲在了dApp的服務器上。買家監測這個消息後,就可以發布buyWithSignature()指令提出購買。
對NFT而言使用掛單機制是正常的,因為NFT本身不具有同質性。那麼如果是均質化的代幣銘文,能否使用合約的AMM機制呢?答案是不行的。銘文NFT或代幣的狀態,都不在L1上,就跟Ordinals和BRC-20差不多。這和一些社群的宣傳是截然相反的,大家需要注意甄別,而銘文並不是真正意義的ETH鏈上的資產。我們並不能說產生資產的calldata在L1上,而且可以在L1上聲明操作指令,就叫L1上的原生資產,否則Rollup上的L2原生資產我們也可以稱為L1資產,因為Rollup的calldata都在L1上。顯然,管這種資產叫L1原生資產非常荒謬。
你可能會疑惑,上面不就是利用智能合約進行了買賣嗎?怎麼就說合約不能讀取和操作銘文呢?其實這個合約只負責收錢,轉錢,拋出事件供鏈下的Indexer節點監聽並觸發對應的操作。在以太坊EVM眼中,銘文這類東西的狀態,無法在以太坊專門儲存狀態的資料庫「世界狀態」中還原出來,合約也沒法引用它。
不論資產是什麼形態,代幣也好NFT也好或任何稀奇古怪的東西,我可以給出一個非常簡單的標準鑑別L1資產和L2資產:它的狀態能否在以太坊的「世界狀態」上還原出來,L1的EVM能否引用、呼叫、查詢、修改該資產的狀態,如果不能,那它就不是L1的資產。
所以你也可以看到充值的事件名字叫PotentialEthscriptionDeposit,即“可能的銘文充值”,而不是一個確定性的充值,因為合約沒法判定這個銘文是否存在,無法驗證其真偽。如果你掛單了一個不存在的銘文,或是別人的銘文,合約不會拒絕你,只是Indexer不會收錄你的行為而已。
因此銘文系統只能實現這種簡易的偽合約邏輯,掛單就是其中一種。掛單的本質是交易雙方在一種規則下互相認同對方提供的訊息,其實不用智能合約用純文字也可以表達,這和銘文的道理類似。
我們可以想像一下如何不使用智能合約來完成上述過程:賣家在普通交易中刻一筆訊息,轉給我1ETH並附言123的人可以獲得我編號為123的銘文NFT。這樣只需要Indexer支持這個邏輯,它監聽到了有人轉了1ETH給賣家並附言ABC,就可以直接在鏈下的Indexer資料庫裡劃轉。
當然這個例子其實會帶來一些問題,例如多人搶購一個NFT可能導致的重複交易等,賣家收了多筆轉賬,但最終NFT只能被Indexer劃給一個人。這也應該是官方明明抨擊智能合約,卻使用合約實現NFT市場的原因之一,因此你也應該能明白官方所說的通過Facet不進行計算而調用智能合約是不靠譜的宣傳。
當然,掛單理論上可以使用純文本,而不是非要用合約,但AMM這種相對比較複雜的邏輯就必須用智能合約,因為它需要的不是雙方p2p式的認同,而是合約認同。充當了可靠審查者的合約,需要檢查餘額、流動性等基礎信息,並進行運算,任何他所需的資產數據,合約都必須能夠獲取到。
而AMM只是比較簡單的一種DeFi形式,其他任何複雜的邏輯在僅僅在Ethscriptions上都是無法實現的。這也是為什麼推出了Facet的原因-Facet的第一要務是跨域!它其實就是個L2,只是沒有區塊結構,所以我們不叫跨鏈而叫跨域。當所有的L1資產跨域到Facet後,就不存在跨域無法呼叫的問題,可以在鏈下對所有鏈下資產用呆笨合約進行操作,進而支援複雜的合約邏輯。
和Rollup的對比
透過上面的長篇大論,大家應該可以發現,Ethscriptions的方案有點類似Rollup。但這只是“類似於”,如果嚴格的說的話,它只能實現Rollup核心功能的子集。而殘缺的功能則為其敘事帶來了致命傷,或者說將使用者置於嚴重的威脅之中。
Rollup是一套複雜的體系,這裡我們不展開。它和Ethscriptions有些共同點:
– 都在以太坊上提交L2交易的資料calldata。
– 都將運算放在鏈下處理。
共同點非常清晰,我們需要詳細論證不同點。
Rollup批次提交calldata
Rollup中用戶大部分情況不會直接向L1提交交易,而是提交給鏈下的排序器,排序器會對所有交易排序後打包、壓縮,將calldata批量發送至L1。這樣多個用戶的calldata在一筆交易中提交,可以攤薄21000 gas的基礎成本。
在Ethscriptions中沒有這樣的機制,所有的使用者直接向L1提交calldata。
我們用上面那個USDT的例子(608 gas for calldata),假設有100個用戶發起了100筆交易,非常不嚴謹地粗略計算下二者的成本差異:
- 銘文使用者每人需要支付21608 gas(608 + 21000)。其餘運算部分不支付,因為運算在鏈下。
- Rollup用戶每人支付818 gas ((608*100+21000)/100)。運算部分同上。
當然,Rollup用戶每個人還需要向排序器繳納L2的運算和儲存費用,但相對L1低廉很多,在本例中可以忽略不計。另外,rollup還需要額外的一些特殊欄位增加了體積,但同時又有比較好的資料壓縮,這裡我們也不展開。
透過這個粗略的估算就可以發現,Ethscriptions比較Layer2,在成本上沒任何優勢。另外,該專案的社區宣傳話術中我看到過類似「4000個銘文可以批量轉賬,大概需要0.11ETH,平均每筆轉賬只需要0.05U」以此來證明Ethscriptions的使用很便宜,這其實都沒有理清ETHS的原理與互動細節。
鏈下預確認
由於具有鏈下的排序器,Rollup的用戶請求可以在1s內預先確認。這一點比銘文系統在L1上的12秒或更久,UX好很多。當然,銘文支持者也可以反駁說,在calldata 提交到ETH鏈上前,這樣的交易結果最終性都是不可靠的。
抗審查性和去中心化
使用者在Rollup有可能被鏈下的排序器審查,而Ethscriptions無法審查使用者。但設計良好的Rollup會有強制歸集功能,以對抗排序器的審查,最終使排序器完全不具備審查使用者的權力。
所以使用者使用Rollup時,也是可以直接在L1上繞過排序器使用的。 Rollup給使用者不同的選擇,可以使用更快的排序器,也可以直接用L1。但Ethscriptions只能使用L1,並沒有給使用者自由選擇的空間。
另外Ethscriptions詬病Rollup的排序器是中心化的。但Indexer本身也是一個高度中心化的組件。 Ethscriptions解釋說Indexer由於任何人都可以運行、驗證,所以不算中心化,但事實上絕大多數人都不會自己運行節點。所以ETHS只是在極端情況下,會體現出它比Rollup去中心化的一面,畢竟Rollup排序器可能宕機或故障,但ETHS只要有社區成員運行多個Indexer,就可以持續運作。
獲利模式
任何專案都不可能用愛發電,長遠發展的專案必須認真考慮獲利模式的問題,不論是中心化實體還是去中心化實體的組合,都必須有盈利才能夠長期地守護網路安全。
Rollup的排序器有明確的獲利模式:多收取gas,榨取MEV等。排序器有動力保證網路的正常運作。 Ethscriptions因為使用者直接向L1提交calldata,Indexer其實不好收費。
開發者友善程度
大多數Rollup的合約開發語言、工具鏈等都直接使用以太坊的即可,開發者可以無縫遷移至Rollup。在Ethscriptions中這些都不存在,需要掌握新的Rubidity,需要建立新的scan,熟悉新的VM等等。當然,這些阻力反過來看也是一個新生態發展時可能帶來的拓荒的機會。
提現和狀態結算
這是Facet的致命問題。我們知道Rollup不只會將calldata(輸入)批次提交到L1上,也會定時將N個運算後的狀態結算(輸出)提交到L1上。 ZKR和OPR有不同的證明方式來決定輸入和輸出的關係是否正確,不論什麼證明方式,最終的裁判都是L1上的合約。在Rollup上輸出和輸入是有跡可循的,無法造假的。
那麼狀態結算有什麼用呢?用於提現,也即L2到L1的資金提領。當L1上的狀態發布後,我們就可以根據狀態根,用Merkle Proof等手段,去證明我在L2上的提現請求包含在了該狀態根裡。合約驗證無誤後就可以在L1上放行資產。
Facet沒有狀態結算機制,所以他無法實現L2到L1的無許可、去中心化的提現。上面提到過,他又需要一個L2層,以執行更複雜的合約邏輯。如他的AMM Swap FacetSwap。
我們可以看到在FacetSwap(Facet上用呆笨合約建構的dex)中明確有充值和提現兩個動作。一般Swap是沒有儲值提現的,因為Facet需要你先跨域才能使用。
在Facet中,儲值需要在L1橋合約上將L1的資金鎖定,並且發射出對應的事件ethscriptions_protocol_CreateEthscription讓Indexer進行索引。這和其他的L2的儲值的手段是一致的。
而提現則有嚴重的安全問題。由於在Facet上沒有任何的狀態結算機制,L2到L1上無法用合約自動判定一筆提現是否有效。那麼Facet使用了什麼方法呢?管理員放行,或叫見證人機制,類似先前被偷的Axie橋。
我們直接來看一眼Facet的橋,地址為
0xD729345aA12c5Af2121D96f87B673987f354496B。
hashedMessage是經過signer簽名的一個訊息,裡面即提現的一些內容。 signer是一個預設的管理員位址。因為沒有狀態結算沒法做任何校驗,例如該帳戶在L2上是否有這麼多幣。所以完全憑signer簽名就可以將合約上的所有資金取走,不論是專案方作惡還是駭客攻擊取得私鑰。
在Rollup中,根本不需要見證人放行資產;在側鏈中,見證人如果想做的去中心化一些,可以從本身的共識體系中選擇出一部分作為代理,用質押等方式進行一定的經濟威懾遏止作惡。
在Ethscriptions和Facet中,nothing。它簡單地、不加掩飾地就是一個管理員地址。這對於一個動輒喊著「智慧合約是設計缺陷」、「Rollup是中心化的」、「我們是新一代計算平台」的類L2項目而言,恐怕過於潦草了。顯然,他的缺陷還有很多,但我們可以對此保持觀望,雖然這些缺陷不太好彌補,並且可能同樣在比特幣Layer2身上存在。
總結
目前的Ethscriptions存在一定的“虛假宣傳”,幾個要點:
- Ethscriptions和Facet上的資產,都不是發行在L1上的資產。
- 為了有複雜的合約能力,演化出了Facet這個L2實體,但有極大的資金安全隱憂。
- 官方宣稱的在L1上去合約運算化,卻連自己的頭牌應用都不用。
- Ethscriptions類似一個基礎功能非常不全的Rollup。既沒有Rollup的便宜和迅速,也沒有Rollup的安全。他能實現的,Rollup都能實現,Rollup能實現的很重要的功能它無法提供。
- 如果想解決上述問題,他需要發展出狀態結算機制,再加上排序器,L2區塊,那麼它最終就變成了Rollup。
Ethscriptions趁著BTC銘文的風口,依靠概念炒作新瓶裝舊酒,但還沒有發掘出新的範式。目前的ETHS還是以金融炒作為主,而不是說這種產品本身能帶來以太坊Layer2沒有的東西。這種東西的長期價值,顯然還有待人們去挖掘,但就以目前的形式來看,ETHS已經承擔了“生命不可承受之重”,他的宣傳口號與其實踐效果相差甚遠。