Layerzero:OFT-adapter

  • 老道
  • 发布于 2小时前
  • 阅读 13

OFT-adapter命令:npxhardhatlz:oft:send--src-eid40231--dst-eid40245--amount1.5--to0x3ab12b9ff37c21c8c2d92f8f0209d1e04d6b57ee

OFT-adapter

命令:

npx hardhat lz:oft:send \
  --src-eid 40231 \
  --dst-eid 40245 \
  --amount 1.5 \
  --to 0x3ab12b9ff37c21c8c2d92f8f0209d1e04d6b57ee

Src(Arbitrum)
RayERC20(本地 ERC20 资产)
0x7bC68465b92b82dDd89097E1BFABA2F9348404c5
OFTAdapter(把 RayERC20 封装成 OFT的适配器,也就是src)
0x1137ef9869DEc71FCa947cd9D8d7606bF05690d6

Dst(Base)
OFTOApp_dst
0x790E5667A1bC449803E68e827b60919859d75546

①:Src(Arbitrum):OFTAdapter 发 message + assignJob + 付款

1. 跨链转账

  • OFTAdapter.sendFrom 里面:
    1. RayERC20 余额:
      • 用户的 RayERC20msg.sender 转到 OFTAdapter(lock 模式)
    2. message 并调用 Endpoint

2. EndpointV2.send / _send:对这笔 OFT 转账生成 Packet

  • EndpointV2.send_senderOFTAdapter
    1. _outbound(OFTAdapter, 40245, receiver=OFT_on_base)
      • OFTAdapter → Base(OFT) 这条路径分配一个新的 nonce;
    2. encode Packet:
      • message 里其实就是这次跨链转账的业务数据:(to, amount)
      • guid 是这笔跨链转账的“全局 ID”,后面 dst 链执行时要用;
    3. 找到 SendLibSendUln302),调用:
      ISendLib(sendLib).send(packet, options, payInLzToken);

3. SendUln302.send:给 Executor/DVN assign“这笔 OFT 转账” + 计算gas fee

  • _payWorkers
    • 针对这笔 OFT 跨链转账:
    • calldata 长度 + dst 链 gas 情况,给 Executor 算 fee;
    • confirmations + quorum,给 DVN 算 fee;
    • 这里 message 只是包含 to + amount 的 payload。
  • _payTreasury
    • 额外抽一部分协议费(LayerZero fee)。
      在干嘛:
      “给 Base 链上 OFT 合约的一笔跨链转账”。

4. EndpointV2.send:检查用户本次 OFT 桥转账付的钱够不够

  • _assertMessagingFee 确认这笔 OFT 跨链操作提供的 native / lzToken 足够覆盖:
    • Executor 的 gas
    • DVN 的 gas
    • Treasury 的协议费
  • _payNative / _payToken 真正把钱存进 SendLib 的 fee 账本
    ✅ 至此,在 src 链的工作完成:
  • 用户已经被扣了 RayERC20(lock);
  • 对应的一条 LayerZero message 已经生成、assignjob、payworkers、并 emit PacketSent

②:Off-chain:DVN / Executor 监听这笔 OFT 跨链转账

这一条跨链消息,代表一笔 OFT 转账。
DVN Network

  • 监听这条 PacketSent,确认:
    • 源链交易已经上链、达到 confirmations
    • packetHeader + payload 确实编码了正确的 (to, amount)
      Executor Network
  • 记录这条 OFT 转账消息要在 Base 上执行:
    • 它后面会在 Base 调 Endpoint.lzReceive(origin, receiver=OFT, guid, message)
      → message 里就是 (to, amount)

③:Dst(Base):DVN 验证 + commit → Base Endpoint.verify → _inbound

这一段链路的逻辑不变,只是:

  • receiver = 在 Base 上部署的 OFT 合约
    0x790E5667A1bC449803E68e827b60919859d75546
  • payloadHash 对应的是:
    abi.encodePacked(guid, abi.encode(to, amount))

    最后:
    Base 链上的 Endpoint 把这条 OFT 转账消息的 payloadHash 写进:

    inboundPayloadHash[OFT][ArbitrumEid][OFTAdapter][nonce] = payloadHash;

    也就是:
    “从 Arbitrum 上 OFTAdapter 来的 OFT 跨链转账”已经进到 Base 上的 message channel,等待 Executor 执行。

④:Dst(Base):Executor.lzReceive → _clearPayload → OFT.lzReceive / _credit

4. Executor 在 Base 调 Endpoint.lzReceive

  • Executor 拿到 src 侧的 encodedPacket,解出:
    • origin = { srcEid = 40231, sender = OFTAdapter, nonce }
    • guid
    • message = abi.encode(to, amount)
    • extraData = executorOptions 编出来的执行配置
  • 在 Base 上调用:
    endpoint.lzReceive(origin, OFT, guid, message, extraData);

5. Endpoint.lzReceive / _clearPayload

  • 验证这条消息的 (guid, message) 的哈希 == inboundPayloadHash[OFT][ArbEid][OFTAdapter][nonce]
  • 更新 lazyInboundNonce
  • 删除 payloadHash,防止这笔 OFT 转账被执行两次

6. OFT 合约的 lzReceive / _lzReceive:在 Base 上 mint OFT

  • OFT._mint(to, amount)

表示:“在src已经锁住了 RayERC20,现在在 Base 链上给对应地址发放同额度的 OFT。”

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

0 条评论

请先 登录 后评论
老道
老道
0xbf65...58d8
江湖只有他的大名,没有他的介绍。