理解 EigenLayer - 从重新设计角度

从头设计角度理解 EigenLayer

在这篇博客文章中,我们将带你了解 EigenLayer 协议的演变,介绍 EigenLayer 架构是如何从最初的概念中产生的。

本博客受 David Philipson 的 账户抽象系列 启发。特别感谢社区的 Noam HorowitzShivaNashQMike NeuderSina 对本文的评论和反馈。

虽然很多人熟悉 restaking 和 EigenLayer 这些术语,但只有少数人知道我们的核心合约包含数千行代码 ,其架构如下。

img

EigenLayer 简化架构

一个看似简单的想法为何变得如此复杂?

在这篇博客文章中,我们将通过介绍 EigenLayer 当前复杂架构是如何从最初概念中产生的,来带你了解该协议的演变

本文的目标读者是对智能合约有基本了解并听说过 EigenLayer 或 restaking 的人。

💡由于本博客文章的目的是对 EigenLayer 的设计演变进行高层次解释,因此接口、变量和逻辑可能与当前 EigenLayer 核心合约有所不同。

现在,让我们开始吧。

最终目标:使构建基础设施变得简单

首先,让我们先介绍 EigenLayer 要解决的问题。如果你已经熟悉这部分内容,请跳到后面的章节。

在以太坊上构建去中心化基础设施的开发人员面临着建立自己的经济安全的挑战。虽然以太坊为智能合约协议提供了经济安全,但桥或排序器等基础设施需要自己的经济安全,以实现节点的分布式网络达成共识。

共识机制对于促进这些节点之间的互动至关重要,无论是 L1、预言机网络还是桥。

工作量证明耗能严重, 权威证明过于集中化,因此权益证明 (PoS)已成为大多数基础设施项目的主要共识机制。

然而,启动新的 PoS 网络很困难。

首先,很难确定抵押者(提供抵押的人)在哪里。没有一个好的地方供开发人员找到抵押者。

其次,抵押者必须投入大量资金来获得新网络的抵押,通常是通过购买网络的原生代币,他们通常是波动的且难以获得。

第三,抵押者必须放弃其他的奖励机会,比如以太坊提供的 5% 奖励。

最后,当前的安全模型不理想,因为破坏任何 dApp 的成本只是破坏其最脆弱的基础设施依赖所需的成本。

💡暂时假设参与基础设施项目的抵押者也负责操作离线软件以保证其安全。但我们将在文章后面更改这一假设。

EigenLayer 被创建来解决这些问题:

  • 它作为一个平台连接抵押者和基础设施开发人员。
  • 抵押者可以使用任何代币提供经济安全。
  • 抵押者可以选择 restaking(重新质押) 他们原有抵押并为其他基础设施的安全做出贡献,同时获得原生以太奖励。
  • 通过重新抵押,EigenLayer 将安全性汇集在一起,而不是使其分散(碎片化)。

💡EigenLayer 的白皮书对这些问题进行了深入探讨。

EigenLayer 泛化了提供经济安全的概念。

目标1:创建连接抵押者和基础设施开发人员的平台

EigenLayer 是一个平台,抵押者可以为任何基础设施项目提供抵押,基础设施项目可以在 EigenLayer 上向潜在抵押者推介。该平台的支柱是使抵押者能够为不同的基础设施做出可信承诺。

这些承诺适用于所有权益证明系统,不仅仅是 EigenLayer。L1 抵押者通常承诺遵循协议规则,并冒着如果在同一区块高度签署冲突区块而失去抵押的风险。

基础设施开发人员构建基础设施逻辑和软件,而抵押者提供抵押以保障基础设施。这个 抵押 作为 承诺 提供给基础设施的用户。 这个 承诺 是为了协议的顺利运行,反对特定的不端行为。

从概念上,当一个项目背后有 1 亿美元的抵押时,这意味着如果它偏离了其承诺并表现出恶意行为,这 1 亿美元的一部分将被削减。简单来说,“削减”可以理解为销毁这笔资金。

这个数字越高,就越能为其用户提供更多的安全性和保障。

如果我们允许抵押者为各种承诺分配抵押,我们就可以在其上创建一个用户友好的平台。

我们需要一个无需信任且可编程的平台来执行不同的抵押者承诺,以太坊是最适合的。 此外,以太坊持有最大的抵押,有助于启动抵押者市场。

这里的目标是,抵押者应该能够通过 EigenLayer 在以太坊上为桥协议提供安全性。如果一个抵押者在以太坊上恶意伪造消息并将其传输给 Gnosis,任何人都可以提交证据并削减该抵押者。

由于抵押者的抵押和承诺执行发生在以太坊上,削减逻辑也是以以太坊智能合约的形式实现的。如果抵押者违反了他们的承诺,任何人都可以向削减合约提供证据并没收恶意抵押者的抵押。

这构成了 EigenLayer 的基础 - 任何抵押者都可以为任何基础设施协议做出可信承诺。

EigenLayer 的初始设计

现在,让我们尝试实现这一点。我们将从最简单的设计开始:抵押者将代币抵押到一个合约中,该合约包括一个函数,允许在提交证据并符合标准时削减抵押者的代币。用户随后可以提取他们的余额。

其他抵押者也可以将代币抵押到这个合约中,增加基础设施的安全性。我们将称这个合约为 TokenPool

为了更清晰,这里对本文中使用的术语进行一些定义:

  • 抵押者:任何提供代币到 EigenLayer 的人。
  • 代币:任何类型的代币;暂时简单地将其视为 ERC20 代币。
  • TokenPool:保存抵押者代币的智能合约。
  • 削减:移除抵押者对其抵押代币的访问权限。

img

这个TokenPool的接口可以表示如下:

contract TokenPool {

    mapping(address => uint256) public balance;

    function stake(uint256 amount) public;
    function withdraw() public;
    function slash(address staker, ??? proof) public;
}

这是否满足任何质押者为任何基础设施提供质押的要求?是的!

  1. 质押者可以向特定承诺(在slash函数中定义)进行质押。

  2. 如果发现恶意行为(违反承诺),则会被削减。

  3. Withdraw() 从系统中提取。

  • ✅ (达成)- 作为连接质押者和基础设施开发者的平台

  • (待达成) - 质押者可以使用任何代币提供经济安全性。

  • (待达成) - 质押者可以选择restaking(重新质押)他们之前质押时获取的代币(如 stETH),并为其他基础设施的安全性做出贡献,同时赚取原生 ETH 奖励。

  • (待达成) - 通过restaking,EigenLayer 将安全性汇集在一起,而不是使其分散。

目标2:降低质押者的机会成本

当新的基础设施协议推出时,它们通常会引入一种本地代币。然而,说服质押者持有这种代币仍然具有挑战性。

首先,本地代币的价值可能会出现显着波动,这使得很难说服质押者获取它。

其次,来自其他协议提供更高奖励率的竞争,这使得协议必须提供有力的激励措施来吸引质押者。

EigenLayer 通过允许质押者质押任何代币并同时赚取多重奖励来解决这些挑战。由于 EigenLayer 在以太坊网络上运行,我们可以利用现有的以太坊基础来实现这一点。

一种方法是允许质押者使用流动质押代币(LST)进行质押。通过使用 LST,质押者可以保留他们的原生的ETH 奖励,同时保护其他基础设施,并有可能获得额外的奖励。

💡 如果我不想通过 LST 服务商,而是想作为独立验证者如何进行重新质押,怎么做?我们在最后的奖励部分详细描述了 EigenLayer 如何实现这一点。

  • ✅ (达成)- 作为连接质押者和基础设施开发者的平台。
  • ✅ (达成)- 质押者可以使用任何代币提供经济安全性。
  • ✅ (达成)- 质押者可以选择restaking(重新质押)他们之前质押时获取的代币(如 stETH),并为其他基础设施的安全性做出贡献,同时赚取原生 ETH 奖励。
  • (待达成) - 通过 restaking,EigenLayer 将安全性汇集在一起,而不是使其分散。

目标:通过 restaking 汇集安全性

EigenLayer 的最终目标是解决碎片化安全性的问题。

目前,如果一个应用的安全性依赖于多个基础设施依赖项,那么单个经济上受损的依赖项就可能威胁整个应用的安全性。

当这些依赖项的经济安全性被孤立时,这个问题会变得更糟。这些孤立的点形成了经济上的“蜜罐”,吸引潜在的攻击。

因此,与其为不同的基础设施维护几个单独的经济安全性池,将这些安全措施汇集起来将是有益的。这样做可以逐步提高所有依赖项的经济安全性。

💡在 EigenLayer 上下文中,这些基础设施服务被称为主动验证服务(AVS)。 现在区分它们很重要,因为 AVS 从 EigenLayer 提供的好处上根本不同于传统基础设施项目。

实现汇集安全性

根据我们目前的模型,我们如何将汇集安全性纳入其中?

目前,每个TokenPool都有其自己独特的削减条件嵌入在合约中。这意味着对于每个 AVS,都需要编写一个单独的TokenPool合约。如果质押者希望同时参与两个 AVS,他们将需要一个新的TokenPool。这个新池必须整合来自两个 AVS 的slash函数。

如果两个削减条件可以同时削减一个质押者,那么质押者就同时做出了两个可信的承诺。

高效的方法是允许质押者参与不同的 AVS,而无需创建新的TokenPool合约或修改slash函数。

这可以通过将slash函数转移到不同的合约中实现,称为“削减者”。以下是它们的交互方式:

img

EigenLayer 中间设计: 将削减与代币池分离后

TokenPool的新接口将如下所示。(slash不再存在。)

contract TokenPool {
    mapping(address => uint256) public balance;
    mapping(address => address[]) public slasher;

    function stake(uint256 amount) public;
    function withdraw() public;
    function enroll(address slasher) onlyOwner;
}

除了stakewithdrawbalance函数和变量外,我们还引入了一个新函数和一个新变量。变量slasher监视每个质押者当前注册的 AVS。函数enroll允许质押者参与 AVS

因此,注册到 AVS 实际上是赋予“削减者”削减你的质押的能力。

通过这种修改,在向TokenPool质押后,质押者可以通过调用enroll函数加入特定的 AVS。该函数包含 特定 AVS 的削减者合约到slasher映射中。

💡这里的 enroll 函数是受访问控制的,因为它可能使任何人都能够注册到任何削减者合约。为了确保这个 TokenPool 被安全管理,我们将假设它由一个受信任的第三方监督。

在提取过程中,TokenPool合约可以要求每个slasher确定质押者是否有资格提取。这通过slasher合约中的isSlashed函数进行验证。如果对于这个质押者,isSlashedTRUE,则质押者无法提取他们的质押,因为他们已经被削减。

contract slasher {
    mapping(address => bool) public isSlashed;

    function slash(address staker, ??? proof) public;
}

slash函数包含每个 AVS 的削减逻辑。虽然削减逻辑可能在各种 AVS 之间有所不同,但在成功执行slash函数后,该函数将为被质疑的质押者将isSlashed变量设置为 true。

✅ (达成)- 作为连接质押者和基础设施开发者的平台。 ✅ (达成)- 质押者可以使用任何代币提供经济安全性。 ✅ (达成)- 质押者可以选择重新质押他们的质押,并为其他基础设施的安全性做出贡献,同时赚取原生 ETH 奖励。 ✅ (达成)- 通过重新质押,EigenLayer 将安全性汇集在一起,而不是使其分散。

通过实施汇集安全性,我们已经创建了最小可行的 EigenLayer! 最小可行版本充当了连接质押者和 AVS 开发者的平台。质押者现在可以质押任何代币,而不会损害其他奖励,而 AVS 开发者可以利用共享的安全池来保护各种类型的新基础设施应用程序。

在接下来的部分,我们将改进最小可行版本,以适应额外的用例,并使 EigenLayer 具有未来的可扩展性。

目标:质押者不必运营

在最小可行设计中,质押者可以为各种 AVS 质押代币。然而,一些质押者可能没有能力或愿望亲自处理确保 AVS 运行安全性的运营。这类似于ETH持有者可能更喜欢操作自己的验证者

我们的目标是区分这两种角色。质押者为每个 AVS 的经济安全性提供代币,而运营者是运行软件以确保每个 AVS 运行安全性的个人。

我们可以对TokenPool合约进行轻微调整,以包括委托流程。这允许质押者的代币余额委托给代表他们的运营者。但是,如果运营者违反 AVS 承诺,质押者的代币将被削减。

contract TokenPool {
    mapping(address => uint256) public stakerBalance;
    mapping(address => uint256) public operatorBalance;
    mapping(address => address) public delegation;
    mapping(address => address[]) public slasher;

    function stake(uint256 amount) public;
    function withdraw() public;
    function delegateTo(address operator) public;
    function enroll(address slasher) operatorOnly;
    function exit(address slasher) operatorOnly;
}

我们已将余额变量分为两个不同的部分:一个用于运营者,一个用于质押者。此外,我们引入了一个delegation映射,用于记录质押者和运营者之间的委托关系。

我们还对slasher映射进行了微小修改。现在,它授予了slasher合约削减运营者的权限,而不是质押者。

contract slasher {
    mapping(address => bool) public isSlashed;

    function slash(address operator, ??? proof) public;
}

在功能方面,我们已经整合了delegateTo,使质押者能够将他们的代币委托给运营者。enroll函数已被重新设计为特定于运营者,允许运营者加入不同的 AVS,而不是质押者。

withdraw过程中,合约首先确定被委托的运营者。然后检查与该运营者地址相关联的每个slasher合约。如果任何一个slasher报告该运营者已被削减,则提款过程立即停止。

保持质押者自治

如果运营者是唯一可以选择加入 AVS 的人,那么质押者如何决定他们想要保护的 AVS 呢?当一个质押者也是运营者并自我委托他们的质押时,他们对他们经营的 AVS 拥有完全控制权。但是如果一个质押者无法独自运行它,并需要另一个运营者来管理这些服务怎么办?这难道不是让运营者完全控制 AVS 选择吗?

我们可以通过一个简单的变通方法允许质押者选择 AVS。运营者可以为不同的 AVS 组合保留不同的地址。每个地址代表一个潜在的组合由运营者支持的 AVS。

例如,如果一个运营者支持两个 AVS,他们可以有三个地址:一个用于 AVS 1,另一个用于 AVS 2,第三个用于同时运行两者。

如果一个质押者信任运营者并且只想保护 AVS 1,他可以委托给适当的运营者地址。

通过这种方法,我们使质押者能够完全控制他们的质押。与此同时,他们可以将链下责任委托给运营者。

模块化运营者

TokenPool合约目前非常庞大。我们将从TokenPool中提取特定于运营者的功能,并将其放入一个单独的合约DelegationManager中。

现在,TokenPool合约将如下所示:

contract TokenPool {
    mapping(address => uint256) public stakerBalance;

    function stake(uint256 amount) public;
    function withdraw() public;
}

TokenPool合约将仅跟踪每个质押者的余额。AVS 的跟踪和加入将由DelegationManager处理。

contract DelegationManager {
    mapping(address => uint256) public operatorBalance;
    mapping(address => address) public delegation;
    mapping(address => address[]) public slasher;

    function delegateTo(address operator) public;
    function enroll(address slasher) operatorOnly;
    function exit(address slasher) operatorOnly;
}

最后,削减合约保持不变。它跟踪每个 AVS 当前时间被削减的运营者。

contract slasher {
    mapping (address => bool) isSlashed;

    function slash(address operator, ??? proof);

}

在清理合约结构并将每个组件模块化之后,架构现在如下所示:

img

EigenLayer中间设计: 将运营者角色与质押者角色分离后。

目标:支持更多代币

到目前为止,我们开发的设计仅支持质押一个代币,因为我们只为质押者维护一个映射。

我们可以通过采用基于LP 份额的模型来解决这个问题,并创建特定于代币的TokenPool

为此,我们将创建一个名为TokenManager的新合约。TokenManager将是质押者质押和提款他们的代币的地方。

TokenManager下,每个代币将有一个TokenPoolTokenManager将充当所有代币的记账中心;它本身不会存储任何代币。每个TokenPool将持有其自己对应的代币。

设计的新组件,现在可以跟踪质押者的不同代币。

当用户质押代币时,它会由TokenManager处理。TokenManager然后调用与该代币相关的相应TokenPoolstake函数。用户的代币将转移到TokenPool。在函数结束时,totalSharesstakerPoolShares将被更新以反映新的质押。totalShares跟踪TokenPool发行的份额总数,而stakerPoolShares记录每个TokenPool中每个个体质押者持有的份额数量。

每个合约的接口将如下所示:

contract TokenManager {
    mapping(address => address) tokenPoolRegistry;
    mapping(address => mapping(address => uint256)) stakerPoolShares;

    function stakeToPool(address pool, uint256 amount);
    function withdrawFromPool(address pool);
}

contract TokenPool {
    uint256 public totalShares;
    function stake(uint256 amount) TokenManagerOnly;
    function withdraw(uint256 shares) TokenManagerOnly;
}

DelegationManager也将进行一些微小的更改以反映这一变化。DelegationManager将不再跟踪每个运营者的余额映射,而是跟踪每个TokenPool中运营者持有的份额,类似于TokenManager

contract DelegationManager {
    // ...
    mapping(address => mapping(address => uint256)) operatorPoolShares;
    // ...
}

现在,在相同的核心架构下,质押者可以将任何代币质押到 EigenLayer 以保护其他 AVS。

目标:扩展 AVS 设计

考虑以下情况:一个质押者在参与可削减行为后立即撤回他们的质押,其他人削减他们的资产之前就进行撤回。

例如,假设有一个既是运营者又是质押者的运营者,在 AVS 中表现恶意。在任何其他人可以在链上削减之前,该运营者从 EigenLayer 合约中提取了他们的质押。这是可能的,因为在提款时,slasher尚未更新以削减他们的资产。因此,AVS 不再能够削减恶意的运营者/质押者,因为没有更多的代币可以用于削减。

img

恶意运营者/质押者的潜在事件时间表。

因此,一个“安全”的 AVS 需要一个能够在发生事件的同一个区块中冻结恶意运营者的削减合约。这个限制极大地限制了 AVS 的设计,使大多数 AVS 都不安全

一个解决方案是引入一个解绑期。我们不再允许质押者立即撤回他们的质押,而是在提款过程中引入一个称为解绑期的延迟。之后,质押者可以像以前一样提款。

当一个质押者决定从系统中提款时,他们的请求被放入一个队列。只有在运营者最长的解绑期到期后,这个排队的提款才会被处理。这是因为一个运营者可能管理多个 AVS,但一个质押者的提款只能与一个解绑期对齐。出于安全原因,系统将解绑期设置为最长的那个

例如,如果一个质押者将他们的质押委托给参与三个 AVS 的运营者,这三个 AVS 的解绑期分别为六、五和七天,那么在从 EigenLayer 请求提款后,他们必须等待七天才能访问他们的质押。这是因为七天是这三个期限中最长的。

在七天期限结束后,质押者可以提款他们的质押。但是,如果在此期间他们委托的运营者被削减,那么待处理的提款也将被停止

为了引入这一变化,DelegationManager需要跟踪每个运营者的解绑期,并在运营者加入新的 AVS 时更新它。

contract DelegationManager {
    // ...
    mapping(address => uint256) public unbondingPeriod;
    // ...
}

在跟踪每个运营者的解绑期之后,我们还将将这个值纳入质押者提款流程中。提款流程包括两个步骤

  1. 质押者排队提款。
  2. 解绑期过后,质押者可以完成他们的提款。
contract TokenManager {
 mapping(address => address) public tokenPoolRegistry;
 mapping(address => mapping(address => uint256)) public stakerPoolShares;
 mapping(address => uint256) public withdrawalCompleteTime;

 function stakeToPool(address pool, uint256 amount) public;
 function queueWithdrawal(address pool) public;
 function completeWithdrawal(address pool) public;
}

当质押者排队提取时,TokenManager 将与 DelegationManager 验证质押者委托的操作员是否被 slash。如果操作员未被 slash,TokenManager 将根据 DelegationManagerunbondingPeriod 和当前时间更新质押者的 withdrawalCompleteTime

解除绑定期后,质押者可以通过 completeWithdrawal 完成其提取。该函数将验证 withdrawalCompleteTime 是否已过。如果已过,质押者的代币将按照之前的流程转出。

💡这个流程的设计复杂,并在我们的流程中经历了几次迭代。我们甚至可以就这个主题撰写一篇单独的文章!目前,我们使用一个时间跟踪系统来实现这种解绑跟踪。这部分仍在进行中!

模块化 slashers

由于我们正在使 slash 机制更安全,让我们也尝试使其更模块化和高效。

目前,在提取过程中,TokenManager 需要与每个单独的 slasher 进行检查,以查看操作员是否被 slash。这会给质押者增加 gas 开销,并可能显著降低较小质押者的奖励。

此外,由于 AVS 开发人员通常设计 slashers,将这个特定组件模块化可以简化各个 AVS 的开发流程。

TokenManager 类似,我们将为 slash 机制采用两部分设计。SlasherManager 维护每个操作员的状态。单独的 slasher 将处理每个 AVS 的 slash 逻辑。

img

更进一步模块化 slash 合约以减少质押者的 gas 成本。

contract SlasherManager {
    mapping(address => bool) public isSlashed;
    mapping(address => mapping(address => bool)) public canSlash;

    function enrollAVS(address slasher) operatorOnly;
    function exitAVS(address slasher) operatorOnly;
}

SlasherManager 允许操作员通过将 AVS slasher 合约添加为能够 slash 该操作员的 slashers 之一来加入 AVS。这个“谁能 slash 谁”的权限由 canSlash 变量跟踪。

contract slasher {
    function slash(address operator, ??? proof) public;
}

slasher 将是特定于 AVS 的,很可能由 AVS 开发人员开发。它将与 SlasherManager 交互,以更新不同操作员的状态。

EigenLayer 已设计好!

回顾一下:EigenLayer 的目标是简化基础架构搭建。 我们从四个主要目标开始:

  1. 构建一个平台连接质押者和基础架构开发人员。
  2. 允许质押者使用任何代币提供经济安全性。
  3. 使质押者能够重新质押他们的质押,并在为其他基础架构提供安全性的同时赚取原生 ETH 奖励。
  4. 通过重新质押来池化安全性,而不是使其分散化。

经过几次迭代,我们开发了三个核心组件:TokenManagerDelegationManagerSlasherManager。每个组件都有特定的功能:

img

EigenLayer 的简化架构

  • TokenManager:处理质押者的质押和提取。
  • DelegationManager:允许操作员注册和跟踪操作员份额。
  • SlasherManager:为 AVS 开发人员提供确定 slash 逻辑的接口。

这些核心组件还相互通信,以确保整个系统的安全性。

除了这些核心合约之外,还有许多其他功能和合约,增强整个堆栈。这些附加功能支持各种 AVS 设计,简化离线技术复杂性,并减少用户和操作员的 gas 费用。

要了解更多关于这些其他功能的信息,你可以访问我们的开源代码库:https://github.com/Layr-Labs/eigenlayer-contracts

💡 如果你对 EigenLayer 核心合约有任何疑问,请在 https://research.eigenlayer.xyz/ 留下评论😉

附加 1:谁信任谁?

当系统是模块化的时候,跟踪协议中参与者之间的信任假设可能是具有挑战性的。 因此,明确概述协议中涉及的参与者之间的信任假设是至关重要的。

在 EigenLayer 中,有三个主要代理:质押者、操作员和 AVS 开发人员。

操作员依赖于 AVS 开发人员准确编写客户端软件和链上 slash 条件。如果 AVS 软件中存在 bug,最好的情况下,操作员可能会错过潜在的费用支付。最坏的情况下,操作员可能会因此被 slash 全部质押。

鉴于所涉及价值的重要性,确保整个系统在投入使用之前具有辅助训练轮是非常重要的。

否决委员会充当这些训练轮。它有权力撤销由于非恶意行为导致的 slash。否决委员会是质押者、操作员和 AVS 开发人员之间的相互信任方

这样,对 AVS 开发人员的信任假设可以被移除。即使 AVS 中存在软件 bug,质押者和操作员也不会受到惩罚。

质押者信任他们委托的操作员。如果操作员行为不端,质押者可能会错过潜在的费用支付,甚至失去全部质押。这一信任假设与现有的验证服务(如币安质押和其他质押服务)相同。

AVS 开发人员依赖于操作员诚实操作。如果操作员不诚实,AVS 服务将显著下降,导致客户流失和其他后果。

在参与者之间,通过否决委员会,信任假设如下:

  • 质押者信任操作员诚实行事,不端行为可能导致 slash。
  • AVS 开发人员信任操作员诚实操作 AVS 软件。
  • 质押者、操作员和 AVS 开发人员信任否决委员会来撤销 slash。

附加 2:原生 Restaking

到目前为止,我们已经讨论了使用 LST 进行重新质押。但是,如果你不想通过流动质押协议对 EigenLayer 进行质押,你可以通过原生重新质押开始参与 EigenLayer。

让我们定义原生重新质押:这是使用验证器内的 ETH 进行额外承诺的过程。如果验证器偏离承诺,它们将失去其验证器内持有的 ETH。

这里的挑战在于,这些验证器内的 ETH 不是以 ERC20 代币的形式表示。相反,ETH 存在于信标链上。如果你对执行层或共识层(信标链)不熟悉, 这篇解释是一个让你快速了解的好资源。

为了解决这个问题,我们可以使用 EigenPod 来跟踪以太坊验证器余额,并在必要时 slash 它们。

EigenPod 充当虚拟记账系统。通过 EigenPod,我们可以监视每个重新质押验证器的 ETH 余额。

在高层次上,EigenPods 处理验证器的提取过程。当验证器从 EigenLayer 提取其质押时,ETH 首先通过 EigenPod,以检查验证器是否已被 slash。如果验证器已被 slash,代币将在 EigenPod 合约内冻结,有效地 slash 它们。

实现 EigenPod

实现 EigenPod 是棘手的,因为以太坊验证器余额存储在信标链上,我们无法访问执行层上的信标链数据。

为了解决这个问题,我们利用一个预言机将信标链状态根传递到执行层。通过获取信标状态根,我们可以通过提供相应的默克尔证明来访问验证者的余额。

有了 EIP-4788 的实施,我们可以移除这个预言机,并直接从执行层查询信标根。

为了封装记账系统,我们将采用类似TokenPoolTokenManager模型的模式,来模块化本地的再抵押系统。每个EigenPod将处理一个验证者的提款过程。EigenPodManager将与其他核心合约协调,以跟踪每个操作员和质押者再抵押的以太币数量。

contract EigenPodManager{
    mapping(address => uint256) public restakerShares;

    function createEigenPod(address owner) public;
    function stakeToPod(address pod, uint256 amount) public;
    function withdrawFromPod(address pod) public;    
}
contract EigenPod{
    address BEACON_CHAIN_ORACLE;
    address podOwner;
    uint256 restakedAmount;

    function stake(uint256 amount) public;
    function verifyRestakedBalance(uint256 amount, MerkleProof proof) public;
    function withdraw() public; 
}

EigenPodManager跟踪每个质押者拥有的份额数量。它允许质押者创建EigenPod,对其进行质押,并从中提款。

EigenPod通过restakedBalance变量跟踪信标链上各个验证者的余额。每当任何再抵押验证者的余额发生变化时,任何人都可以通过调用verifyRestakedBalance()函数来更新该特定验证者的余额。该函数将通过我们从BEACON_CHAIN_ORACLE获取的信标状态根来检查更新后的余额是否正确。

这就是 EigenLayer 如何实现本地再抵押。


本翻译由 DeCert.me 协助支持, 在 DeCert 构建可信履历,为自己码一个未来。

点赞 1
收藏 1
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
翻译小组
翻译小组
0x9e64...7c84
大家看到好的文章可以在 GitHub 提 Issue: https://github.com/lbc-team/Pioneer/issues 欢迎关注我的 Twitter: https://twitter.com/UpchainDAO