作者:雾月,极客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批量提交calldataRollup中用户大部分情况不会向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已经承担了“生命不可承受之重”,他的宣传口号与其实践效果相差甚远。