https://medium.com/@quentangle/optimism%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6%E8%AF%A6%E8%A7%A3-fbc441764425

https://twitter.com/quentangle_

https://research.paradigm.xyz/optimism

https://www.alchemy.com/overviews/optimistic-rollups

https://godorz.info/2022/04/optimism-notes/

https://blog.csdn.net/shangsongwww/article/details/119274785

https://www.cnblogs.com/linguanh/p/16535408.html

![image-20230223162738841](/Users/carver/Library/Application Support/typora-user-images/image-20230223162738841.png)

https://www.helloworld.net/p/0748466805 重点看

什么是乐观的rollup

链外处理txns,可以从以下节省:

  1. 数据压缩:一个批次所占用的空间比单独的txns堆叠在一起要少。原因

optimism 认为L2提交上来的新状态,L1 是不需要验证的,如果验证他会浪费很多计算,失去了rollup意义(核心)

所以他们将新提交的批次锁定一个星期(挑战窗口期,这是个优化点,1个星期太久了,为什么挑战期需要这么久🚩), 任何人(无门槛)可以在这个窗口期提交数学证明,如果发现了欺诈就可以获得奖励(提交批次的人存入的钱,必须存才有资格提交),若是没有争议,就是最终结果。

optimism 组件

L1:

  • CanonicalTransactionChain
  • StateCommitmentChain
  • CrossDomainManager

L2:

  • Sequencer (optimism )
  • batch-submitter
    • 出于 data availability(这里是否可以尝试替换为DA解决方案🚩),把交易按敲定的顺序,序列化后作为 calldata 提交到 L1
  • CrossDomainManager

Data-transport-layer

索引 L1 事件,并存储到数据库中

  • TransactionEnqueued
  • SequencerBatchAppended
  • StateBatchAppended

对于 L1L2 交易,还将建立引用 index > queueIndex

Sequencer 向它查询待执行的 L1L2 交易

realyer:

实时监控已过挑战期的 L2L1 交易,在 L1 上调用合约完成中继 ,未找到代码🚩

optimism 合约组成

L1和L2移动资金的双向桥梁

===========L1 bridge

===========L2 bridge

原理:锁定L1的资金,并在L2上铸造等值资金。提取资金时,桥要烧掉L2的资金并释放锁定的L1资金

跨域信息传递

L1和L2之间的通信是通过一个跨域信使合约进行的(L1、L2上都有一个副本)。在内部这个合约存储消息,并依靠 “中继器relayers”来通知另一个链(L1或L2)有新消息

不存在原生的L1通信,每一方都有relayMessage这样的函数, 中继器应该使用传统的web2 HTTP来调用它们

处理交易并rollup

其角色是sequencer(目前是中心化的,去中心化或者分布式的应该更好,避免单点故障问题🚩) ,主要代码就是L2Geth, 他就是专门接收L2交易。将状态更新作为一个待定区块应用到其本地状态。这些待处理区块会定期大批量地提交给以太坊(L1上的规范链合约)进行最终处理。

在以太坊上接受这些批次的功能是appendSequencerBatch,这是L1上CanonicalTransactionChain合约的一部分。在内部,appendSequencerBatch使用下面的函数来处理批次。他会存储批量交易,这个里面的数据是后面处理争端的证明数据,需要理解下怎么工作的🚩

处理纠纷的状态更新

争端的工作方式是提交一个状态更新无效的证明,并根据存储的状态更新(存储的批次元数据:哈希和上下文)验证这个证明。

负责处理纠纷的合约是OVMFraudVerifier。该合约是OVM — Optimism虚拟机(类似于EVM — Ethereum虚拟机)的一部分

这个合约我并没有搜到

contract OVM_FraudVerifier is Lib_AddressResolver, OVM_FraudContributor, iOVM_FraudVerifier {
    /**
     * 最终完成欺诈验证过程。
     * @param _preStateRoot 欺诈交易前的状态根。
     * @param _preStateRootBatchHeader 所提供的前状态根的批次头。
     * @param _preStateRootProof 为所提供的前状态根的包容证明。
     * @param _txHash 状态根的交易
     * @param _postStateRoot 欺诈性交易后的状态根。
     * @param _postStateRootBatchHeader 所提供的后状态根的批次头。
     * @param _postStateRootProof 为所提供的后状态根的包容证明。
     */
    function finalizeFraudVerification(
        bytes32 _preStateRoot,
        Lib_OVMCodec.ChainBatchHeader memory _preStateRootBatchHeader,
        Lib_OVMCodec.ChainInclusionProof memory _preStateRootProof,
        bytes32 _txHash,
        bytes32 _postStateRoot,
        Lib_OVMCodec.ChainBatchHeader memory _postStateRootBatchHeader,
        Lib_OVMCodec.ChainInclusionProof memory _postStateRootProof
    )
        override
        public
        contributesToFraudProof(_preStateRoot, _txHash)
    {
        iOVM_StateTransitioner transitioner = getStateTransitioner(_preStateRoot, _txHash);
        
        // ... a bunch of require statements omitted
 
        // If the post state root did not match, then there was fraud and we should delete the batch
        require(
            _postStateRoot != transitioner.getPostStateRoot(),
            "State transition has not been proven fraudulent."
        );
        
        _cancelStateTransition(_postStateRootBatchHeader, _preStateRoot);
 
        // TEMPORARY: Remove the transitioner; for minnet.
        transitioners[keccak256(abi.encodePacked(_preStateRoot, _txHash))] = iOVM_StateTransitioner(0x0000000000000000000000000000000000000000);
 
        emit FraudProofFinalized(
            _preStateRoot,
            _preStateRootProof.index,
            _txHash,
            msg.sender
        );
    }
    
    /**
     * 从状态承诺链中删除一个状态转换。
     * @param _postStateRootBatchHeader 后状态根的头。
     * @param _preStateRoot 前状态根的哈希值。
     */
    function _cancelStateTransition(
        Lib_OVMCodec.ChainBatchHeader memory _postStateRootBatchHeader,
        bytes32 _preStateRoot
    )
        internal
    {
        iOVM_StateCommitmentChain ovmStateCommitmentChain = iOVM_StateCommitmentChain(resolve("OVM_StateCommitmentChain"));
        iOVM_BondManager ovmBondManager = iOVM_BondManager(resolve("OVM_BondManager"));
 
        // Delete the state batch.
        ovmStateCommitmentChain.deleteStateBatch(
            _postStateRootBatchHeader
        );
 
        // Get the timestamp and publisher for that block.
        (uint256 timestamp, address publisher) = abi.decode(_postStateRootBatchHeader.extraData, (uint256, address));
 
        // Slash the bonds at the bond manager.
        ovmBondManager.finalize(
            _preStateRoot,
            publisher,
            timestamp
        );
    }
}
  • finalizeFraudVerification检查_postStateRoot(由验证者提交)是否与排序器提交的root不一致。
  • 如果不一致,那么我们就在_cancelStateTransition中删除该批次,并削减排序者的存款(为了成为一个排序器,你需要锁定一个存款。当你提交一个欺诈性的批次时,你的押金就会被削减,这些钱就会给验证者,作为保持整个机制运行的激励)。

rollup交易

欺诈证明

OVM

参考