Skip to main content
Monad 使用一个 预编译合约 来管理验证者委托和奖励。 本页涵盖与质押预编译合约交互的关键概念和工作流。要查看完整接口参考,请访问 API 页面。要了解 Monad 质押系统的工作原理,请访问 learn 标签页。 质押预编译合约位于地址

关键概念

纪元(Epoch)和时序

质押状态变更不会立即生效。Monad 将时间划分为 纪元(epochs),大多数操作只会在新纪元开始时激活。 每 50,000 个区块(约 4 小时 12 分钟)会有一个 边界区块(boundary block) 提交即将生效的质押变更。经过 5,000 轮延迟(EPOCH_DELAY_ROUNDS)后,新纪元开始。 显示纪元中边界区块位置的时间线 这意味着您的操作将在以下之一激活:
  • 纪元 n+1 —— 如果在边界区块之前提交
  • 纪元 n+2 —— 如果在边界区块之后提交(在纪元延迟期内)
使用 getEpoch() 检查当前纪元以及边界是否已过:
一轮(round)不是一个区块 —— 即使有提案缺失,轮次也会递增。您不能通过对区块编号取模来计算纪元边界。请始终使用 getEpoch()

提现延迟

已解除委托的质押不会立即可用。调用 undelegate 后,您必须等待 WITHDRAWAL_DELAY(1 个纪元),然后才能调用 withdraw 来提取资金。

常见操作

委托(Delegate)

要将 MON 委托给验证者,请调用 delegate(validatorId) 并将金额作为 msg.value:
  • msg.value 必须至少为 DUST_THRESHOLD(1 gwei)。
  • 您的委托将在下一个纪元(或再下一个纪元,如果已过边界区块)生效。
  • 如果这使得验证者的总质押达到 ACTIVE_VALIDATOR_STAKE,则该验证者将被加入活跃集合。

解除委托和提现

移除质押是一个两步过程: 步骤 1:解除委托 —— 通过指定金额和 withdrawId(0–255)发起提现:
步骤 2:提现 —— 在 WITHDRAWAL_DELAY 纪元过后,调用 withdraw 提取资金:
timeline of undelegation and withdrawal

质押可提现性相对于 undelegate 的时间线

  • 您只能解除委托 活跃 状态的质押(不包括待生效的委托)。
  • 每个 (validator, delegator) 对最多支持 256 个并发提现请求。
  • withdrawId 可以在提现完成后重复使用。

领取和复投奖励

当您的验证者出块时,奖励会自动累积。您有两个选择:
  • 领取奖励 —— 将累积奖励提取到您的账户:
    领取 立即 生效 —— 无纪元延迟。
  • 复投奖励 —— 将累积奖励重新委托,增加您的质押:
    复投的奖励将在下一个纪元激活(遵循标准的时序规则)。

查询质押状态

用于读取质押状态的主要视图方法: 分页方法每次调用最多返回 100 条结果。首次调用请传入 startIndex = 0,之后使用 nextIndex 进行后续调用,直到 isDone 为 true。

约束

由于质押系统是预编译合约而非智能合约,因此在行为上存在一些差异。
  • 只允许 CALL STATICCALLDELEGATECALLCALLCODE 会回滚。这意味着所有视图方法使用 nonpayable 状态可变性,而不是 view
  • 无 fork 环境测试。 质押系统是预编译合约,而非智能合约 —— 该地址上没有代码,所以 fork 测试环境无法工作。
  • 边界区块时序。 在纪元延迟期内(边界区块之后)提交的操作,要到两个纪元之后才生效。如果时序很重要,请检查 getEpoch()
  • 粉尘阈值。 低于 DUST_THRESHOLD(1 gwei)的委托将回滚。
  • EIP-7702 注意事项。 如果某账户使用 EIP-7702 将其委托设置为质押预编译合约地址,则对其发起的所有调用都会回滚。

延伸阅读

  • API 参考 —— 质押预编译合约的完整参考,包含方法签名、参数、gas 成本、事件、结构体和 ABI
  • 质押如何工作 —— Monad 质押系统如何确定验证者投票权重、纪元调度和奖励分配