作者:霧月,極客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 biggest design 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已經承擔了“生命不可承受之重”,他的宣傳口號與其實踐效果相差甚遠。