作者:Vitalik Buterin. 编译:Cointime:QDD.
特别感谢丹·芬利(Dan Finlay)、卡尔·弗洛尔什(Karl Floersch)、大卫·霍夫曼(David Hoffman)以及 Scroll 和 SoulWallet 团队的反馈、审查和建议。
随着以太坊从一个年轻的实验性技术发展为一个成熟的技术堆栈,能够为普通用户提供开放、全球和无许可体验,它需要同时经历三个主要的技术过渡阶段:
第一是二层扩容过渡 – 所有人都转向滚动计算(rollups);
第二是钱包安全过渡 – 所有人都转向智能合约钱包;
第三是隐私过渡 – 确保可用的保护隐私的资金转移,并确保正在开发的其他设备(社交恢复、身份、声誉)也是保护隐私的。
这三个过渡阶段之所以至关重要,原因如下。如果没有第一阶段,以太坊将会失败,因为每笔交易的成本为3.75美元(如果再次出现牛市,则为82.48美元),而每个旨在面向大众市场的产品都不可避免地会忽视区块链,并采用中心化的解决方案。
如果没有第二阶段,以太坊将会失败,因为用户对于存储资金(以及非金融资产)感到不安,而且所有人都会转向中心化交易所。
如果没有第三阶段,以太坊将会失败,因为对于许多用户来说,所有的交易(以及POAP等)都公开可见,这在隐私方面是牺牲得太大了,所以所有人都会转向至少在一定程度上隐藏数据的中心化解决方案。
这三个过渡阶段之所以具有挑战性,是因为需要进行密切的协调才能妥善解决它们。这不仅仅涉及协议功能的改进;在某些情况下,我们与以太坊的互动方式需要进行相当根本性的改变,这需要应用程序和钱包进行深度改变。
这三个过渡阶段将从根本上重塑用户和地址之间的关系。
在二层扩容的世界中,用户将存在于许多二层上。你是 ExampleDAO 的成员,它存在于 Optimism 上吗?那你在 Optimism 上有一个账户!你在 ZkSync 上持有稳定币系统中的 CDP 吗?那你在 ZkSync 上有一个账户!你曾经尝试过某个运行在 Kakarot 上的应用程序吗?那你在 Kakarot 上有一个账户!用户仅拥有一个地址的日子将一去不复返。
智能合约钱包增加了更多复杂性,因为在 L1 和各个 L2 之间拥有相同地址变得更加困难。如今,大多数用户使用的是外部拥有账户(EOA),其地址实际上是用于验证签名的公钥的哈希 – 因此在 L1 和 L2 之间没有任何变化。然而,使用智能合约钱包,保持一个地址变得更加困难。尽管在尝试让地址成为可以在网络之间等效的代码哈希方面做了很多工作,尤其是 CREATE2 和 ERC-2470 单例工厂,但要完美实现这一点很困难。某些 L2(例如“第四类型的 ZK-EVMs”)并不完全等效于 EVM,通常使用 Solidity 或中间级汇编语言,从而阻止了哈希等效性。即使可以实现哈希等效性,钱包通过密钥更改变更所有权的可能性会产生其他不直观的后果。
隐私要求每个用户拥有更多的地址,甚至可能改变我们处理哪些类型地址的方式。如果隐形地址方案被广泛使用,那么用户可能每笔交易都有一个地址,而不是只有几个地址或一个地址每个 L2。其他隐私方案,甚至是现有的方案,如 Tornado Cash,以不同的方式改变了资产的存储方式:许多用户的资金存储在同一个智能合约中(因此在同一个地址上)。要将资金发送给特定用户,用户将需要依赖隐私方案自己的内部寻址系统。
正如我们所看到的,这三个过渡阶段以不同的方式削弱了“一个用户等于一个地址”的心理模型,其中一些效应反过来又增加了执行过渡的复杂性。两个特定的复杂点是:
1. 如果你想支付给某人,你将如何获取支付信息?
2. 如果用户的资产存储在不同的链上的不同位置,他们如何进行密钥更改和社交恢复?
三个过渡阶段和链上支付(和身份)
我在 Scroll 上拥有货币,并且我想为咖啡付款(如果“I”是指我作为本文的作者,那么“咖啡”当然是“绿茶”的借代)。你正在卖给我咖啡,但你只能接收 Taiko 上的货币。怎么办?
基本上有两种解决方案:
1. 收款钱包(可以是商家,也可以是普通个人)努力支持每个 L2,并具有一些用于异步合并资金的自动化功能。
2. 收款方提供他们的 L2 地址,发送方的钱包会通过一些跨 L2 的桥接系统自动将资金路由到目标 L2。
当然,这些解决方案可以结合使用:收款方提供他们愿意接受的 L2 列表,发送方的钱包确定支付方式,这可能涉及直接发送(如果幸运的话)或者通过跨 L2 桥接路径。
但这只是一个关键挑战的例子,这三个过渡阶段引入了更多的信息需求,而不仅仅是一个20字节的地址。
幸运的是,智能合约钱包的过渡对于寻址系统来说并不是一个大负担,但在应用程序堆栈的其他部分仍然存在一些技术问题需要解决。钱包需要更新以确保它们在交易中不仅发送21000单位的Gas,并且确保钱包的接收方不仅跟踪来自外部拥有账户(EOA)的 ETH 转账,还跟踪由智能合约代码发送的 ETH。依赖地址所有权不可变的应用程序(例如禁止智能合约以执行版税的NFT)将不得不寻找其他实现目标的方式。智能合约钱包还将使某些事情变得更容易 – 特别是,如果某人只收到非 ETH ERC20 代币,他们将能够使用 ERC-4337 付款方来支付Gas费用。
然而,隐私问题再次带来了一些我们尚未真正解决的重大挑战。最初的 Tornado Cash 并没有引入任何这些问题,因为它不支持内部转账:用户只能将资金存入系统并从中提取。然而,一旦可以进行内部转账,用户将需要使用隐私系统的内部寻址方案。实际上,用户的“支付信息”将需要包含以下内容:(i)某种“消费公钥”,即接收者可以用来支出的秘密承诺,以及(ii)发送者可以发送加密信息,只有接收者才能解密,以帮助接收者发现付款。
隐形地址协议依赖于元地址的概念,其工作方式如下:元地址的一部分是发送方的消费密钥的盲化版本,另一部分是发送方的加密密钥(尽管最小的实现可以将这两个密钥设置为相同)。
这里的一个关键教训是,在一个注重隐私的生态系统中,用户将同时拥有消费公钥和加密公钥,用户的“支付信息”将不得不包括这两个密钥。除了支付之外,还有其他很好的原因来扩展这个方向。例如,如果我们想要基于以太坊的加密电子邮件,用户将需要公开提供某种加密密钥。在“EOA 世界”中,我们可以重复使用账户密钥来实现这一点,但在安全的智能合约钱包世界中,我们可能应该对此有更明确的功能。这也有助于使基于以太坊的身份与非以太坊的分布式隐私生态系统更兼容,尤其是 PGP 密钥。
三个过渡阶段和密钥恢复
在每个用户有多个地址的世界中,实现密钥更改和社交恢复的默认方式是让用户单独在每个地址上运行恢复过程。这可以通过单击完成:钱包可以包含用于同时在用户的所有地址上执行恢复过程的软件。然而,即使使用了这种用户体验的简化,朴素的多地址恢复仍然存在三个问题:
1. Gas费用不切实际:这个问题不言而喻。
2. 假设地址:尚未发布智能合约的地址(实际上意味着您尚未从中发送资金的账户)。作为用户,你可能拥有潜在的无限数量的假设地址:每个 L2 上都有一个或多个地址,包括尚不存在的 L2,并且来自隐形地址方案的无限集合中还有一整套假设地址。
3. 隐私:如果一个用户有意拥有多个地址以避免将它们彼此关联,那么他们肯定不希望通过在同一时间恢复它们来公开关联所有地址!
解决这些问题很困难。幸运的是,有一个相当优雅的解决方案,表现相当不错:一种将验证逻辑和资产持有分离的体系结构。
每个用户都拥有一个密钥库合约,该合约存在于一个位置(可以是主网或特定的 L2)。然后,用户在不同的 L2 上拥有地址,其中每个地址的验证逻辑是指向密钥库合约的指针。从这些地址中花费资金将需要提供一个证明,证明当前(或更现实地说,非常近期的)消费公钥。
证明可以通过以下几种方式实现:
1. 在 L2 内部直接读取只读 L1。可以修改 L2,使其能够直接读取 L1 状态。如果密钥库合约在 L1 上,这意味着 L2 内的合约可以免费访问密钥库。
2. 默克尔分支。默克尔分支可以证明 L1 状态给 L2,或者 L2 状态给 L1,或者可以将两者结合起来证明一个 L2 的部分状态给另一个 L2。默克尔证明的主要弱点是由于证明长度导致的高Gas费用:一个证明可能需要5 kB,尽管由于 Verkle 树的原因,这将在未来减少到 <1 kB。
3. ZK-SNARKs。您可以通过使用 Merkle 分支的 ZK-SNARK 减少数据成本,而不是使用分支本身。可以建立离线聚合技术(例如基于 EIP-4337)来让一个 ZK-SNARK 验证块中所有跨链状态证明。
4. KZG 承诺。无论是 L2 还是基于 L2 的方案,都可以引入顺序寻址系统,允许证明这个系统内部的状态只有 48 字节长。与 ZK-SNARKs 一样,多证明方案可以将所有这些证明合并为每个块的单个证明。
如果我们想避免每笔交易生成一个证明,我们可以实现一种更轻的方案,只需要进行跨 L2 的恢复证明。从账户中支出资金将取决于一个消费密钥,该消费密钥的相应公钥存储在该账户中,但恢复将需要一笔交易,该交易将当前消费公钥复制到密钥库中。即使您的旧密钥不安全,储存在假设地址中的资金也是安全的:将假设地址“激活”以将其转换为可工作的合约将需要进行跨 L2 证明,以复制当前的消费公钥。Safe 论坛上的这个thread描述了类似架构的工作原理。
要为这样的方案添加隐私,我们只需对指针进行加密,然后在 ZK-SNARKs 中进行所有的证明:
更进一步(例如,以此作为起点),我们可以简化大部分 ZK-SNARK 的复杂性,实现一个更简化的基于 KZG 的方案。
这些方案可能会变得复杂。好的一面是它们之间存在许多潜在的协同效应。例如,“密钥库合约”的概念也可以解决前面提到的“地址”挑战:如果我们希望用户拥有持久的地址,而不是每次用户更新密钥时都更改地址,我们可以将隐形元地址、加密密钥和其他信息放入密钥库合约,并使用密钥库合约的地址作为用户的“地址”。
许多次要的基础设施需要更新
使用 ENS 是昂贵的。目前,在2023年6月,情况还不算太糟糕:交易费用是相当可观的,但与 ENS 域名费用相比还是可以接受的。注册 zuzalu.eth 对我来说大约花费了27美元,其中11美元是交易费用。但是,如果我们再次经历牛市,费用将会飙升。即使没有以太币价格的增长,Gas费用回到200 gwei将使域名注册的交易费用达到104美元。因此,如果我们希望人们真正使用 ENS,特别是对于像去中心化社交媒体这样的用例,用户要求几乎免费注册(而 ENS 域名费用不是问题,因为这些平台为用户提供子域名),我们需要在 L2 上使用 ENS。
幸运的是,ENS 团队已经加大了努力,ENS 在 L2 上正在实际进行中!ERC-3668(即“CCIP 标准”),以及 ENSIP-10,提供了一种在任何 L2 上自动验证 ENS 子域名的方法。CCIP 标准要求设置一个智能合约,描述在 L2 上验证数据证明的方法,一个域名(例如,Optinames 使用 ecc.eth)可以置于这样一个合约的控制之下。一旦 CCIP 合约在 L1 上控制了 ecc.eth,访问一些子域名.ecc.eth 将自动涉及查找和验证在实际存储该特定子域的 L2 中的状态的证明(例如,默克尔分支)。
实际获取证明涉及访问存储在合约中的 URL 列表,尽管我承认这感觉像是集中化,但我认为实际上并非如此:这是一种 1-N 的信任模型(无效证明会被 CCIP 合约回调函数中的验证逻辑捕获,只要其中一个 URL 返回有效证明,就可以了)。URL 列表可能包含数十个。
ENS CCIP 的努力是一个成功的案例,应该被视为我们实现需要的根本改革是可能的迹象。但还需要进行许多应用层改革。以下是几个例子:
1. 许多 DApp 依赖用户提供链下签名。对于外部所有账户(EOA),这很容易。ERC-1271 提供了一种标准化的方法,可以为智能合约钱包执行此操作。然而,很多 DApp 仍不支持 ERC-1271,它们需要支持。
2. 使用“这是一个 EOA 吗?”来区分用户和合约的 DApp(例如,用于阻止转账或执行版税)将会出现问题。一般来说,我建议不要尝试在这里找到纯技术解决方案;确定特定的密码控制转移是否转移了受益所有权是一个困难的问题,可能无法在不诉诸某些链下社区驱动的机制的情况下解决。最可能的情况是,应用将更少地依赖于防止转移,而更多地依赖于像 Harberger 税这样的技术。
3. 钱包与消费和加密密钥的交互将需要改进。目前,钱包通常使用确定性签名生成应用程序特定密钥:使用 EOA 的私钥对标准 nonce(例如,应用程序名称的哈希)进行签名,生成一个不能在没有私钥的情况下生成的确定性值,因此从纯技术上讲,是安全的。然而,这些技术对钱包来说是“不透明”的,阻止了钱包实施用户界面级别的安全检查。在更成熟的生态系统中,签名、加密和相关功能将更明确地由钱包处理。
4. 轻客户端(例如 Helios)将需要验证 L2,而不仅仅是 L1。目前,轻客户端专注于检查 L1 标头的有效性(使用轻客户端同步协议),并验证根据 L1 标头的 L1 状态和交易的默克尔分支。明天,他们还需要验证一个以 L1 中存储的状态根为根的 L2 状态的证明(更高级的版本实际上会查看 L2 的预确认)。
钱包需要同时保护资产和数据
如今,钱包的任务是保护资产。一切都存储在链上,钱包需要保护的只是当前保护这些资产的私钥。如果您更改密钥,您可以安全地在互联网上发布您以前的私钥。然而,在 ZK 世界中,情况就不再如此:钱包不仅需要保护身份验证凭据,还需要保护您的数据。
我们在 Zuzalu 上看到了这种世界的初步迹象,Zupass 是基于 ZK-SNARK 的身份系统,用于 Zuzalu。用户拥有一个私钥,用于身份验证,可以用来生成基本证明,例如“证明我是 Zuzalu 的居民,而不透露是哪一个”。但是 Zupass 系统还开始在上面构建其他应用程序,最重要的是邮票(Zupass 版本的 POAP)。
邮票相对于 POAP 的关键功能是私密性:您在本地保存数据,只有当您希望将某个邮票(或者对邮票的某个计算)的 ZK 证明发送给某人时,才会进行证明。但这带来了风险:如果您丢失该信息,您将失去您的邮票。
当然,处理数据可以减少为持有单个加密密钥的问题:某些第三方(甚至链)可以持有对数据的加密副本。这具有方便之处,即您采取的操作不会改变加密密钥,并且不需要与保护您的加密密钥的系统进行任何交互。但即使如此,如果您丢失了加密密钥,您将失去所有内容。而且,反过来,如果有人看到了您的加密密钥,他们将看到所有使用该密钥加密的内容。
Zupass 的实际解决方案是鼓励人们将密钥存储在多个设备上(例如,笔记本电脑和手机),因为同时失去所有设备的机会几乎为零。我们可以更进一步,使用秘密共享将密钥分割为多个守护者之间。
这种通过 MPC 进行的社交恢复不是钱包的足够解决方案,因为它意味着不仅当前守护者,而且以前的守护者都可以勾结窃取您的资产,这是一个无法接受的高风险。但是,隐私泄漏通常比完全丧失资产的风险更低,而且对于隐私需求较高的用例,某人始终可以通过不备份与这些隐私需求相关的密钥来接受更高的丧失风险。
为了避免向用户提供一个拜占庭式的多重恢复路径的问题,支持社交恢复的钱包很可能需要同时管理资产的恢复和加密密钥的恢复。
回到身份认证
这些变化的一个共同点是,“地址”这个概念,即在链上代表“您”的加密标识符,将发生根本性的改变。表示“如何与我互动”的指令将不再仅仅是一个 ETH 地址;在某种形式上,它们将成为多个 L2 上的多个地址、隐形元地址、加密密钥和其他数据的组合。
一种方法是将 ENS 作为您的身份:您的 ENS 记录可以包含您的所有这些信息,如果您发送给某人 bob.eth(或 bob.ecc.eth,或…),他们可以查询并查看关于如何支付和与您互动的所有信息,包括跨域和隐私保护的更复杂方式。
但是,这种以 ENS 为中心的方法有两个弱点:
1. 它将太多的事情绑定到您的名称上。您的名称不是您,您的名称只是您的众多属性之一。应该可以更改您的名称而不需要迁移整个身份配置文件并更新许多应用程序中的记录。
2. 您无法拥有可信的对偶名称。任何区块链的一个关键 UX 功能是能够向尚未与链交互的人发送硬币。如果没有这样的功能,就会出现进退两难的情况:与链的交互需要支付交易费用,而支付交易费用需要…已经拥有硬币。ETH 地址,包括使用 CREATE2 的智能合约地址,具备此功能。ENS 名称没有此功能,因为如果两个人都在链下决定他们都是 bob.ecc.eth,就无法选择哪个人获得该名称。
一种可能的解决方案是将更多的事物放入先前在架构部分提到的密钥库合约中。密钥库合约可以包含有关您以及与您互动的各种信息(而且通过 CCIP,其中一些信息可以在链下),用户将使用其密钥库合约作为其主要标识符。但实际接收到的资产将存储在各种不同的地方。密钥库合约不与名称相关联,并且对可行性的选择是友好的:您可以生成一个地址,该地址只能由具有某些固定初始参数的密钥库合约初始化。
另一类解决方案涉及完全放弃用户可见的地址概念,类似于比特币支付协议。一个想法是更加依赖于发件人和收件人之间的直接通信渠道;例如,发件人可以发送一个要求链接(作为显式 URL 或二维码),接收者可以使用该链接以他们希望的方式接受付款。
无论是发件人还是收件人先行动,更多地依赖于钱包实时生成最新的支付信息,以减少摩擦。但是,假设发件人和收件人之间进行直接通信是一个非常棘手的问题,在实践中很难实现,因此可能会看到不同技术的组合。
在所有这些设计中,保持分散和对用户可理解性是至关重要的。我们需要确保用户可以轻松获取关于其当前资产和针对他们的消息的最新视图。这些视图应该依赖于开放的工具,而不是专有的解决方案。在使支付基础设施更复杂时,我们需要努力避免变成一个不透明的“抽象之塔”,使开发人员难以理解正在发生的事情,并将其适应新的环境。尽管面临挑战,但实现对常规用户的可扩展性、钱包安全性和隐私性至关重要。这不仅仅是技术可行性的问题,而是实际上对常规用户的可访问性的问题。我们需要努力应对这一挑战。
发现沙发条评论