导语
目前的以太坊铭文本质还是 Ordinals 的新瓶装旧酒,没有真正意义的新范式。ETHS 仍然存在安全风险,虽然它的确比 Rollup 去中心化,但其提款流程还是依赖于第三方公证人/管理者,有被盗风险。显然 ETHS 当下还是以金融炒作居多,而不是说它能带来以太坊 Layer2 带不来的革新。
近期 BTC 生态铭文的火热,带动了其他链的开发者搭建类似的系统。不同链上的铭文系统的实现方式和可实现的功能略有不同,但有一些共同点:
1.铭文都利用了转账时附加的文本信息来表达想要完成的操作,如,在信息内写入「向 XXX 转 1 个币」。注意,这些信息是纯文本的,不会涉及链上的智能合约执行等操作。
2.开发者会设计一系列规范和标准,来将所有的文本信息规范化。
3.开发者提供一套 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 已经承担了「生命不可承受之重」,他的宣传口号与其实践效果相差甚远。